-
Notifications
You must be signed in to change notification settings - Fork 0
Shader Diffing
- Every primitive requires knowing which shader to use
- Changes to the scene affect what the shader code should be
- Scene is updated immutably and rendered as a pure function
- Generating and uploading a new shader is expensive
-
A plain object called
shaderConfig
is derived for each scene + primitive combo. -
This object is hashed, resulting in a
shaderHash
(just a plain string). -
This hash is used as the key for looking up a shader in a global
Map<string, Shader>
. In other words, this global lookup is based on this runtime derivation, not a reference to any particular object in the scene or primitive. -
If the shader is not found for that hash, it is compiled and stored.
Compiling a shader requires passing theCompiling a shader requires passing the data, scene, and primitive (note to self - should just need data and shaderConfig?)shaderConfig
object (and nothing else)
All of this happens every tick (though of course cache misses are typically only on the first tick). Therefore, creating shaderConfig
and hashing it must be very fast (and they are - setting shaderConfig
is mostly unrolled settings of flags, and the hash is a hand-tuned approach that was tested against several other approaches).
This is one of the reasons why extensions are hardcoded rather than an open and flexible api (though conceptually they could be dynamically loaded and just append the hash string).
At this point from some minimal tests - it seems to support a few thousand gltf objects no problem. At that point the bottleneck is almost definitely somewhere else in the system rather than diffing/hashing. Since it's all pure data, this work could be offloaded to a separate thread as well.