Bladeren bron

Merge pull request #17567 from higharc/custom-program-code

Material: Added callback to identify customized programs
Mr.doob 5 jaren geleden
bovenliggende
commit
92f26f7957

+ 30 - 0
docs/api/en/materials/Material.html

@@ -334,6 +334,36 @@
 		Unlike properties, the callback is not supported by [page:Material.clone .clone](), [page:Material.copy .copy]() and [page:Material.toJSON .toJSON]().
 		</p>
 
+		<h3>[method:String customProgramCacheKey]()</h3>
+		<p>
+		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.
+		</p>
+
+		<p>
+		For example, if onBeforeCompile contains a conditional statement like:<br />
+
+		<code>if ( black ) {
+
+			shader.fragmentShader = shader.fragmentShader.replace('gl_FragColor = vec4(1)', 'gl_FragColor = vec4(0)')
+
+		}
+		</code>
+
+		then customProgramCacheKey should be set like this:<br />
+
+		<code>material.customProgramCacheKey = function() {
+
+			return black ? '1' : '0';
+
+		}
+		</code>
+
+		</p>
+
+		<p>
+		Unlike properties, the callback is not supported by [page:Material.clone .clone](), [page:Material.copy .copy]() and [page:Material.toJSON .toJSON]().
+		</p>
+
 		<h3>[method:null setValues]( [param:object values] )</h3>
 		<p>
 		values -- a container with parameters.<br />

+ 5 - 0
src/materials/Material.d.ts

@@ -327,6 +327,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.

+ 6 - 0
src/materials/Material.js

@@ -85,6 +85,12 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
 	onBeforeCompile: function ( /* shaderobject, renderer */ ) {},
 
+	customProgramCacheKey: function () {
+
+		return this.onBeforeCompile.toString();
+
+	},
+
 	setValues: function ( values ) {
 
 		if ( values === undefined ) return;

+ 2 - 2
src/renderers/webgl/WebGLPrograms.js

@@ -289,7 +289,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()
 
 		};
 
@@ -336,7 +336,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
 
 		}
 
-		array.push( parameters.onBeforeCompile.toString() );
+		array.push( parameters.customProgramCacheKey );
 
 		return array.join();