Three.js: NodeMaterial doesn't always recompile

Created on 9 Jan 2020  路  6Comments  路  Source: mrdoob/three.js

Description of the problem

NodeMaterial is only recompiled the first time the needsUpdate flag is set to true if the WebGL program cache key doesn't change. I believe that this is due to the fact that now material recompiling is based on version and not only on this needsUpdate flag.

To fix this issue, onBeforeCompile.toString method of NodeMaterial shall return the material version instead of the needsCompile flag. It will force programCacheKey to be different and therefore the material will recompile as requested by the needsUpdate flag.

this.onBeforeCompile.toString = function () {

    return self.version

};
Three.js version
  • [x] Dev
Browser
  • [x] All of them
OS
  • [x] All of them

\ping @sunag

Bug Examples

Most helpful comment

Should be fixed via #19833.

I think it's okay to close this one. It can be reopened if there are still recompilation issues with r119.

All 6 comments

It will force programCacheKey to be different and therefore the material will recompile as requested by the needsUpdate flag.

It can be a problem if the proposal is to share the same shader program with other materials.

Do you already try to add needsCompile = false after the build?

this.onBeforeCompile = function ( shader, renderer ) {

        var materialProperties = renderer.properties.get( this );

        if ( this.version !== materialProperties.__version ) {

            this.build( { renderer: renderer } );

            shader.uniforms = this.uniforms;
            shader.vertexShader = this.vertexShader;
            shader.fragmentShader = this.fragmentShader;

            this.needsCompile = false;

        }

    };

No, that doesn't work.

this.onBeforeCompile = function ( shader, renderer ) {

      var materialProperties = renderer.properties.get( this );

      if ( this.version !== materialProperties.__version ) {

          this.build( { renderer: renderer } );

          shader.uniforms = this.uniforms;
          shader.vertexShader = this.vertexShader;
          shader.fragmentShader = this.fragmentShader;

          this.needsCompile = false;

      }

  };

This change worked for r111 and r112, but is no longer sufficient for r113.
The line changed by @njarraud does produce a fix.

/ping @sunag Any ideas? I don't feel like making a PR for something potentially troublesome.

@njarraud @rclankhorst You can test now with the current dev state of the threejs?

Should be fixed via #19833.

I think it's okay to close this one. It can be reopened if there are still recompilation issues with r119.

Was this page helpful?
0 / 5 - 0 ratings