diff --git a/docs/api/en/materials/Material.html b/docs/api/en/materials/Material.html index 09db0f2131416e..4cda1c4b403a86 100644 --- a/docs/api/en/materials/Material.html +++ b/docs/api/en/materials/Material.html @@ -343,6 +343,36 @@

[method:null onBeforeCompile]( [param:Shader shader], [param:WebGLRenderer r Unlike properties, the callback is not supported by [page:Material.clone .clone](), [page:Material.copy .copy]() and [page:Material.toJSON .toJSON]().

+

[method:String customProgramCacheKey]()

+

+ In case onBeforeCompile is used, this callback can be used to identify values of settings used in onBeforeCompile, so three.js can reuse a cached shader or recompile the shader for this material as needed. +

+ +

+ For example, if onBeforeCompile contains a conditional statement like:
+ + if ( black ) { + + shader.fragmentShader = shader.fragmentShader.replace('gl_FragColor = vec4(1)', 'gl_FragColor = vec4(0)') + + } + + + then customProgramCacheKey should be set like this:
+ + material.customProgramCacheKey = function() { + + return black ? '1' : '0'; + + } + + +

+ +

+ Unlike properties, the callback is not supported by [page:Material.clone .clone](), [page:Material.copy .copy]() and [page:Material.toJSON .toJSON](). +

+

[method:null setValues]( [param:object values] )

values -- a container with parameters.
diff --git a/src/materials/Material.d.ts b/src/materials/Material.d.ts index cdec1d114f0ae4..78de72aaa4069f 100644 --- a/src/materials/Material.d.ts +++ b/src/materials/Material.d.ts @@ -334,6 +334,11 @@ export class Material extends EventDispatcher { */ onBeforeCompile ( shader : Shader, renderer : WebGLRenderer ) : void; + /** + * In case onBeforeCompile is used, this callback can be used to identify values of settings used in onBeforeCompile, so three.js can reuse a cached shader or recompile the shader as needed. + */ + customProgramCacheKey(): string; + /** * Sets the properties based on the values. * @param values A container with parameters. diff --git a/src/materials/Material.js b/src/materials/Material.js index 3967f5d1aa3269..ca3af21793af38 100644 --- a/src/materials/Material.js +++ b/src/materials/Material.js @@ -86,6 +86,12 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), onBeforeCompile: function () {}, + customProgramCacheKey: function () { + + return this.onBeforeCompile.toString(); + + }, + setValues: function ( values ) { if ( values === undefined ) return; diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index b710c186c38823..9bba41e71126ca 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -288,7 +288,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) { rendererExtensionDrawBuffers: isWebGL2 || extensions.get( 'WEBGL_draw_buffers' ) !== null, rendererExtensionShaderTextureLod: isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) !== null, - onBeforeCompile: material.onBeforeCompile + customProgramCacheKey: material.customProgramCacheKey() }; @@ -335,7 +335,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) { } - array.push( parameters.onBeforeCompile.toString() ); + array.push( parameters.customProgramCacheKey ); return array.join();