the writeup
overview
The project itself I would say was built quite well. It is reasonably able to render
chunks at a good enough framerate that im happy with it. I personally would of not picked
java script, mostly because of the multithreading support.
js slow
Being forced to halt rendering
so that the game can generate AND mesh chunks does cause quite noticeable lag spikes.
The best thing to do would create a render thread, and only have generation and meshing done
on its own thread, but I cannot do this in JS.
vertex data
As also described in the presentation, I do thing the vertex mesh for the chunk is not well
made. 192 bytes per quad (vec3 + vec3 + vec2 + vec3 + float) * 4, is really terrible for
gpu performance. The smaller the mesh, the quicker the gpu can process it each frame and the
high the fps. I have decided to continue this project but not in javascript, but in c, and I
have gotten it down to 4 bytes, horray!
typedef union {
struct {
u32 x : 5;
u32 y : 5;
u32 z : 5;
u32 width : 5;
u32 height : 5;
u32 face : 3;
u32 block : 4;
};
u32 raw;
} Quad;
Above is the struct I am not using in C for per quad data. Each quad is then instanced on the gpu, stored in a uniform buffer. Then I use the instance index to index into the uniform of "Quad"s, to render each face. It is quite a lot faster than the approach I did in JS.
You may also notice that this contains a width and height field, which allows us to use this
with greedy meshing! Horray!!!
If you would like to take a look at my C code, you can find it at https://g.freya.cat/voxel. Yes its OpenGL, but I've done Vulkan once, and never again.
texture array
The first time i made minecraft I ran into the issue where texture atlases would get blurd and wonky when msaa or mipmapping were turned on. This ended up being because the edges of each texture in atlas would get blured (msaa'd) togeather, and the edges of blocks would look terrible. The solution to this was to use a texture array (or a 3d texture), since each layer gets sampeled differently, and such there would be no bluring between the layers.
what would i do differently
So though all the issues I ran into, what would i do differently? Well thats easy, the C code I just linked to in the previous section. It fixes alot of the issues I ran into in the
JS voxel "engine", and also adds a whole new slew of features such as frustum culling and soon will have ambient occlusion.
Frustum culling turns out is alot easier than I thought, because once can get each plane from the proj-view matrix.
I rally had a fun time writing this, and I hope you think It was a cool project :)
johnvertize