-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Suggestion: Support refreshing specific uniforms independent of switching program / material #9870
Comments
@mrdoob Would love your feedback when you have time. Happy to craft a PR once you weigh in. |
Heh... We seem to be going back and forth here... 65b8e84 |
I hope this isn't too back-and-forth-y! I think
All that's really missing is an appropriate way to mark a uniform as dirty, such that the
|
@mrdoob Thoughts? |
Finally figured out how to use function onBeforeRender( renderer, scene, camera, geometry, material, group ){
var updateList = [];
var u = material.uniforms;
var d = this.userData;
if( u.pickingColor ){
u.pickingColor.value.setHex( d.pickingColor );
updateList.push( "pickingColor" );
}
if( u.color ){
u.color.value.setHex( d.color );
updateList.push( "color" );
}
if( updateList.length ){
var materialProperties = renderer.properties.get( material );
if( materialProperties.program ){
var gl = renderer.getContext();
var p = materialProperties.program;
gl.useProgram( p.program );
var pu = p.getUniforms();
updateList.forEach( function( name ){
pu.setValue( gl, name, u[ name ].value );
} );
}
}
} What about another callback in WebGLRenderer that is called after |
@arose function onBeforeRender(renderer, scene, camera, geometry, material, group) {
if ( !material.programIsSet ) {
const map = material.uniforms;
map.ufSaturation.value = this.userData.saturation;
material.programIsSet = true;
return;
}
if ( material.program && material.uniforms !== undefined ) {
const gl = material.program.getUniforms().renderer.context;
const map = material.program.getUniforms().map;
map.ufSaturation.setValue(gl, this.userData.saturation);
}
} |
@bodison the program can change, so you need to set which to use as far as I can tell. |
@arose true. Mine is not a robust solution, I really should not use this material again after switching to a different one in my pipeline. (or reset programIsSet, but who wants to keep track of that...) |
We should probably try to do something so that this kind of code doesn't have to be so gnarly :( Would it make any sense to somehow put this logic into |
I added a |
Don't know if this is relevant anymore, but |
uniformsNeedUpdate is also fixing an issue for me when using onBeforeRender. But I don't see it in the docs or in the typescript types. Is this the accepted way to update uniforms for shaders, or is there some other way this should be done? |
Related #15581 |
Docs should be added with the above PR. The TS file was already updated here: #18289 It's important to highlight that |
Since there is a solution for I suggest you follow #21305 for an alternative, more generic approach. And there is already an elegant solution with the new node material, see webgpu_instance_uniform (WebGPU only right now). |
Remove milestone? |
Thanks for the pointer! Done. |
Description of the problem
onBeforeRender
was added as a solution for #9662Unfortunately, because of the way
setProgram
works inTHREE.WebGLRenderer
, uniform changes made in theonBeforeRender
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 byonBeforeRender
,refreshMaterial
will fail to be set totrue
, and the uniform will not be refreshed.This was highlighted by @arose here: #9662 (comment)
I've given a shot at supporting this kind of uniform change on a branch here: fallenoak@24c5d9a
I'd have preferred calling the
THREE.Uniform
flagneedsUpdate
, 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
Browser
OS
Hardware Requirements (graphics card, VR Device, ...)
The text was updated successfully, but these errors were encountered: