From 11e7f63af9fc2d0f6c5329528df77f7650d5e27a Mon Sep 17 00:00:00 2001
From: Olli Etuaho [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]().
+ 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](). +
+
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();