Skip to content

Commit

Permalink
Add callback to identify customized programs
Browse files Browse the repository at this point in the history
In case onBeforeCompile has conditional statements in it, the parameter values affecting the shader code can be returned from customProgramCode so the shader program is correctly fetched from cache or recompiled as needed.
  • Loading branch information
Oletus committed Jan 31, 2020
1 parent c23b245 commit 11e7f63
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 2 deletions.
30 changes: 30 additions & 0 deletions docs/api/en/materials/Material.html
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,36 @@ <h3>[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]().
</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 />
Expand Down
5 changes: 5 additions & 0 deletions src/materials/Material.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 6 additions & 0 deletions src/materials/Material.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/renderers/webgl/WebGLPrograms.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()

};

Expand Down Expand Up @@ -335,7 +335,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) {

}

array.push( parameters.onBeforeCompile.toString() );
array.push( parameters.customProgramCacheKey );

return array.join();

Expand Down

0 comments on commit 11e7f63

Please sign in to comment.