diff --git a/src/scene/shader-lib/programs/lit-shader.js b/src/scene/shader-lib/programs/lit-shader.js index 013ff1e7b4c..559b7435db1 100644 --- a/src/scene/shader-lib/programs/lit-shader.js +++ b/src/scene/shader-lib/programs/lit-shader.js @@ -190,6 +190,22 @@ class LitShader { } } + /** + * Helper function to define a value in both the vertex and fragment shaders. This is used for + * object / mesh level defines (derived from {@link MeshInstance} shader defines), which describe + * properties of the rendered mesh and so are made available to both shader stages. + * + * @param {boolean} condition - The define is added if the condition is true. + * @param {string} name - The define name. + * @param {string} [value] - The define value. + */ + sharedDefineSet(condition, name, value = '') { + if (condition) { + this.vDefines.set(name, value); + this.fDefines.set(name, value); + } + } + /** * The function generates defines for the lit vertex shader, and handles required attributes and * varyings. The source code of the shader is supplied by litMainVS chunk. This vertex shader is @@ -303,13 +319,13 @@ class LitShader { vDefines.set('MSDF', true); } - // morphing + // morphing - object level define, exposed to both vertex and fragment shaders if (options.useMorphPosition || options.useMorphNormal) { - vDefines.set('MORPHING', true); - if (options.useMorphTextureBasedInt) vDefines.set('MORPHING_INT', true); - if (options.useMorphPosition) vDefines.set('MORPHING_POSITION', true); - if (options.useMorphNormal) vDefines.set('MORPHING_NORMAL', true); + this.sharedDefineSet(true, 'MORPHING', true); + this.sharedDefineSet(options.useMorphTextureBasedInt, 'MORPHING_INT', true); + this.sharedDefineSet(options.useMorphPosition, 'MORPHING_POSITION', true); + this.sharedDefineSet(options.useMorphNormal, 'MORPHING_NORMAL', true); // vertex ids attributes attributes.morph_vertex_id = SEMANTIC_ATTR15; @@ -319,16 +335,20 @@ class LitShader { attributes.vertex_boneIndices = SEMANTIC_BLENDINDICES; + // skinning / batching - object level define, exposed to both vertex and fragment shaders if (options.batch) { - vDefines.set('BATCH', true); + this.sharedDefineSet(true, 'BATCH', true); } else { attributes.vertex_boneWeights = SEMANTIC_BLENDWEIGHT; - vDefines.set('SKIN', true); + this.sharedDefineSet(true, 'SKIN', true); } } - if (options.useInstancing) vDefines.set('INSTANCING', true); - if (options.screenSpace) vDefines.set('SCREENSPACE', true); + // object level defines, exposed to both vertex and fragment shaders + this.sharedDefineSet(options.useInstancing, 'INSTANCING', true); + this.sharedDefineSet(options.screenSpace, 'SCREENSPACE', true); + + // vertex transform only define if (options.pixelSnap) vDefines.set('PIXELSNAP', true); // generate varyings code diff --git a/src/scene/shader-lib/programs/shader-generator-shader.js b/src/scene/shader-lib/programs/shader-generator-shader.js index fd350cc1400..3ce0d54fdec 100644 --- a/src/scene/shader-lib/programs/shader-generator-shader.js +++ b/src/scene/shader-lib/programs/shader-generator-shader.js @@ -49,14 +49,15 @@ class ShaderGeneratorShader extends ShaderGenerator { definitionOptions.attributes = attributes; } - createVertexDefinition(definitionOptions, options, sharedIncludes, wgsl) { - - const desc = options.shaderDesc; - - const includes = new Map(sharedIncludes); - includes.set('transformInstancingVS', ''); // no default instancing, needs to be implemented in the user shader - - const defines = new Map(options.defines); + /** + * Adds object / mesh level defines (derived from {@link MeshInstance} shader defines) to the + * supplied map. These describe properties of the rendered mesh and so are made available to + * both the vertex and fragment shaders. + * + * @param {Map} defines - The defines map to add to. + * @param {object} options - The shader generation options. + */ + addSharedDefines(defines, options) { if (options.skin) defines.set('SKIN', true); if (options.useInstancing) defines.set('INSTANCING', true); if (options.useMorphPosition || options.useMorphNormal) { @@ -65,6 +66,17 @@ class ShaderGeneratorShader extends ShaderGenerator { if (options.useMorphPosition) defines.set('MORPHING_POSITION', true); if (options.useMorphNormal) defines.set('MORPHING_NORMAL', true); } + } + + createVertexDefinition(definitionOptions, options, sharedIncludes, wgsl) { + + const desc = options.shaderDesc; + + const includes = new Map(sharedIncludes); + includes.set('transformInstancingVS', ''); // no default instancing, needs to be implemented in the user shader + + const defines = new Map(options.defines); + this.addSharedDefines(defines, options); definitionOptions.vertexCode = wgsl ? desc.vertexWGSL : desc.vertexGLSL; definitionOptions.vertexIncludes = includes; @@ -77,6 +89,7 @@ class ShaderGeneratorShader extends ShaderGenerator { const includes = new Map(sharedIncludes); const defines = new Map(options.defines); + this.addSharedDefines(defines, options); definitionOptions.fragmentCode = wgsl ? desc.fragmentWGSL : desc.fragmentGLSL; definitionOptions.fragmentIncludes = includes;