Suggestion: Better way to update multiple dynamic uniforms

Description of the problem

I’m curious if there’s a better way to handle dynamic uniform updates.

Currently, when using dynamic uniforms, onUpdate callbacks are defined on each THREE.Uniform. Unfortunately, if there are several uniforms for a given material that need dynamic updates, this means multiple callback executions per render call. Based on Chrome’s profiler, I’m a little concerned about how much time is spent in evalDynamic() in my app.

Would it be acceptable to rework the renderer’s handling of render list items a bit, and instead allow an object to define a single callback to update multiple material uniforms?

For example, something like this:

var object = new THREE.Mesh();

object.onRender(function(material, camera) {
  material.uniforms.textureWeight.value = this.textureWeights[material.textureWeightIndex];
  material.uniforms.localDiffuseColor.value = this.localDiffuseColor;
  ... etc etc ...
});

or flipped around:

var material = new THREE.ShaderMaterial();

material.onRender(function(object, camera) {
  this.uniforms.textureWeight.value = object.textureWeights[this.textureWeightIndex];
  this.uniforms.localDiffuseColor.value = object.localDiffuseColor;
  ... etc etc ...
});

I’m not sure if the overhead of checking for the presence of an onRender callback for each object in the scene graph would be more taxing than the cost of calling multiple callbacks per material with dynamic uniforms.

I’m happy to do the work on this, but I’d like a bit of input on whether I’m barking up the wrong tree, or there are other plans to improve uniform handling.

Three.js version
  • Dev
  • r80
Browser
  • All of them
  • Chrome
  • Firefox
  • Internet Explorer
OS
  • All of them
  • Windows
  • Linux
  • Android
  • IOS

Author: Fantashit

2 thoughts on “Suggestion: Better way to update multiple dynamic uniforms

  1. I feel that I proposed exactly this in the past also. I would vote for placing it on the Mesh (Object3D).

  2. could you update webgl_interactive_instances_gpu using the onBeforeRender() approach?

    yes, will do.

Comments are closed.