Description of the problem
Dynamic Uniforms shouldn’t be in the library if you are adding onWillRender events.
1 ambiguity
This may be ambiguous. When the dynamic
property of a uniform is set to false, what does this mean? The uniform doesn’t change?
When it is set to true, it means more “updateOnEveryTickAndUseCallback” than “dynamic”.
When we change the value of a uniform on an event such as onButtonClicked
, onSliderChange
, onWindowResize
is this uniform dynamic or non-dynamic?
Why would just onProcessingTick/frame
qualify it for dynamic? If you don’t need to set it every tick does that make it non-dynamic?
http://searchnetworking.techtarget.com/definition/dynamic-and-static
In computer terminology, dynamic usually means capable of action and/or change, while static means fixed.
I.e. if it’s not dynamic, it’s static – fixed. Which is confusing, since you can change uniforms whenever you want, not just once every tick before the drawcall (although that is what technically happens, it doesn’t have to happen every frame).
Hence a uniform that is prone to change via gui, is also “capable of action and/or change” but odds are you would set it to be non-dynamic. It’s a paradox.
Line 16
in
d8b24a1
2 performance
While this happens once, it seems pretty unnecessary?
https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLUniforms.js#L546
With the new onBeforeRender, one can just reference the uniforms that need to be changed in the update loop explicitly. No need for this split and arrays to happen?
This is where it gets a bit worse:
https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLUniforms.js#L578
- Another loop is introduced
- multiple null checks
- lookup into array
if ( f !== undefined ) f.call( v, object, material, camera );
check andcall
I think the .call()
l is much more expensive than just calling the function. Before it was bind.
#7048 (comment)
You really don’t want to use the bind method in performance-sensitive library code: It’s a whole lot slower than using a function with an upvalue, where “a whole lot” refers to a browser-dependent ~100 – ~7000%% time overhead per call.
3 redundancy
With the new render event system, one can ideally have a callback right before the render call. Instead of having a whole system that automatically manages this very fringe case at a huge performance cost, one can just use the callback to do this (along with many other things). I.e. if an object has a callback that does something with it’s own material, there is no need to designate the uniform as anything special. It’s a uniform, hence it can change. The question/problem is when to change it. Changing it from a gui, or onClick
should not be any different than onBeforeRender
, all are the same problem of WHEN. At least there is no need to split them, group them, eval them with call()
or bind()
.
4 confusion
We seem to have gotten an onWillRender
event that every other engine has (i’m familiar with unity and scene kit) because of these dynamic uniforms (look at #9662). While i do think it’s awesome that we at least got the event from this feature, i still think people are confused as to what it does, why it does it and it might be the wrong way to approach it.
One does not need to bind thousands of time within the game loop just to do this -> one can do this as one of thousands of things that one could do within these events.
If i understand correctly this idea came from a fringe case documented here:
But besides having the ability to change these uniforms through the event (rather than a whole system) one does not need to create nor clone these objects if one has a performance concern. Instanced geometry is the way to go, while something else could take care of hit detection. For example, one needs only to evaluate a sphere ( radius + position ) in order to figure which object needs further hit detection. This could all be done with a simple, per case algorithm.
meanwhile
people are still confused as to why a uniform, that references a texture, clones that texture when it’s being cloned.
if you really want to extend uniforms, i think a much better property would be to add something along the lines of ‘shareable/referencable/static’. Where one could say that when cloning the uniform, an image for example shouldn’t be cloned as well. If it references myImage
, the clone should also reference myImage
, not clone the image too…
It would solve this issue too:
One can’t instantiate JavaScipt Numbers. So Unifoms that use a Number as value will get “cloned” anyway. This behaviour of cloning then follows this limitation.
Three.js version
- Dev
- r80
- …
Browser
- All of them
- Chrome
- Firefox
- Internet Explorer
OS
- All of them
- Windows
- Linux
- Android
- IOS
Done!