Since this seems to have sparked some interesting discussion, here is my take of why I would _not_ implement something like Nanite in Godot and instead go for something else. Some complex technical points in thread, but make sure to fully unroll and read them first (thread) 🧵👇
The first thing to understand is that this type of technology is more the realm of cinematic renderers. It requires more modern, dedicated GPUs as a baseline.
Most Godot users currently do not need or aim for this with their games, hence not a priority..
Instead, most of the work the past year was to first modernize the rendering base code and solve all the existing problems (thanks to large part amazing work from @RandomPedroJ, @dariosamo and @matiasgoldberg). This was needed before any work on a cinematic renderer...
But okay, lets say everything ready to do a cinematic renderer. The first thing to understand is that Godot is not Epic, the project does not have 150 veteran graphics engineers that can maintain an insanely huge renderer..
Instead, to achieve similar goals, we have to be smart and plan properly to get the best possible results with the minimum amount of code that we can write and maintain.
So, how would a cinematic renderer work?
First of all, it should be ray/path-tracing only (with base raster pass). This saves incredible amounts of work, as shadows, GI, reflections, etc. would all be ray traced. Hybrids like Unreal or Unity HDRP are far too much complexity, and hardware is getting there anyway..
As for Nanite. The problem with it is that Its also just too complex, it works as a hierarchical meshlet LOD, plus its not that friendly with raytracing, which is our main goal..
Instead, a much simpler approach can be using more traditional auto-LODs with meshlets, all GPU driven. This works great with raytracing (just stream LOD levels together). Has a bit more overdraw? sure, but remember we don' t have shadow maps, so we don't care..
Downsides? Probably slower for insanely complex, huge geometry if it spans hundreds of meters. Just divide it up (which most, if not all games, do anyway), but for anything else you still get great performance and detail. Also likely will use meshlet LRU less efficiently..
But TBH unless you are an AAA studio, you don't care about these things, you have something close that solves a similar problem, and on the Godot side, something _way_ simpler to do and maintain.
• • •
Missing some Tweet in this thread? You can try to
force a refresh
One of the most interesting things when working with game engine technology is spatial indexing algorithms.
This means, ability to store 2D or 3D objects in space and query them efficiently without having to test every single of them. Here is a list of most common ones! 🧵👇
Octree/Quadtree. An octant (3d) is divided in 8 subregions (4 in 2D) recursively:
Pros: Fast updates, insertions, deletions.
Cons: Hard to balance, same object can be contained in many octants (making it less efficient and threaded queries harder)..
Typically used for rendering.
Dynamic BVH: A BVH that is built dynamically as objects move.
Pros: Very fast updates, insertions deletions
Cons: It needs to be progressively rebalanced over time, which may be a problem if too many objects move.
Typically used for rendering and physics.
Since I'm at it. I'm going to write a brief history of how video game music playback happened on consoles on the technical side. This is a topic I love and you' ll see this is quite fascinating!
So, how did this start? (thread 🧵👇).
8 bit systems just had square (also called pulse) waves. This was just a simple oscillator moving dc from - to +. Some hw had quirks (envelopes, analog filters, basic dac, etc), Maybe tri, noise (for perc) or saw wave, but that was it..
This was all accessible as memory mapped registers.
This hardware, however, lacked any kind of timers, so the registers were often updated during vblank interrupt, which was basically the best timing available, which results in an interesting and overlooked peculiarity:
Did you know? The original version of Godot (before it was open sourced) used the Squirrel programming language. ()..
What happened with it? Where did it go? Read on below.. (🧵👇) squirrel-lang.org
Squirrel is very similar to the Lua programming language () but it has some fundamental differences:
- Friendlier C style syntax
- Class support
- No GC
- Easier to bind
I much prefer it over Lua, myself, but It never got much traction..lua.org
Ariel and I published a couple of games using it in 2010-2012. But still, the experience was rather sub-optimal, which resulted in the creation of GDScript.
So, what problems did we have exactly? Even if Squirrel was better, mostly the same as with other languages we tried..
Did you know? Common knowledge says that normal maps can be in OpenGL or DirectX format, and that different game engines/DCCs support different normal map formats.. but this is not quite true and more on the myth side.
Want to know why? Read below! (🧵👇).
In truth, shader code in all game engines look more or less the same for processing the normalmap. A tangent basis is generated using normal/tangent/binormal and the normal map is just multiplied by it.
Notice, nothing is "negated" or flipped. It's a 3x3 matrix mult everywhere..
So, what changes then? Why are there then two texture formats?
The answer is quite simple, It's the tangent space in the 3D asset formats what is different! Although you can sometimes override it, engines will normally use the tangents that come with the asset (FBX, GLTF, DAE)..
One of the things that makes me the the most proud in Godot 4 is also the least visible of them all: The engine foundation.
Godot 4 has now by far one of the best (if not the best) foundations you can find in a game engine... (thread blow🧵👇)
This enormous amount of work took part from 2018 to 2022, the time it took Godot 4 to be made. The whole engine core was in large part redone, helping fix a tremendous amount of bottlenecks/design dead ends, while still keeping the foundation relatively simple..
The biggest consequence of this rework is not what you saw in the Godot 4.0 release per se, but something that is starting to be visible now:
* The insane amount of new features in each release, answering community demands much faster.
* The relatively small effort they take...
Implemented an occlusion aware trilinear voxel filter in HDDAGI. This makes the reflections look a lot more believable (it looks like a low quality video version of the scene). This also has significant advantages quality wise... 🧵👇
First, this removes a lot of high frequency information from the scene, reducing the rays needed to converge (noise). But also, one of the devil's hidden in the details in HDDAGI is that every voxel _already_ has the full GI information in real-time, which is computed cheaply..
The challenge when writing a GI implementation is not so much just throwing rays around. This is easy. The hard part is obtaining the lighting information where the ray hits. HDDAGI solves this with voxels in a *much* cheaper way than path tracing..