Suggestion: Support refreshing specific uniforms independent of switching program / material
See original GitHub issueDescription of the problem
onBeforeRender was added as a solution for #9662
Unfortunately, because of the way setProgram works in THREE.WebGLRenderer, uniform changes made in the onBeforeRender callback can end up ignored. For example, if the render loop attempts to draw two objects with the same material, and the second material has a uniform that was updated by onBeforeRender, refreshMaterial will fail to be set to true, and the uniform will not be refreshed.
This was highlighted by @arose here: https://github.com/mrdoob/three.js/issues/9662#issuecomment-249395529
I’ve given a shot at supporting this kind of uniform change on a branch here: https://github.com/fallenoak/three.js/commit/24c5d9a8f1765dcb97f340617c71835c38d90d29
I’d have preferred calling the THREE.Uniform flag needsUpdate, but it seems like that’s already used for something (not sure what, however).
I’d also have liked a less kludgy way of iterating over defined uniforms for a given material. Perhaps there’s a better way of doing this (still a bit new to how uniforms are managed in THREE).
Apologies on recycling the ‘dynamic’ label for these uniforms. It does seem like an appropriate name to me.
Three.js version
- Dev
- r81
- …
Browser
- All of them
- Chrome
- Firefox
- Internet Explorer
OS
- All of them
- Windows
- Linux
- Android
- IOS
Hardware Requirements (graphics card, VR Device, …)
Issue Analytics
- State:
- Created 7 years ago
- Reactions:1
- Comments:17 (9 by maintainers)

Top Related StackOverflow Question
Remove milestone?
We should probably try to do something so that this kind of code doesn’t have to be so gnarly 😦 Ideally just changing the uniform on the material should reflect the change, without any low level calls, but it requires a bit of an overhaul?
@arose
Would it make any sense to somehow put this logic into
Uniform’s domain? Like an explicit method to set the uniform for the currently bound program, although i’ve no idea how or if that would work 😕, it would probably only be valid to use within this callback?