This is a raymarching renderer that marches through one 40x40x40 voxel space written in Assembly. I chose that chunk size because 40 is the largest number, the cube of which is less than the max size of an appvar (one byte for each block).

It fakes a resolution of 80x60 as that would be 16 times less rays to render than in 320x240.

You can move forward, backward, left, right, up, down. You cannot yet rotate. The long delay you see at launch is it calculating each ray position and direction. That is very slow due to the complexity of the formulas being evaluated and I'm not sure of a way to optimize it.

The raymarcher is very inaccurate as well for speed's sake. It uses a form of sphere tracing, but distances are whole numbers, so rays often jump too far.

The reason that is is that the signed distance field (the function that returns the signed distance from any point to the surface of the shape) is encoded in the appvar itself as bytes. I had thought to maybe store half units instead of whole units to approximate better, but decided not to due to the lack of simple long bitshifting on the ez80.

You'll see an extreme case of this inaccuracy when you put the camera close enough to the shape. You get some fisheye distortion effect. Here's a thin straight line as the chunk and the camera pointing toward it. Depending on the angle, the rays may jump too far ahead, over the blocks, thus not hit them, making it look like the line is bent:



Calculating the signed distance field is not very fast either on my i7 Skylake. If you limit the max SDF distance to ~11 units, the chunk generator script takes 2m14s. For this reason I might not add a way to edit the world on the calculator itself (this means no 3D Minecraft clone, very sorry).

Other than that the actual rendering function is relatively quick. It takes around 0.8 seconds to render a full frame at first and slows down as more rays start to hit nothing (because those take up all of the raymarching iterations before hitting the limit). This is as fast as I could make it.

I plan on putting up the source online very soon, once I clean it up.
Very nice concept, always good to see some new faces bring cool stuff to the forums!

Welcome Smile.
Welcome to Cemetech!! Smile
I thought the speed might have been a bit faster dues to it written in asm but I guess that's not the case. I think the best way to render is without filling in shapes. "I'm guessing this may increase the speed of the rendering, Let me know how it goes!"
Very nice. I assume you have seen John Lin's work on his voxel ray marcher?

Edit: you should probably be doing DDA instead of actual intersection based raytracing if you aren't already.
Thanks for the welcome.

Alvajoy123 wrote:
Welcome to Cemetech!! Smile
I thought the speed might have been a bit faster dues to it written in asm but I guess that's not the case. I think the best way to render is without filling in shapes. "I'm guessing this may increase the speed of the rendering, Let me know how it goes!"


I'm not sure how that would work considering the nature of raymarching. If you project the 8 points of a cube and draw lines between them, then you have rasterization, not raymarching. In retrospect, raymarching is not at all efficient for simple cube rendering. It's fit for more complex, dynamically changing shapes. So if you ditch the marching part it can almost certainly be made faster.
c4ooo wrote:
Very nice. I assume you have seen John Lin's work on his voxel ray marcher?


No, actually, I've never heard of him. I've just checked and so far the screenshots are very pretty.

c4ooo wrote:
you should probably be doing DDA instead of actual intersection based raytracing if you aren't already.


It's raymarching, which involves testing an intersection between a point and an arbitrary shape. Here I'm just taking the integer part of the points coordinates and use those to index into the chunk data. If no intersection, the point marches in the ray's direction. I guess that would count as DDA?
Hmm. With DDA you increment the ray position by a specific amount so that you can index into the chunk data. The advantage of DDA is that you can do everything with integers and don't have to compute any actual intersections.
Most importantly, DDA will slow down as you increase the render distance, where as tracing against spheres will slow down as you increase the amount of spheres.

Either way though, this seems really cool. It's a shame that as you can't fit more blocks into memory.
c4ooo wrote:
Hmm. With DDA you increment the ray position by a specific amount so that you can index into the chunk data. The advantage of DDA is that you can do everything with integers and don't have to compute any actual intersections.
Most importantly, DDA will slow down as you increase the render distance, where as tracing against spheres will slow down as you increase the amount of spheres.

Either way though, this seems really cool. It's a shame that as you can't fit more blocks into memory.


Well, raytracing with DDA just sounds like raymarching :P.

I could technically load more chunks from more appvars, but I'd rather try to optimize single-chunk performance for now.

Anyway, here is the source code: https://gitlab.com/midn/voxelray/ (Warning: causes a RAM reset upon exit!)

I had been working on an off-calculator chunk editor written in Python (I didn't want to use Python but my chunk generator was already written in it, so). It's included in the GitLab repository. The required modules are glfw, imgui[glfw], numpy, PyOpenGL. Sorry if that's a lot.

If anyone wishes to use it, design a chunk (left to place, right to remove), press the "Export" button, then make the project with `make`. It will produce voxelray.8xp, vrchunk.8xv which you copy to the calculator. There's no Undo & Redo in the editor!

Here's a house:



The distortion actually produces a neat Animal Crossing globe effect.
Well, thats a real cool project. Coming from the original playstation, the imperfect lines don't bother me at all.
Cool! How slow would it run at the normal (320x240) resolution?
Sorry for the late reply. I got hung up in other things.

Jinnai wrote:
Well, thats a real cool project. Coming from the original playstation, the imperfect lines don't bother me at all.

Yeah, it makes for a neat aesthetic.

sirdudeman wrote:
Cool! How slow would it run at the normal (320x240) resolution?

Thanks. Well, compared to 80x60, that would mean 16 times the rays, so a little over 16 times slower.

This was a neat experiment but I don't think I'll continue working on it. I've run out of ways to optimize the rendering, and raymarching is in itself computationally expensive.

That said, I've made an article explaining how it works a bit deeper.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement