UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

71 lines (70 loc) 3.24 kB
import { Debug } from "../../../core/debug.js"; import { BINDGROUP_VIEW, bindGroupNames, uniformTypeToName } from "../constants.js"; import { ShaderProcessorGLSL } from "../shader-processor-glsl.js"; class WebglShaderProcessorGLSL extends ShaderProcessorGLSL { /** * @param {GraphicsDevice} device - The graphics device. * @param {object} shaderDefinition - The shader definition. * @param {Shader} shader - The shader. * @returns {{ vshader: string, fshader: string }} The processed shader sources. */ static run(device, shaderDefinition, shader) { const vertexExtracted = WebglShaderProcessorGLSL.extract(shaderDefinition.vshader, true); const fragmentExtracted = WebglShaderProcessorGLSL.extract(shaderDefinition.fshader, true); const concatUniforms = vertexExtracted.uniforms.concat(fragmentExtracted.uniforms); const uniforms = Array.from(new Set(concatUniforms)); const parsedUniforms = WebglShaderProcessorGLSL.parseUniformLines(uniforms, shader); const code = WebglShaderProcessorGLSL.processUniformsGL2(parsedUniforms, shaderDefinition.processingOptions); const vshader = vertexExtracted.src.replace(ShaderProcessorGLSL.MARKER, code); const fshader = fragmentExtracted.src.replace(ShaderProcessorGLSL.MARKER, code); return { vshader, fshader }; } /** * Generate the uniform code for a WebGL2 shader: a single std140 view uniform block plus all * non-view uniforms re-emitted as individual uniforms (which keep their per-uniform commit path). * * @param {Array<UniformLine>} uniforms - The parsed uniform lines. * @param {ShaderProcessorOptions} processingOptions - The shader processing options. * @returns {string} The generated GLSL. */ static processUniformsGL2(uniforms, processingOptions) { let code = ""; const viewFormat = processingOptions.uniformFormats[BINDGROUP_VIEW]; if (viewFormat) { code += WebglShaderProcessorGLSL.getUniformShaderDeclarationGL2(viewFormat, BINDGROUP_VIEW); } uniforms.forEach((uniform) => { if (!processingOptions.hasUniform(uniform.name)) { code += `uniform ${uniform.line}; `; } }); return code; } /** * Generate a WebGL2 std140 uniform block declaration. Unlike the base * {@link ShaderProcessorGLSL#getUniformShaderDeclaration} it emits no `set` / `binding` layout * qualifiers - the block is linked to its binding point at runtime by WebglShader via * `gl.uniformBlockBinding`. * * @param {UniformBufferFormat} format - The uniform buffer format. * @param {number} bindGroup - The bind group index, used to name the block `ub_<bindGroupName>`. * @returns {string} The block declaration. */ static getUniformShaderDeclarationGL2(format, bindGroup) { const name = bindGroupNames[bindGroup]; let code = `layout(std140) uniform ub_${name} { `; format.uniforms.forEach((uniform) => { const typeString = uniformTypeToName[uniform.type]; Debug.assert(typeString.length > 0, `Uniform type ${uniform.type} is not handled.`); code += ` ${typeString} ${uniform.shortName}${uniform.count ? `[${uniform.count}]` : ""}; `; }); return `${code}}; `; } } export { WebglShaderProcessorGLSL };