Discuss Scratch

TheOnoX
Scratcher
10 posts

Optimizations for 3D Voxel Engine (pipeline + techniques)

Hey!

Since I'm developing a 3D voxel engine in Scratch, I'm constantly looking for ways to improve performance. So far I've gotten a lot of the basic optimizations done, such as only rendering faces of cubes that aren't neighbouring another cube or that isn't visible by the player. Cubes won't render if they exceed the FOV range of the camera or go beyond the farplane/nearplane distances. However, that's sort of where my knowledge of optimizations takes a halt. I've heard of meshing and occlusion culling, but the check for occlusion seems almost more performance draining than not having one at all, since most worlds are going to be flat planes (the culling doesn't change anything for the camera as I use a z-buffer to draw stuff furthest away from the camera first) and meshing, while logical and surely effective on render times, is surely beyond my level of knowledge and skills and I suspect would need a alot of research.

Here's my pipeline:

Setup (only goes once, at start or when the world gets updated)
1. Check all faces on all cubes for neighbours (and put in a list)
2. Load in textures


Update (goes every frame) =

1. Culling
1. Get cube position
1. Check if cube is a block (not air) and that atleast one face on cube touches “air”
2. View frustum culling
3. Check if inside nearplane and farplane
4. Goes over all faces of cube with no neighouring cells and checks if the camera can see that face (due to the angle) (Backface-culling)
5. Adds cubes to camera into an array based on distance (z-buffer)


2. Render
1. Get cube position
2. Repeat for all drawable faces:
1. Transform points on face and add into array + Rotation matrix
2. Fill area with texture

This is the basic pipeline for the engine I have skipped the small steps as that would just be clutter.

The only direct optimization I can think of at the moment is to load all cubes coordinates into an array on start or update of world, so it doesn't have to get checked twice every single frame. However this check isn't very performance heavy either way, so I doubt it will speed up the engine much at all. Here's the link to a project with a pretty similar filling technique for filling faces. It's not the most effective (that project is just a test so I would'n read too far into the code) technique, I'm sure, but I can't see it being optimised much in any way.

The performance of my voxel engine from testing does better than most others I've found (if not a whole lot better) at times, but I don't want to stop here. Do you have any ideas for optimizations, either techiques or changes to my pipeline or in general? Any common practices used for other engines that I've missed? Also, if you have experience with meshing / occlusion culling and know a cheap /effective method please comment, I appreciate any help I can get! Thank you!


note: I haven't shared the project since I'm dealing with some bugs when it comes to rendering, which would likely lead to confusion. Rest assured, this pipeline is the same and the performance aswell.
kkidslogin
Scratcher
1000+ posts

Optimizations for 3D Voxel Engine (pipeline + techniques)

If you're using voxels, implementing an occlusion culler is a MUST, even if most worlds are flat. In the setup script you could check over the world and see if it's too flat. if not, enable the culler.

Another suggestion is like a culler, but simpler: only render the 3 faces of each voxel that faces the camera.
TheOnoX
Scratcher
10 posts

Optimizations for 3D Voxel Engine (pipeline + techniques)

kkidslogin wrote:

Another suggestion is like a culler, but simpler: only render the 3 faces of each voxel that faces the camera.

I've actually already made this, it just checks if a face is that is in open air would be visible with a theta function and then don't draw if it doesn't face the camera!
SkibidyRizzles
Scratcher
1 post

Optimizations for 3D Voxel Engine (pipeline + techniques)

How???

Powered by DjangoBB