@maptalks/gpu 0.124.4 → 0.125.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @maptalks/gpu v0.124.4
2
+ * @maptalks/gpu v0.125.0
3
3
  * LICENSE : UNLICENSED
4
4
  * (c) 2016-2026 maptalks.com
5
5
  */
@@ -25,11 +25,11 @@ getGlobal()[WGSL_KEY] = sources;
25
25
 
26
26
  var analysisDepthFrag = "struct FragUniforms {\n logDepthBufFC: f32,\n};\n@group(0) @binding($b) var<uniform> uniforms: FragUniforms;\nconst PackUpscale: f32 = 256.0 / 255.0;\nconst UnpackDownscale: f32 = 255.0 / 256.0;\nconst PackFactors: vec3f = vec3f(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0);\nconst UnpackFactors: vec4f = vec4f(UnpackDownscale / PackFactors, UnpackDownscale);\nconst ShiftRight8: f32 = 1.0 / 256.0;\nfn packDepthToRGBA(v: f32) -> vec4f {\n var r: vec4f = vec4f(fract(v * PackFactors), v);\n r = vec4f(r.x, r.yzw - r.xyz * ShiftRight8);\n return r * PackUpscale;\n}\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n let fragCoordZ: f32 = vertexOutput.vHighPrecisionZW[0] / vertexOutput.vHighPrecisionZW[1];\n var glFragColor: vec4f = packDepthToRGBA(fragCoordZ);\n return glFragColor;\n}";
27
27
 
28
- var analysisDepthVert = "#include <get_output>\nstruct Uniforms {\n projViewModelMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n};\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\n#ifdef HAS_ALTITUDE\nstruct VertexInput {\n @location($i) aPosition: vec2f,\n @location($i) aAltitude: f32,\n};\n#else\nstruct VertexInput {\n #include <position_vert>\n};\n#endif\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location($o) vHighPrecisionZW: vec2f,\n @location($o) vFragDepth: f32,\n};\n#ifdef HAS_ALTITUDE\nfn unpackVTPosition(vertexInput: VertexInput) -> vec3f {\n return vec3f(vertexInput.aPosition, vertexInput.aAltitude);\n}\n#endif\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n #ifdef HAS_ALTITUDE\n let i: vec3f = unpackVTPosition(vertexInput);\n let j: vec4f = vec4f(i, 1.0);\n output.position = uniforms.projViewModelMatrix * j;\n #else\n let localPositionMatrix: mat4x4f = getPositionMatrix(vertexInput, &output, uniforms.positionMatrix);\n output.position = uniforms.projViewModelMatrix * localPositionMatrix * getPosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n #endif\n output.vFragDepth = 1.0 + output.position.w;\n output.vHighPrecisionZW = output.position.zw;\n return output;\n}";
28
+ var analysisDepthVert = "#if IS_TERRAIN\n#include <common_pack_float>\n#include <mask_vert>\n#ifdef HAS_MASK_EXTENT\nstruct MatrixUniforms {\n projMatrix: mat4x4f\n};\n#endif\nstruct TerrainUniforms {\n minAltitude: f32,\n projViewModelMatrix: mat4x4f,\n modelMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n};\nstruct VertexOutput {\n @builtin(position) position : vec4f,\n @location($o) vHighPrecisionZW: vec2f,\n};\nstruct VertexInput {\n @location($i) aPosition: vec3f,\n @location($i) aTexCoord: vec2f,\n};\n#ifdef HAS_MASK_EXTENT\n@group(0) @binding($b) var<uniform> matrixUniforms: MatrixUniforms;\n#endif\n@group(0) @binding($b) var<uniform> uniforms: TerrainUniforms;\n@group(0) @binding($b) var flatMaskSampler: sampler;\n@group(0) @binding($b) var flatMask: texture_2d<f32>;\n@vertex\nfn main(\n vertexInput: VertexInput,\n) -> VertexOutput {\n var vertexOutput: VertexOutput;\n var uv: vec2f = vertexInput.aTexCoord;\n let encodedHeight: vec4f = textureSampleLevel(flatMask, flatMaskSampler, uv, 0.0);\n var altitude: f32 = vertexInput.aPosition.z;\n if (length(encodedHeight) < 2.0) {\n let maskHeight: f32 = decodeFloat32(encodedHeight);\n altitude = min(vertexInput.aPosition.z, maskHeight);\n }\n var position: vec4f = vec4f(vertexInput.aPosition.xy, (altitude + uniforms.minAltitude), 1.0);\n position = uniforms.positionMatrix * position;\n #ifdef HAS_MASK_EXTENT\n vertexOutput.position = matrixUniforms.projMatrix * getMaskPosition(position, uniforms.modelMatrix, vertexOutput);\n #else\n vertexOutput.position = uniforms.projViewModelMatrix * position;\n #endif\n vertexOutput.vHighPrecisionZW = vertexOutput.position.zw;\n return vertexOutput;\n}\n#else\n#include <get_output>\nstruct Uniforms {\n projViewModelMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n};\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\nstruct VertexInput {\n#ifdef HAS_ALTITUDE\n @location($i) aPosition: vec2f,\n @location($i) aAltitude: f32,\n#else\n #include <position_vert>\n#endif\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location($o) vHighPrecisionZW: vec2f,\n};\n#ifdef HAS_ALTITUDE\nfn unpackVTPosition(vertexInput: VertexInput) -> vec3f {\n return vec3f(vertexInput.aPosition, vertexInput.aAltitude);\n}\n#endif\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n #ifdef HAS_ALTITUDE\n let i: vec3f = unpackVTPosition(vertexInput);\n let j: vec4f = vec4f(i, 1.0);\n output.position = uniforms.projViewModelMatrix * j;\n #else\n let localPositionMatrix: mat4x4f = getPositionMatrix(vertexInput, &output, uniforms.positionMatrix);\n output.position = uniforms.projViewModelMatrix * localPositionMatrix * getPosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n #endif\n output.vHighPrecisionZW = output.position.zw;\n return output;\n}\n#endif";
29
29
 
30
30
  var analysisExcavateExtentFrag = "@fragment\nfn main() -> @location(0) vec4f {\n return vec4f(1.0, 0.0, 0.0, 1.0);\n}";
31
31
 
32
- var analysisExcavateExtentVert = "#include <get_output>\nstruct Uniforms {\n positionMatrix: mat4x4f,\n projViewModelMatrix: mat4x4f,\n};\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\nstruct VertexInput {\n #include <position_vert>\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f\n};\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let localPositionMatrix: mat4x4f = getPositionMatrix(vertexInput, &output, uniforms.positionMatrix);\n let localPosition: vec4f = localPositionMatrix * getPosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n output.position = uniforms.projViewModelMatrix * localPosition;\n return output;\n}";
32
+ var analysisExcavateExtentVert = "#include <get_output>\nstruct Uniforms {\n positionMatrix: mat4x4f,\n projViewModelMatrix: mat4x4f,\n};\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\nstruct VertexInput {\n #include <position_vert>\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n};\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let localPositionMatrix: mat4x4f = getPositionMatrix(vertexInput, &output, uniforms.positionMatrix);\n let localPosition: vec4f = localPositionMatrix * getPosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n output.position = uniforms.projViewModelMatrix * localPosition;\n return output;\n}";
33
33
 
34
34
  var analysisFloodFrag = "struct FloodAnalysisUniforms {\n extent: vec4f,\n waterHeight: f32,\n hasExtent: f32,\n analysisType: f32,\n};\n@group(0) @binding($b) var<uniform> floodAnalysisUniforms: FloodAnalysisUniforms;\n@group(0) @binding($b) var extentMap: texture_2d<f32>;\n@group(0) @binding($b) var extentMapSampler: sampler;\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n let extent = floodAnalysisUniforms.extent;\n let waterHeight = floodAnalysisUniforms.waterHeight;\n let hasExtent = floodAnalysisUniforms.hasExtent;\n let analysisType = floodAnalysisUniforms.analysisType;\n let width = extent.z - extent.x;\n let height = extent.y - extent.w;\n let uvInExtent = vec2f(\n (vertexOutput.vWorldPosition.x - extent.x) / width,\n (vertexOutput.vWorldPosition.y - extent.w) / height\n );\n let extentColor = textureSample(extentMap, extentMapSampler, uvInExtent);\n var compare: bool;\n if (analysisType == 1.0) {\n compare = vertexOutput.flood_height < waterHeight;\n } else {\n compare = vertexOutput.flood_height >= waterHeight;\n }\n var color: vec4f = vec4f(0.0);\n if (compare) {\n if (hasExtent == 1.0) {\n if (extentColor.r > 0.0) {\n color = vec4f(1.0, 0.0, 0.0, 1.0);\n }\n } else {\n color = vec4f(1.0, 0.0, 0.0, 1.0);\n }\n }\n return color;\n}";
35
35
 
@@ -39,31 +39,31 @@ var analysisInsightFrag = "@group(0) @binding($b) var depthMap: texture_2d<f32>;
39
39
 
40
40
  var analysisInsightVert = "#include <get_output>\nstruct Uniforms {\n modelMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n projViewModelMatrix: mat4x4f,\n};\nstruct ShaderUniforms {\n insight_projViewMatrixFromViewpoint: mat4x4f,\n}\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\nstruct VertexInput {\n #include <position_vert>\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location($o) viewpoint: vec4f,\n};\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let localPositionMatrix: mat4x4f = getPositionMatrix(vertexInput, &output, uniforms.positionMatrix);\n let localPosition: vec4f = localPositionMatrix * getPosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n output.viewpoint = shaderUniforms.insight_projViewMatrixFromViewpoint * uniforms.modelMatrix * localPosition;\n output.position = uniforms.projViewModelMatrix * localPosition;\n return output;\n}";
41
41
 
42
- var analysisViewshedFrag = "struct FragUniforms {\n near: f32,\n far: f32,\n};\n#ifdef HAS_HELPERLINE\n struct HelperUniforms {\n lineColor: vec3f,\n };\n#endif\n@group(0) @binding($b) var<uniform> uniforms: FragUniforms;\n#ifdef HAS_HELPERLINE\n @group(0) @binding($b) var<uniform> helperUniforms: HelperUniforms;\n#endif\n@group(0) @binding($b) var depthMap: texture_2d<f32>;\n@group(0) @binding($b) var depthMapSampler: sampler;\nconst UnpackDownscale: f32 = 255.0 / 256.0;\nconst PackFactors: vec3f = vec3f(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0);\nconst UnpackFactors: vec4f = vec4f(UnpackDownscale / PackFactors, UnpackDownscale);\nfn unpackRGBAToDepth(v: vec4f) -> f32 {\n return dot(v, UnpackFactors);\n}\nfn linear(value: f32) -> f32 {\n let near = uniforms.near;\n let far = uniforms.far;\n let z = value * 2.0 - 1.0;\n return (2.0 * near * far) / (far + near - z * (far - near));\n}\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n #ifdef HAS_HELPERLINE\n return vec4f(helperUniforms.lineColor, 0.009);\n #else\n let near = uniforms.near;\n let far = uniforms.far;\n let viewpoint = vertexOutput.viewpoint;\n let shadowCoord: vec3f = vec3f((viewpoint.xy / viewpoint.w) / 2.0 + 0.5, viewpoint.z / viewpoint.w);\n let rgbaDepth: vec4f = textureSample(depthMap, depthMapSampler, shadowCoord.xy);\n let depth: f32 = unpackRGBAToDepth(rgbaDepth);\n let linearDepth: f32 = linear(depth);\n let linearZ: f32 = linear(shadowCoord.z);\n if (shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 &&\n shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0 &&\n linearZ >= near && linearZ <= far - near) {\n if (linearZ <= linearDepth) {\n return vec4f(0.0, 1.0, 0.0, 1.0); } else {\n return vec4f(1.0, 0.0, 0.0, 1.0); }\n } else {\n return vec4f(0.0, 0.0, 1.0, 1.0);\n }\n #endif\n}";
42
+ var analysisViewshedFrag = "struct FragUniforms {\n near: f32,\n far: f32,\n};\n#ifdef HAS_HELPERLINE\n struct HelperUniforms {\n lineColor: vec3f,\n };\n#endif\n@group(0) @binding($b) var<uniform> uniforms: FragUniforms;\n#ifdef HAS_HELPERLINE\n @group(0) @binding($b) var<uniform> helperUniforms: HelperUniforms;\n#endif\n@group(0) @binding($b) var depthMap: texture_2d<f32>;\n@group(0) @binding($b) var depthMapSampler: sampler;\nconst UnpackDownscale: f32 = 255.0 / 256.0;\nconst PackFactors: vec3f = vec3f(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0);\nconst UnpackFactors: vec4f = vec4f(UnpackDownscale / PackFactors, UnpackDownscale);\nfn unpackRGBAToDepth(v: vec4f) -> f32 {\n return dot(v, UnpackFactors);\n}\nfn linear(value: f32) -> f32 {\n let near = uniforms.near;\n let far = uniforms.far;\n let z = value;\n return (near * far) / (far - z * (far - near));\n}\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n #ifdef HAS_HELPERLINE\n return vec4f(helperUniforms.lineColor, 0.009);\n #else\n let near = uniforms.near;\n let far = uniforms.far;\n let viewpoint = vertexOutput.viewpoint;\n let viewCoord: vec3f = viewpoint.xyz / viewpoint.w;\n let shadowCoord: vec3f = vec3f(viewCoord.xy / 2.0 + 0.5, viewCoord.z);\n let uv = vec2f(shadowCoord.x, 1 - shadowCoord.y);\n let rgbaDepth: vec4f = textureSample(depthMap, depthMapSampler, uv);\n let depth: f32 = unpackRGBAToDepth(rgbaDepth);\n let linearDepth: f32 = linear(depth);\n let linearZ: f32 = linear(shadowCoord.z);\n if (shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 &&\n shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0 &&\n linearZ >= near && linearZ <= far) {\n let delta = (far - near) * 0.08;\n if (linearZ <= (linearDepth + delta)) {\n return vec4f(0.0, 1.0, 0.0, 1.0); } else {\n return vec4f(1.0, 0.0, 0.0, 1.0); }\n } else {\n return vec4f(0.0, 0.0, 1.0, 1.0);\n }\n #endif\n}";
43
43
 
44
- var analysisViewshedVert = "#include <get_output>\nstruct Uniforms {\n modelMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n projViewModelMatrix: mat4x4f,\n};\nstruct ShaderUniforms {\n viewshed_projViewMatrixFromViewpoint: mat4x4f,\n}\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\nstruct VertexInput {\n #include <position_vert>\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location($o) viewpoint: vec4f,\n};\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let localPositionMatrix: mat4x4f = getPositionMatrix(vertexInput, &output, uniforms.positionMatrix);\n let localPosition: vec4f = localPositionMatrix * getPosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n output.viewpoint = shaderUniforms.viewshed_projViewMatrixFromViewpoint * uniforms.modelMatrix * localPosition;\n output.position = uniforms.projViewModelMatrix * localPosition;\n return output;\n}";
44
+ var analysisViewshedVert = "#if IS_TERRAIN\n#include <common_pack_float>\n#include <mask_vert>\n#ifdef HAS_MASK_EXTENT\nstruct MatrixUniforms {\n projMatrix: mat4x4f\n};\n#endif\nstruct TerrainUniforms {\n minAltitude: f32,\n projViewModelMatrix: mat4x4f,\n modelMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n};\nstruct ShaderUniforms {\n viewshed_projViewMatrixFromViewpoint: mat4x4f,\n}\nstruct VertexOutput {\n @builtin(position) position : vec4f,\n @location($o) viewpoint: vec4f,\n};\nstruct VertexInput {\n @location($i) aPosition: vec3f,\n @location($i) aTexCoord: vec2f,\n};\n#ifdef HAS_MASK_EXTENT\n@group(0) @binding($b) var<uniform> matrixUniforms: MatrixUniforms;\n#endif\n@group(0) @binding($b) var<uniform> uniforms: TerrainUniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\n@group(0) @binding($b) var flatMaskSampler: sampler;\n@group(0) @binding($b) var flatMask: texture_2d<f32>;\n@vertex\nfn main(\n vertexInput: VertexInput,\n) -> VertexOutput {\n var output: VertexOutput;\n var uv: vec2f = vertexInput.aTexCoord;\n let encodedHeight: vec4f = textureSampleLevel(flatMask, flatMaskSampler, uv, 0.0);\n var altitude: f32 = vertexInput.aPosition.z;\n if (length(encodedHeight) < 2.0) {\n let maskHeight: f32 = decodeFloat32(encodedHeight);\n altitude = min(vertexInput.aPosition.z, maskHeight);\n }\n var position: vec4f = vec4f(vertexInput.aPosition.xy, (altitude + uniforms.minAltitude), 1.0);\n position = uniforms.positionMatrix * position;\n #ifdef HAS_MASK_EXTENT\n output.position = matrixUniforms.projMatrix * getMaskPosition(position, uniforms.modelMatrix, output);\n #else\n output.position = uniforms.projViewModelMatrix * position;\n #endif\n output.viewpoint = shaderUniforms.viewshed_projViewMatrixFromViewpoint * uniforms.modelMatrix * position;\n return output;\n}\n#else\n#include <get_output>\nstruct Uniforms {\n modelMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n projViewModelMatrix: mat4x4f,\n};\nstruct ShaderUniforms {\n viewshed_projViewMatrixFromViewpoint: mat4x4f,\n}\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\nstruct VertexInput {\n #include <position_vert>\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location($o) viewpoint: vec4f,\n};\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let localPositionMatrix: mat4x4f = getPositionMatrix(vertexInput, &output, uniforms.positionMatrix);\n let localPosition: vec4f = localPositionMatrix * getPosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n output.viewpoint = shaderUniforms.viewshed_projViewMatrixFromViewpoint * uniforms.modelMatrix * localPosition;\n output.position = uniforms.projViewModelMatrix * localPosition;\n return output;\n}\n#endif";
45
45
 
46
- var glAnalysisFrag = "struct FragmentUniforms {\n resolution: vec2f,\n #ifdef HAS_FLOODANALYSE\n flood_waterColor: vec3f,\n flood_waterOpacity: f32,\n #endif\n #ifdef HAS_VIEWSHED\n viewshed_visibleColor: vec4f,\n viewshed_invisibleColor: vec4f,\n #endif\n #ifdef HAS_INSIGHT\n insight_visibleColor: vec4f,\n insight_invisibleColor: vec4f,\n #endif\n #ifdef HAS_CROSSCUT\n cutLineColor: vec4f,\n #endif\n #ifdef HAS_HEIGHTLIMIT\n limitColor: vec3f,\n #endif\n};\n#ifdef HAS_FLOODANALYSE\n @group(0) @binding($b) var floodMap: texture_2d<f32>;\n @group(0) @binding($b) var floodMapSampler: sampler;\n#endif\n#ifdef HAS_SKYLINE\n @group(0) @binding($b) var skylineMap: texture_2d<f32>;\n @group(0) @binding($b) var skylineMapSampler: sampler;\n#endif\n#ifdef HAS_VIEWSHED\n @group(0) @binding($b) var viewshedMap: texture_2d<f32>;\n @group(0) @binding($b) var viewshedMapSampler: sampler;\n#endif\n#ifdef HAS_INSIGHT\n @group(0) @binding($b) var insightMap: texture_2d<f32>;\n @group(0) @binding($b) var insightMapSampler: sampler;\n#endif\n#ifdef HAS_CUT\n @group(0) @binding($b) var meshesMap: texture_2d<f32>;\n @group(0) @binding($b) var meshesMapSampler: sampler;\n @group(0) @binding($b) var invisibleMap: texture_2d<f32>;\n @group(0) @binding($b) var invisibleMapSampler: sampler;\n#endif\n#ifdef HAS_EXCAVATE\n @group(0) @binding($b) var excavateMap: texture_2d<f32>;\n @group(0) @binding($b) var excavateMapSampler: sampler;\n#endif\n#ifdef HAS_CROSSCUT\n @group(0) @binding($b) var crosscutMap: texture_2d<f32>;\n @group(0) @binding($b) var crosscutMapSampler: sampler;\n#endif\n#ifdef HAS_HEIGHTLIMIT\n @group(0) @binding($b) var heightLimitMap: texture_2d<f32>;\n @group(0) @binding($b) var heightLimitMapSampler: sampler;\n#endif\n#ifdef HAS_MULTISAMPLED\n @group(0) @binding($b) var sceneMap: texture_multisampled_2d<f32>;\n#else\n @group(0) @binding($b) var sceneMap: texture_2d<f32>;\n#endif\n@group(0) @binding($b) var sceneMapSampler: sampler;\n@group(0) @binding($b) var<uniform> uniforms: FragmentUniforms;\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n var glFragColor: vec4f;\n var uv = vertexOutput.vTexCoord;\n uv.y = 1.0 - uv.y;\n #ifdef HAS_MULTISAMPLED\n let sceneColor = textureLoad(sceneMap, vec2i(uv * uniforms.resolution), 0);\n #else\n let sceneColor = textureSample(sceneMap, sceneMapSampler, uv);\n #endif\n glFragColor = sceneColor;\n #ifdef HAS_VIEWSHED\n let viewshedColor = textureSample(viewshedMap, viewshedMapSampler, uv);\n if (viewshedColor.r > 0.99) {\n glFragColor = vec4f(\n mix(uniforms.viewshed_invisibleColor.rgb, sceneColor.rgb, uniforms.viewshed_invisibleColor.a),\n sceneColor.a\n );\n } else if (viewshedColor.g > 0.99) {\n glFragColor = vec4f(\n mix(uniforms.viewshed_visibleColor.rgb, sceneColor.rgb, uniforms.viewshed_visibleColor.a),\n sceneColor.a\n );\n } else if (viewshedColor.a < 0.01) {\n glFragColor = vec4f(viewshedColor.rgb, 1.0);\n }\n #endif\n #ifdef HAS_FLOODANALYSE\n let floodColor = textureSample(floodMap, floodMapSampler, uv);\n if (floodColor.r > 0.0) {\n glFragColor = vec4f(\n mix(glFragColor.rgb, uniforms.flood_waterColor, uniforms.flood_waterOpacity),\n glFragColor.a\n );\n }\n #endif\n #ifdef HAS_SKYLINE\n let skylineColor = textureSample(skylineMap, skylineMapSampler, uv);\n if (skylineColor.r > 0.0 || skylineColor.g > 0.0 || skylineColor.b > 0.0) {\n glFragColor = skylineColor;\n }\n #endif\n #ifdef HAS_INSIGHT\n let insightColor = textureSample(insightMap, insightMapSampler, uv);\n if (insightColor.g > 0.0) {\n glFragColor = uniforms.insight_visibleColor;\n } else if (insightColor.r > 0.0) {\n glFragColor = uniforms.insight_invisibleColor;\n }\n #endif\n #ifdef HAS_CUT\n let cutColor = textureSample(invisibleMap, invisibleMapSampler, uv);\n let meshesMapColor = textureSample(meshesMap, meshesMapSampler, uv);\n if (cutColor.r == 1.0 && cutColor.g == 0.0 && cutColor.b == 0.0) {\n glFragColor = meshesMapColor;\n } else if (cutColor.r == 0.0 && cutColor.g == 1.0 && cutColor.b == 0.0) {\n glFragColor = meshesMapColor;\n } else if (cutColor.r == 0.0 && cutColor.g == 0.0 && cutColor.b == 1.0) {\n glFragColor = sceneColor;\n }\n #endif\n #ifdef HAS_EXCAVATE\n let excavateColor = textureSample(excavateMap, excavateMapSampler, uv);\n if (excavateColor.r == 1.0 && excavateColor.g == 0.0 && excavateColor.b == 0.0) {\n glFragColor = sceneColor;\n } else {\n glFragColor = excavateColor;\n }\n #endif\n #ifdef HAS_CROSSCUT\n let crosscutColor = textureSample(crosscutMap, crosscutMapSampler, uv);\n if (crosscutColor.r > 0.0) {\n glFragColor = vec4f(\n mix(uniforms.cutLineColor.rgb, glFragColor.rgb, 0.99),\n glFragColor.a\n );\n }\n #endif\n #ifdef HAS_HEIGHTLIMIT\n let heightLimitColor = textureSample(heightLimitMap, heightLimitMapSampler, uv);\n if (heightLimitColor.r > 0.0) {\n glFragColor = vec4f(\n mix(uniforms.limitColor, glFragColor.rgb, 0.6),\n glFragColor.a\n );\n }\n #endif\n return glFragColor;\n}";
46
+ var glAnalysisFrag = "struct FragmentUniforms {\n resolution: vec2f,\n #ifdef HAS_FLOODANALYSE\n flood_waterColor: vec3f,\n flood_waterOpacity: f32,\n #endif\n #ifdef HAS_VIEWSHED\n viewshed_visibleColor: vec4f,\n viewshed_invisibleColor: vec4f,\n #endif\n #ifdef HAS_INSIGHT\n insight_visibleColor: vec4f,\n insight_invisibleColor: vec4f,\n #endif\n #ifdef HAS_CROSSCUT\n cutLineColor: vec4f,\n #endif\n #ifdef HAS_HEIGHTLIMIT\n limitColor: vec3f,\n #endif\n};\n#ifdef HAS_FLOODANALYSE\n @group(0) @binding($b) var floodMap: texture_2d<f32>;\n @group(0) @binding($b) var floodMapSampler: sampler;\n#endif\n#ifdef HAS_SKYLINE\n @group(0) @binding($b) var skylineMap: texture_2d<f32>;\n @group(0) @binding($b) var skylineMapSampler: sampler;\n#endif\n#ifdef HAS_VIEWSHED\n @group(0) @binding($b) var viewshedMap: texture_2d<f32>;\n @group(0) @binding($b) var viewshedMapSampler: sampler;\n#endif\n#ifdef HAS_INSIGHT\n @group(0) @binding($b) var insightMap: texture_2d<f32>;\n @group(0) @binding($b) var insightMapSampler: sampler;\n#endif\n#ifdef HAS_CUT\n @group(0) @binding($b) var meshesMap: texture_2d<f32>;\n @group(0) @binding($b) var meshesMapSampler: sampler;\n @group(0) @binding($b) var invisibleMap: texture_2d<f32>;\n @group(0) @binding($b) var invisibleMapSampler: sampler;\n#endif\n#ifdef HAS_EXCAVATE\n @group(0) @binding($b) var excavateMap: texture_2d<f32>;\n @group(0) @binding($b) var excavateMapSampler: sampler;\n#endif\n#ifdef HAS_CROSSCUT\n @group(0) @binding($b) var crosscutMap: texture_2d<f32>;\n @group(0) @binding($b) var crosscutMapSampler: sampler;\n#endif\n#ifdef HAS_HEIGHTLIMIT\n @group(0) @binding($b) var heightLimitMap: texture_2d<f32>;\n @group(0) @binding($b) var heightLimitMapSampler: sampler;\n#endif\n@group(0) @binding($b) var sceneMap: texture_2d<f32>;\n@group(0) @binding($b) var sceneMapSampler: sampler;\n@group(0) @binding($b) var<uniform> uniforms: FragmentUniforms;\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n var glFragColor: vec4f;\n var uv = vertexOutput.vTexCoord;\n uv.y = 1.0 - uv.y;\n let sceneColor = textureSample(sceneMap, sceneMapSampler, uv);\n glFragColor = sceneColor;\n #ifdef HAS_VIEWSHED\n let viewshedColor = textureSample(viewshedMap, viewshedMapSampler, uv);\n if (viewshedColor.r > 0.99) {\n glFragColor = vec4f(\n mix(uniforms.viewshed_invisibleColor.rgb, sceneColor.rgb, uniforms.viewshed_invisibleColor.a),\n sceneColor.a\n );\n } else if (viewshedColor.g > 0.99) {\n glFragColor = vec4f(\n mix(uniforms.viewshed_visibleColor.rgb, sceneColor.rgb, uniforms.viewshed_visibleColor.a),\n sceneColor.a\n );\n } else if (viewshedColor.a < 0.01) {\n glFragColor = vec4f(viewshedColor.rgb, 1.0);\n }\n #endif\n #ifdef HAS_FLOODANALYSE\n let floodColor = textureSample(floodMap, floodMapSampler, uv);\n if (floodColor.r > 0.0) {\n glFragColor = vec4f(\n mix(glFragColor.rgb, uniforms.flood_waterColor, uniforms.flood_waterOpacity),\n glFragColor.a\n );\n }\n #endif\n #ifdef HAS_SKYLINE\n let skylineColor = textureSample(skylineMap, skylineMapSampler, uv);\n if (skylineColor.r > 0.0 || skylineColor.g > 0.0 || skylineColor.b > 0.0) {\n glFragColor = skylineColor;\n }\n #endif\n #ifdef HAS_INSIGHT\n let insightColor = textureSample(insightMap, insightMapSampler, uv);\n if (insightColor.g > 0.0) {\n glFragColor = uniforms.insight_visibleColor;\n } else if (insightColor.r > 0.0) {\n glFragColor = uniforms.insight_invisibleColor;\n }\n #endif\n #ifdef HAS_CUT\n let cutColor = textureSample(invisibleMap, invisibleMapSampler, uv);\n let meshesMapColor = textureSample(meshesMap, meshesMapSampler, uv);\n if (cutColor.r == 1.0 && cutColor.g == 0.0 && cutColor.b == 0.0) {\n glFragColor = meshesMapColor;\n } else if (cutColor.r == 0.0 && cutColor.g == 1.0 && cutColor.b == 0.0) {\n glFragColor = meshesMapColor;\n } else if (cutColor.r == 0.0 && cutColor.g == 0.0 && cutColor.b == 1.0) {\n glFragColor = sceneColor;\n }\n #endif\n #ifdef HAS_EXCAVATE\n let excavateColor = textureSample(excavateMap, excavateMapSampler, uv);\n if (excavateColor.r == 1.0 && excavateColor.g == 0.0 && excavateColor.b == 0.0) {\n glFragColor = sceneColor;\n } else {\n glFragColor = excavateColor;\n }\n #endif\n #ifdef HAS_CROSSCUT\n let crosscutColor = textureSample(crosscutMap, crosscutMapSampler, uv);\n if (crosscutColor.r > 0.0) {\n glFragColor = vec4f(\n mix(uniforms.cutLineColor.rgb, glFragColor.rgb, 0.99),\n glFragColor.a\n );\n }\n #endif\n #ifdef HAS_HEIGHTLIMIT\n let heightLimitColor = textureSample(heightLimitMap, heightLimitMapSampler, uv);\n if (heightLimitColor.r > 0.0) {\n glFragColor = vec4f(\n mix(uniforms.limitColor, glFragColor.rgb, 0.6),\n glFragColor.a\n );\n }\n #endif\n return glFragColor;\n}";
47
47
 
48
48
  var glFillFrag = "#if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_frag>\n#endif\nstruct BackFillUniforms {\n polygonFill: vec4f,\n polygonOpacity: f32,\n};\n@group(0) @binding($b) var<uniform> uniforms: BackFillUniforms;\n#ifdef HAS_PATTERN\n@group(0) @binding($b) var polygonPatternFile: texture_2d<f32>;\n@group(0) @binding($b) var polygonPatternFileSampler: sampler;\n#endif\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n#ifdef HAS_PATTERN\n let color = textureSample(polygonPatternFile, polygonPatternFileSampler, vertexOutput.vTexCoord);\n#else\n let color = uniforms.polygonFill;\n#endif\n var fragColor: vec4f = color * uniforms.polygonOpacity;\n#if HAS_SHADOWING && !HAS_BLOOM\n let shadowCoeff = shadow_computeShadow(vertexOutput);\n fragColor = vec4(shadow_blend(fragColor.rgb, shadowCoeff), fragColor.a);\n#endif\n return fragColor;\n}";
49
49
 
50
50
  var glFillVert = "#include <vsm_shadow_vert>\nstruct VertexInput {\n @location($i) aPosition: vec3f,\n#ifdef HAS_PATTERN\n @location($i) aTexCoord: vec2f,\n#endif\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n#ifdef HAS_PATTERN\n @location($o) vTexCoord: vec2f,\n#endif\n};\nstruct BackFillUniforms {\n projViewModelMatrix: mat4x4f,\n modelMatrix: mat4x4f,\n#ifdef HAS_PATTERN\n uvScale: vec2f,\n uvOffset: vec2f,\n#endif\n};\n@group(0) @binding($b) var<uniform> uniforms: BackFillUniforms;\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var vertexOutput: VertexOutput;\n#ifdef HAS_PATTERN\n vertexOutput.vTexCoord = vertexInput.aTexCoord * uniforms.uvScale + uniforms.uvOffset;\n#endif\n let position = vec3f(vertexInput.aPosition.xyz);\n vertexOutput.position = uniforms.projViewModelMatrix * vec4f(position, 1.0);\n#if HAS_SHADOWING && !HAS_BLOOM\n shadow_computeShadowPars(vec4f(position, 1.0), &vertexOutput);\n#endif\n return vertexOutput;\n}";
51
51
 
52
- var glTerrainFrag = "#define SHADER_NAME TERRAIN_MESH\n#include <mask_frag>\n#if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_frag>\n#endif\nstruct TerrainUniforms {\n polygonOpacity: f32,\n};\n@group(0) @binding($b) var<uniform> uniforms: TerrainUniforms;\n@group(0) @binding($b) var skin: texture_2d<f32>;\n@group(0) @binding($b) var skinSampler: sampler;\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n var uv = vec2f(vertexOutput.vUv);\n var color = textureSample(skin, skinSampler, uv);\n #if HAS_SHADOWING && !HAS_BLOOM\n var shadowCoeff = shadow_computeShadow(vertexOutput);\n color.rgb = shadow_blend(color.rgb, shadowCoeff).rgb;\n #endif\n var fragColor = color * uniforms.polygonOpacity;\n #ifdef HAS_MASK_EXTENT\n fragColor = setMask(fragColor);\n #endif\n return fragColor;\n}";
52
+ var glTerrainFrag = "#define SHADER_NAME TERRAIN_MESH\n#include <mask_frag>\n#if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_frag>\n#endif\nstruct LayerUniforms {\n layerOpacity: f32,\n #if HAS_COLORS\n colorsMin: f32,\n colorsMax: f32,\n #endif\n};\n@group(0) @binding($b) var<uniform> layerUniforms: LayerUniforms;\n@group(0) @binding($b) var skin: texture_2d<f32>;\n@group(0) @binding($b) var skinSampler: sampler;\n#if HAS_COLORS\n @group(0) @binding($b) var colorsTexture: texture_2d<f32>;\n @group(0) @binding($b) var colorsTextureSampler: sampler;\n fn getColor(vAltitude: f32) -> vec4f {\n var altitude = clamp(vAltitude, layerUniforms.colorsMin, layerUniforms.colorsMax);\n var altitudeNorm = (altitude - layerUniforms.colorsMin) / (layerUniforms.colorsMax - layerUniforms.colorsMin);\n var colorFromTexture = textureSample(colorsTexture, colorsTextureSampler, vec2f(altitudeNorm, 0.5));\n return colorFromTexture;\n }\n#endif\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n var uv = vec2f(vertexOutput.vUv);\n var color = textureSample(skin, skinSampler, uv);\n #if HAS_COLORS\n var colorFromTexture = getColor(vertexOutput.vAltitude);\n color *= colorFromTexture;\n #endif\n #if HAS_SHADOWING && !HAS_BLOOM\n var shadowCoeff = shadow_computeShadow(vertexOutput);\n color = vec4f(shadow_blend(color.rgb, shadowCoeff).rgb, color.a);\n #endif\n var fragColor = color * layerUniforms.layerOpacity;\n #ifdef HAS_MASK_EXTENT\n fragColor = setMask(fragColor);\n #endif\n return fragColor;\n}";
53
53
 
54
- var glTerrainSkinFrag = "struct TerrrainSkinUniforms {\n tileSize: f32,\n skinDim: vec3f,\n opacity: f32,\n flipY: f32\n}\n@group(0) @binding($b) var<uniform> uniforms: TerrrainSkinUniforms;\n@group(0) @binding($b) var skinTexture: texture_2d<f32>;\n@group(0) @binding($b) var skinTextureSampler: sampler;\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n var fragCoord = vertexOutput.position.xy / 2.0;\n var resolution = vec2f(uniforms.tileSize);\n var uv = (fragCoord - uniforms.skinDim.xy) / (resolution * uniforms.skinDim.z);\n if (uniforms.flipY > 0.5) {\n uv.y = 1.0 - uv.y;\n }\n var color = textureSample(skinTexture, skinTextureSampler, uv);\n var opacity = 0.0;\n if (uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0) {\n opacity = uniforms.opacity;\n }\n return color * opacity;\n}";
54
+ var glTerrainSkinFrag = "struct TerrrainSkinUniforms {\n tileSize: f32,\n skinScale: f32,\n skinDim: vec3f,\n opacity: f32,\n flipY: f32\n}\n@group(0) @binding($b) var<uniform> uniforms: TerrrainSkinUniforms;\n@group(0) @binding($b) var skinTexture: texture_2d<f32>;\n@group(0) @binding($b) var skinTextureSampler: sampler;\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n var fragCoord = vertexOutput.position.xy / uniforms.skinScale;\n var resolution = vec2f(uniforms.tileSize);\n var uv = (fragCoord - uniforms.skinDim.xy) / (resolution * uniforms.skinDim.z);\n if (uniforms.flipY > 0.5) {\n uv.y = 1.0 - uv.y;\n }\n var color = textureSample(skinTexture, skinTextureSampler, uv);\n var opacity = 0.0;\n if (uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0) {\n opacity = uniforms.opacity;\n }\n return color * opacity;\n}";
55
55
 
56
56
  var glTerrainSkinVert = "struct VertexInput {\n @location($i) aPosition: vec2i\n};\nstruct VertexOutput {\n @builtin(position) position : vec4f,\n}\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var vertexOutput: VertexOutput;\n vertexOutput.position = vec4f(vec2f(vertexInput.aPosition), 0.0, 1.0);\n return vertexOutput;\n}";
57
57
 
58
- var glTerrainVert = "#include <common_pack_float>\n#include <mask_vert>\n#if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_vert>\n#endif\nstruct MatrixUniforms {\n projMatrix: mat4x4f,\n heightScale: f32,\n};\nstruct TerrainUniforms {\n minAltitude: f32,\n projViewModelMatrix: mat4x4f,\n modelMatrix: mat4x4f,\n modelViewMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n};\nstruct VertexOutput {\n @builtin(position) position : vec4f,\n @location($o) vUv: vec2f,\n};\nstruct VertexInput {\n @location($i) aPosition: vec3f,\n @location($i) aTexCoord: vec2f,\n};\n@group(0) @binding($b) var<uniform> matrixUniforms: MatrixUniforms;\n@group(0) @binding($b) var<uniform> uniforms: TerrainUniforms;\n@group(0) @binding($b) var flatMaskSampler: sampler;\n@group(0) @binding($b) var flatMask: texture_2d<f32>;\n@vertex\nfn main(\n vertexInput: VertexInput,\n) -> VertexOutput {\n var vertexOutput: VertexOutput;\n var uv: vec2f = vertexInput.aTexCoord;\n let encodedHeight: vec4f = textureSampleLevel(flatMask, flatMaskSampler, uv, 0.0);\n var altitude: f32 = vertexInput.aPosition.z;\n if (length(encodedHeight) < 2.0) {\n let maskHeight: f32 = decodeFloat32(encodedHeight);\n altitude = min(vertexInput.aPosition.z, maskHeight);\n }\n var position: vec4f = vec4f(vertexInput.aPosition.xy, (altitude + uniforms.minAltitude) * matrixUniforms.heightScale, 1.0);\n position = uniforms.positionMatrix * position;\n #ifdef HAS_MASK_EXTENT\n vertexOutput.position = matrixUniforms.projMatrix * getMaskPosition(position, uniforms.modelMatrix, vertexOutput);\n #else\n vertexOutput.position = uniforms.projViewModelMatrix * position;\n #endif\n vertexOutput.vUv = vertexInput.aTexCoord;\n #if HAS_SHADOWING && !HAS_BLOOM\n shadow_computeShadowPars(position, &vertexOutput);\n #endif\n return vertexOutput;\n}";
58
+ var glTerrainVert = "#include <common_pack_float>\n#include <mask_vert>\n#if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_vert>\n#endif\nstruct MatrixUniforms {\n projMatrix: mat4x4f\n};\nstruct TerrainUniforms {\n minAltitude: f32,\n projViewModelMatrix: mat4x4f,\n modelMatrix: mat4x4f,\n modelViewMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n};\nstruct VertexOutput {\n @builtin(position) position : vec4f,\n @location($o) vUv: vec2f,\n #if HAS_COLORS\n @location($o) vAltitude: f32,\n #endif\n};\nstruct VertexInput {\n @location($i) aPosition: vec3f,\n @location($i) aTexCoord: vec2f,\n};\n@group(0) @binding($b) var<uniform> matrixUniforms: MatrixUniforms;\n@group(0) @binding($b) var<uniform> uniforms: TerrainUniforms;\n@group(0) @binding($b) var flatMaskSampler: sampler;\n@group(0) @binding($b) var flatMask: texture_2d<f32>;\n@vertex\nfn main(\n vertexInput: VertexInput,\n) -> VertexOutput {\n var vertexOutput: VertexOutput;\n var uv: vec2f = vertexInput.aTexCoord;\n let encodedHeight: vec4f = textureSampleLevel(flatMask, flatMaskSampler, uv, 0.0);\n var altitude: f32 = vertexInput.aPosition.z;\n if (length(encodedHeight) < 2.0) {\n let maskHeight: f32 = decodeFloat32(encodedHeight);\n altitude = min(vertexInput.aPosition.z, maskHeight);\n }\n var position: vec4f = vec4f(vertexInput.aPosition.xy, (altitude + uniforms.minAltitude), 1.0);\n #if HAS_COLORS\n vertexOutput.vAltitude = position.z;\n #endif\n position = uniforms.positionMatrix * position;\n #ifdef HAS_MASK_EXTENT\n vertexOutput.position = matrixUniforms.projMatrix * getMaskPosition(position, uniforms.modelMatrix, vertexOutput);\n #else\n vertexOutput.position = uniforms.projViewModelMatrix * position;\n #endif\n vertexOutput.vUv = vertexInput.aTexCoord;\n #if HAS_SHADOWING && !HAS_BLOOM\n shadow_computeShadowPars(position, &vertexOutput);\n #endif\n return vertexOutput;\n}";
59
59
 
60
- var glStandardFrag = "#include <hsv_frag>\n#include <srgb_frag>\n#include <highlight_frag>\n#include <snow_frag>\n#include <mask_frag>\n#include <terrain_normal_frag>\n#include <vertex_color_frag>\n#include <excavate_frag>\n#include <compute_texcoord_frag>\n#if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_frag>\n#endif\n#define PI 3.141593\n#define RECIPROCAL_PI 1.0\nstruct MaterialUniforms {\n roughnessMetalness: vec2f,\n albedo: vec3f,\n alpha: f32,\n normal: vec3f,\n emit: vec3f,\n ao: f32,\n specularColor: vec3f,\n glossiness: f32,\n skinColor: vec4f,\n #ifdef MESH_ENV_EXPO\n environmentExposure: f32,\n #endif\n};\nvar<private> materialUniforms: MaterialUniforms;\nstruct SceneUniforms {\n alphaTest: f32,\n emissiveFactor: vec3f,\n baseColorFactor: vec4f,\n baseColorIntensity: f32,\n emitColorFactor: f32,\n occlusionFactor: f32,\n roughnessFactor: f32,\n metallicFactor: f32,\n normalMapFactor: f32,\n specularF0: f32,\n emitMultiplicative: f32,\n normalMapFlipY: f32,\n outputSRGB: f32,\n contrast: f32,\n hsv: vec3f,\n specularAAVariance: f32,\n specularAAThreshold: f32,\n #if HAS_SSR\n invProjMatrix: mat4x4f,\n outputFovInfo: array<vec4f, 2>,\n reprojViewProjMatrix: mat4x4f,\n #endif\n #ifndef HAS_COLOR\n #ifdef IS_LINE_EXTRUSION\n lineColor: vec4f,\n #else\n polygonFill: vec4f,\n #endif\n #endif\n #ifdef HAS_PATTERN\n #ifndef HAS_PATTERN_ANIM\n linePatternAnimSpeed: f32,\n #endif\n #ifndef HAS_PATTERN_GAP\n linePatternGap: f32,\n #endif\n linePatternGapColor: vec4f,\n flipY: f32,\n animSpeedScale: f32,\n uvScale: vec2f,\n atlasSize: vec2f,\n #endif\n #ifdef IS_LINE_EXTRUSION\n lineOpacity: f32,\n #else\n polygonOpacity: f32,\n #endif\n};\nstruct ShaderUniforms {\n #if HAS_IBL_LIGHTING\n hdrHSV: vec3f,\n diffuseSPH: array<vec3f, 9>,\n prefilterMiplevel: vec2f,\n prefilterSize: vec2f,\n #else\n ambientColor: vec3f,\n #endif\n cameraPosition: vec3f,\n cameraNearFar: vec2f,\n #ifndef MESH_ENV_EXPO\n environmentExposure: f32,\n #endif\n environmentTransform: mat3x3f,\n light0_viewDirection: vec3f,\n light0_diffuse: vec4f,\n #if HAS_LAYER_OPACITY\n layerOpacity: f32,\n #endif\n #if HAS_SSR\n outSize: vec2f,\n ssrFactor: f32,\n ssrQuality: f32,\n projMatrix: mat4x4f,\n #endif\n #ifdef HAS_PATTERN\n currentTime: f32,\n #endif\n}\n@group(0) @binding($b) var<uniform> uniforms: SceneUniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\n#if HAS_ALBEDO_MAP\n @group(0) @binding($b) var baseColorTexture: texture_2d<f32>;\n @group(0) @binding($b) var baseColorTextureSampler: sampler;\n#endif\n#if HAS_METALLICROUGHNESS_MAP\n @group(0) @binding($b) var metallicRoughnessTexture: texture_2d<f32>;\n @group(0) @binding($b) var metallicRoughnessTextureSampler: sampler;\n#endif\n#if HAS_EMISSIVE_MAP\n @group(0) @binding($b) var emissiveTexture: texture_2d<f32>;\n @group(0) @binding($b) var emissiveTextureSampler: sampler;\n#endif\n#if HAS_AO_MAP\n @group(0) @binding($b) var occlusionTexture: texture_2d<f32>;\n @group(0) @binding($b) var occlusionTextureSampler: sampler;\n#endif\n#if HAS_NORMAL_MAP && HAS_TANGENT\n @group(0) @binding($b) var normalTexture: texture_2d<f32>;\n @group(0) @binding($b) var normalTextureSampler: sampler;\n#endif\n#if HAS_SKIN_MAP\n @group(0) @binding($b) var skinTexture: texture_2d<f32>;\n @group(0) @binding($b) var skinTextureSampler: sampler;\n#endif\n#if HAS_RANDOM_TEX\n @group(0) @binding($b) var noiseTexture: texture_2d<f32>;\n @group(0) @binding($b) var noiseTextureSampler: sampler;\n#endif\n@group(0) @binding($b) var brdfLUT: texture_2d<f32>;\n@group(0) @binding($b) var brdfLUTSampler: sampler;\n#if HAS_IBL_LIGHTING\n @group(0) @binding($b) var prefilterMap: texture_cube<f32>;\n @group(0) @binding($b) var prefilterMapSampler: sampler;\n#endif\n#if HAS_SSR\n @group(0) @binding($b) var TextureDepth: texture_2d<f32>;\n @group(0) @binding($b) var TextureDepthSampler: sampler;\n @group(0) @binding($b) var TextureReflected: texture_2d<f32>;\n @group(0) @binding($b) var TextureReflectedSampler: sampler;\n#endif\n#if HAS_BUMP_MAP && HAS_TANGENT\n @group(0) @binding($b) var bumpTexture: texture_2d<f32>;\n @group(0) @binding($b) var bumpSampler: sampler;\n#endif\n#if HAS_PATTERN\n @group(0) @binding($b) var linePatternFile: texture_2d<f32>;\n @group(0) @binding($b) var linePatternFileSampler: sampler;\n#endif\nfn sum(v: vec3f) -> f32 {\n return v.x + v.y + v.z;\n}\nfn fetchTexture(tex: texture_2d<f32>, tex_sampler: sampler, uv: vec2f) -> vec4f {\n#ifdef HAS_RANDOM_TEX\n let origin = uniforms.uvOrigin; let uv1 = uv + origin - (origin % vec2f(1.0));\n let randomSeed = textureSample(noiseTexture, noiseSampler, 0.005 * uv1).x;\n let duvdx = dpdx(uv1);\n let duvdy = dpdy(uv1);\n let seed = randomSeed * 8.0;\n var seedFract = fract(seed);\n let seedDigit = floor(seed);\n let seedDigitPlusOne = seedDigit + 1.0;\n let offa = sin(vec2f(3.0, 7.0) * seedDigit);\n let offb = sin(vec2f(3.0, 7.0) * seedDigitPlusOne);\n let velocity = 0.5;\n let cola = textureSampleGrad(tex, tex_sampler, uv + velocity * offa, duvdx, duvdy);\n let colb = textureSampleGrad(tex, tex_sampler, uv + velocity * offb, duvdx, duvdy);\n let diffSum = sum(cola.rgb - colb.rgb);\n let t = smoothstep(0.2, 0.8, seedFract - 0.1 * diffSum);\n return mix(cola, colb, t);\n#else\n return textureSample(tex, tex_sampler, uv);\n#endif\n}\nfn getMaterialAlbedo() -> vec3f {\n return materialUniforms.albedo;\n}\nfn getMaterialAlpha() -> f32 {\n return materialUniforms.alpha;\n}\nfn getMaterialMetalness() -> f32 {\n return materialUniforms.roughnessMetalness.y;\n}\nfn getMaterialRoughness() -> f32 {\n #if SHADING_MODEL_SPECULAR_GLOSSINESS\n return 1.0 - materialUniforms.glossiness;\n #else\n return materialUniforms.roughnessMetalness.x;\n #endif\n}\nfn getMaterialEmitColor() -> vec3f {\n return materialUniforms.emit;\n}\nfn getMaterialSkinColor() -> vec4f {\n return materialUniforms.skinColor;\n}\nfn getMaterialNormalMap() -> vec3f {\n return materialUniforms.normal;\n}\nfn getMaterialOcclusion() -> f32 {\n return materialUniforms.ao;\n}\nfn decodeDepth(pack: vec4f) -> f32 {\n return pack.r + pack.g / 255.0;\n}\nfn transformNormal(factor: f32, normalToTransform: vec3f, t: vec3f, b: vec3f, n: vec3f) -> vec3f {\n let normal = vec3f(normalToTransform.xy * factor, normalToTransform.z);\n let tbn = mat3x3f(t, b, n);\n return normalize(tbn * normal);\n}\nfn D_GGX(roughness: f32, normal: vec3f, H: vec3f) -> f32 {\n let NoH = clamp(dot(normal, H), 0.0, 1.0);\n let a = roughness * roughness;\n let a2 = a * a;\n let d = (NoH * a2 - NoH) * NoH + 1.0;\n return a2 / ( PI * d * d);\n}\nfn F_Schlick(f0: vec3f, f90: f32, L: vec3f, H: vec3f) -> vec3f {\n var VoH = clamp(dot(L, H), 0.0, 1.0);\n VoH = pow(1.0 - VoH, 5.0);\n return f90 * VoH + (1.0 - VoH) * f0;\n}\nfn V_SmithGGXCorrelated(normal: vec3f, V: vec3f, roughness: f32, NoL: f32) -> f32 {\n let NoV = clamp(dot(normal, V), 0.0, 1.0);\n let a = roughness * roughness;\n let GGXL = NoV * (NoL * (1.0 - a) + a);\n let GGXV = NoL * (NoV * (1.0 - a) + a);\n return 0.5 / (GGXV + GGXL);\n}\nfn computeSpecularBRDF(roughness: f32, normal: vec3f, V: vec3f, L: vec3f, specular: vec3f, NoL: f32, f90: f32) -> vec3f {\n let H = normalize(V + L);\n let D = D_GGX(roughness, normal, H);\n let V_S = V_SmithGGXCorrelated(normal, V, roughness, NoL);\n let F = F_Schlick(specular, f90, L, H);\n return (D * V_S * PI) * F;\n}\nfn BRDF_Lambert(diffuseColor: vec3f) -> vec3f {\n return RECIPROCAL_PI * diffuseColor;\n}\nstruct LambertLight {\n diffuse: vec3f,\n specular: vec3f\n}\nfn computeLambert(\n normal: vec3f,\n V: vec3f,\n NoL: f32,\n roughness: f32,\n materialDiffuse: vec3f,\n specular: vec3f,\n lightColor: vec3f,\n L: vec3f,\n f90: f32\n) -> LambertLight {\n var lambert: LambertLight;\n if (NoL <= 0.0) {\n lambert.diffuse = vec3f(0.0);\n lambert.specular = vec3f(0.0);\n return lambert;\n }\n let a = NoL * lightColor;\n let brdf = computeSpecularBRDF(roughness, normal, V, L, specular, NoL, f90);\n lambert.specular = a * brdf;\n lambert.diffuse = a * BRDF_Lambert(materialDiffuse);\n return lambert;\n}\n#if HAS_IBL_LIGHTING\n fn computeDiffuseSPH(normal: vec3f) -> vec3f {\n let n = shaderUniforms.environmentTransform * normal;\n let diffuseSPH = shaderUniforms.diffuseSPH;\n let x = n.x;\n let y = n.y;\n let z = n.z;\n let result = (\n diffuseSPH[0] +\n diffuseSPH[1] * x +\n diffuseSPH[2] * y +\n diffuseSPH[3] * z +\n diffuseSPH[4] * z * x +\n diffuseSPH[5] * y * z +\n diffuseSPH[6] * y * x +\n diffuseSPH[7] * (3.0 * z * z - 1.0) +\n diffuseSPH[8] * (x*x - y*y)\n );\n if (length(shaderUniforms.hdrHSV) > 0.0) {\n return hsv_apply3(result, shaderUniforms.hdrHSV);\n }\n return max(result, vec3f(0.0));\n }\n fn fetchEnvMap(roughness: f32, R: vec3f) -> vec3f {\n let dir = R;\n let maxLevels = shaderUniforms.prefilterMiplevel.x;\n let lod = min(maxLevels, roughness * shaderUniforms.prefilterMiplevel.y);\n var envLight = textureSampleLevel(prefilterMap, prefilterMapSampler, dir, lod).rgb;\n if (length(shaderUniforms.hdrHSV) > 0.0) {\n envLight = hsv_apply3(envLight, shaderUniforms.hdrHSV);\n }\n return envLight;\n }\n fn getIBLEnvMap(N: vec3f, V: vec3f, roughness: f32, frontNormal: vec3f, materialDiffuse: vec3f) -> vec3f {\n let smoothness = 1.0 - roughness;\n let R = mix(N, reflect(-V, N), smoothness * (sqrt(smoothness) + roughness));\n let factor = clamp(1.0 + dot(R, frontNormal), 0.0, 1.0);\n let prefilteredEnvColor = fetchEnvMap(roughness, shaderUniforms.environmentTransform * R) * factor * factor;\n return prefilteredEnvColor;\n }\n#else\n fn getIBLEnvMap(normal: vec3f, eyeVector: vec3f, roughness: f32, frontNormal: vec3f, materialDiffuse: vec3f) -> vec3f {\n return shaderUniforms.ambientColor * BRDF_Lambert(materialDiffuse);\n }\n#endif\nfn computeBRDF(spec: vec3f, roughness: f32, NoV: f32, f90: f32) -> vec3f {\n let rgba = fetchTexture(brdfLUT, brdfLUTSampler, vec2f(NoV, roughness)) * vec4f(255.0, 65280.0, 255.0, 65280.0);\n let b = (rgba[3] + rgba[2]);\n let a = (rgba[1] + rgba[0]);\n return (spec * a + b * f90) / 65535.0;\n}\nfn computeIBLSpecular(\n normal: vec3f,\n eyeVector: vec3f,\n NoV: f32,\n roughness: f32,\n specular: vec3f,\n frontNormal: vec3f,\n f90: f32,\n materialDiffuse: vec3f\n) -> vec3f {\n return getIBLEnvMap(normal, eyeVector, roughness, frontNormal, materialDiffuse) * computeBRDF(specular, roughness, NoV, f90);\n}\nfn computeSpecularAO(ao: f32, NoV: f32) -> f32 {\n let d = NoV + ao;\n return clamp((d * d) - 1.0 + ao, 0.0, 1.0);\n}\n#ifdef HAS_PATTERN\n fn computeUV(input: VertexOutput, texCoord: vec2f) -> vec2f {\n let uv = texCoord % 1.0;\n let uvStart = vec2f(input.vTexInfo.xy);\n let uvSize = vec2f(input.vTexInfo.zw);\n return (uvStart + uv * uvSize) / uniforms.atlasSize;\n }\n#endif\nfn initMaterial(vertexOutput: VertexOutput) -> MaterialUniforms {\n var materialUniforms: MaterialUniforms;\n var uv: vec2f;\n#ifdef HAS_MAP\n uv = computeTexCoord(vertexOutput.vTexCoord, vertexOutput);\n#endif\n#ifdef HAS_UV_FLIP\n uv.y = 1.0 - uv.y;\n#endif\n#if HAS_BUMP_MAP && HAS_TANGENT\n uv = bumpUV(uv, normalize(vertexOutput.vTangentViewPos - vertexOutput.vTangentFragPos));\n#endif\n materialUniforms.albedo = uniforms.baseColorIntensity * uniforms.baseColorFactor.rgb;\n materialUniforms.alpha = uniforms.baseColorFactor.a * vertexOutput.vOpacity;\n#if HAS_PATTERN\n var linesofar = vertexOutput.vLinesofar;\n let uvSize = vertexOutput.vTexInfo.zw;\n#ifdef HAS_PATTERN_GAP\n let myGap = vertexOutput.vLinePatternGap;\n#else\n let myGap = uniforms.linePatternGap;\n#endif\n#ifdef HAS_PATTERN_ANIM\n let myAnimSpeed = vertexOutput.vLinePatternAnimSpeed;\n#else\n let myAnimSpeed = uniforms.linePatternAnimSpeed;\n#endif\n let patternWidth = ceil(uvSize.x * vertexOutput.vPatternHeight / uvSize.y);\n let plusGapWidth = patternWidth * (1.0 + myGap);\n let animSpeed = myAnimSpeed / uniforms.animSpeedScale;\n linesofar += (shaderUniforms.currentTime * -animSpeed * 0.2) % plusGapWidth;\n let patternx = (linesofar / plusGapWidth) % 1.0;\n let patterny = (uniforms.flipY * vertexOutput.vNormalY) % 1.0;\n let texCoord = vec2f(patternx * (1.0 + myGap) * uniforms.uvScale[0], patterny * uniforms.uvScale[1]);\n uv = computeUV(vertexOutput, texCoord);\n var patternColor = fetchTexture(linePatternFile, linePatternFileSampler, uv);\n let inGap = clamp(sign(1.0 / (1.0 + myGap) - patternx) + 0.000001, 0.0, 1.0);\n patternColor = mix(uniforms.linePatternGapColor, patternColor, inGap);\n#ifdef IS_SQUARE_TUBE\n let v = clamp(sign(abs(vertexOutput.vNormalY) - 0.999999), 0.0, 1.0);\n patternColor = mix(patternColor, vec4(1.0), v);\n#endif\n materialUniforms.albedo *= patternColor.rgb;\n materialUniforms.alpha *= patternColor.a;\n#endif\n#if HAS_ALBEDO_MAP\n let baseColor = fetchTexture(baseColorTexture, baseColorTextureSampler, uv);\n materialUniforms.albedo *= sRGBToLinear(baseColor.rgb);\n materialUniforms.alpha *= baseColor.a;\n#endif\n#if HAS_SKIN_MAP\n let skinColorValue = fetchTexture(skinTexture, skinTextureSampler, uv);\n materialUniforms.skinColor = skinColorValue;\n#endif\n#if HAS_COLOR0\n materialUniforms.albedo *= vertexOutput.vColor0.rgb;\n#if COLOR0_SIZE == 4\n materialUniforms.alpha *= vertexOutput.vColor0.a;\n#endif\n#endif\n#if HAS_COLOR\n materialUniforms.albedo *= vertexOutput.vColor.rgb;\n materialUniforms.alpha *= vertexOutput.vColor.a;\n#elif IS_LINE_EXTRUSION\n materialUniforms.albedo *= uniforms.lineColor.rgb;\n materialUniforms.alpha *= uniforms.lineColor.a;\n#else\n materialUniforms.albedo *= uniforms.polygonFill.rgb;\n materialUniforms.alpha *= uniforms.polygonFill.a;\n#endif\n#if HAS_INSTANCE_COLOR\n materialUniforms.albedo *= vertexOutput.vInstanceColor.rgb;\n materialUniforms.alpha *= vertexOutput.vInstanceColor.a;\n#endif\n#if HAS_METALLICROUGHNESS_MAP\n let mrSample = fetchTexture(metallicRoughnessTexture, metallicRoughnessTextureSampler, uv).gb;\n materialUniforms.roughnessMetalness = mrSample * vec2(uniforms.roughnessFactor, uniforms.metallicFactor);\n#else\n materialUniforms.roughnessMetalness = vec2(uniforms.roughnessFactor, uniforms.metallicFactor);\n#endif\n materialUniforms.emit = uniforms.emissiveFactor;\n#if HAS_EMISSIVE_MAP\n if (uniforms.emitMultiplicative == 1.0) {\n materialUniforms.emit *= sRGBToLinear(fetchTexture(emissiveTexture, emissiveTextureSampler, uv).rgb);\n } else {\n materialUniforms.emit += sRGBToLinear(fetchTexture(emissiveTexture, emissiveTextureSampler, uv).rgb);\n }\n#endif\n materialUniforms.emit *= uniforms.emitColorFactor;\n#if HAS_AO_MAP\n let aoTexCoord = computeTexCoord(vertexOutput.vTexCoord1, vertexOutput);\n materialUniforms.ao = fetchTexture(occlusionTexture, occlusionTextureSampler, aoTexCoord).r;\n#else\n materialUniforms.ao = 1.0;\n#endif\n materialUniforms.ao *= uniforms.occlusionFactor;\n#if HAS_NORMAL_MAP && HAS_TANGENT\n var nmap = fetchTexture(normalTexture, normalTextureSampler, uv).xyz * 2.0 - 1.0;\n nmap.y = select(nmap.y, -nmap.y, uniforms.normalMapFlipY == 1.0);\n materialUniforms.normal = nmap;\n#else\n materialUniforms.normal = normalize(vertexOutput.vModelNormal);\n#endif\n#if HAS_TERRAIN_NORMAL && HAS_TANGENT\n var nmap = convertTerrainHeightToNormalMap(uv);\n nmap.y = select(nmap.y, -nmap.y, uniforms.normalMapFlipY == 1.0);\n materialUniforms.normal = nmap;\n#endif\n#if SHADING_MODEL_SPECULAR_GLOSSINESS\n materialUniforms.albedo *= uniforms.diffuseFactor.rgb;\n materialUniforms.alpha *= uniforms.diffuseFactor.a;\n#if HAS_DIFFUSE_MAP\n let diffuse = fetchTexture(diffuseTexture, diffuseTextureSampler, uv);\n materialUniforms.albedo *= sRGBToLinear(diffuse.rgb);\n materialUniforms.alpha *= diffuse.a;\n#endif\n materialUniforms.specularColor = uniforms.specularFactor;\n materialUniforms.glossiness = uniforms.glossinessFactor;\n#if HAS_SPECULARGLOSSINESS_MAP\n let specularGlossiness = fetchTexture(specularGlossinessTexture, specularGlossinessTextureSampler, uv);\n materialUniforms.specularColor *= sRGBToLinear(specularGlossiness.rgb);\n materialUniforms.glossiness *= specularGlossiness.a;\n#endif\n#endif\n return materialUniforms;\n}\nfn HDR_ACES(x: vec3f) -> vec3f {\n const a = 2.51;\n const b = 0.03;\n const c = 2.43;\n const d = 0.59;\n const e = 0.14;\n return (x * (a * x + b)) / (x * (c * x + d) + e);\n}\nfn tonemap(color: vec3f) -> vec3f {\n let tonemapped = HDR_ACES(color);\n return pow(tonemapped, vec3f(1.0/2.2));\n}\nfn normalFiltering(roughness: f32, worldNormal: vec3f) -> f32 {\n let du = dpdx(worldNormal);\n let dv = dpdy(worldNormal);\n let variance = uniforms.specularAAVariance * (dot(du, du) + dot(dv, dv));\n let kernelRoughness = min(2.0 * variance, uniforms.specularAAThreshold);\n let squareRoughness = saturate(roughness * roughness + kernelRoughness);\n return sqrt(squareRoughness);\n}\n#if HAS_SSR\n fn ssrViewToScreen(projection: mat4x4f, viewVertex: vec3f) -> vec3f {\n let projected = projection * vec4f(viewVertex, 1.0);\n return vec3f(0.5 + 0.5 * projected.xy / projected.w, projected.w);\n }\n fn fetchColorLod(level: f32, uv: vec2f) -> vec3f {\n return textureSampleLevel(TextureReflected, TextureReflectedSampler, uv, level).rgb;\n }\n fn linearizeDepth(depth: f32) -> f32 {\n let projection = uniforms.projMatrix;\n let z = depth * 2.0 - 1.0; return -projection[3].z / (z + projection[2].z);\n }\n fn fetchDepth(uv: vec2f) -> f32 {\n let depth = decodeDepth(textureSample(TextureDepth, TextureDepthSampler, uv));\n return depth;\n }\n fn interleavedGradientNoise(fragCoord: vec2f, frameMod: f32) -> f32 {\n let magic = vec3f(0.06711056, 0.00583715, 52.9829189);\n return fract(magic.z * fract(dot(fragCoord.xy + frameMod * vec2f(47.0, 17.0) * 0.695, magic.xy))) * 0.5;\n }\n fn importanceSampling(\n fragCoord: vec2f,\n frameMod: f32,\n tangentX: vec3f,\n tangentY: vec3f,\n tangentZ: vec3f,\n eyeVector: vec3f,\n rough4: f32\n ) -> vec3f {\n var E: vec2f;\n E.x = interleavedGradientNoise(fragCoord.yx, frameMod);\n E.y = fract(E.x * 52.9829189);\n E.y = mix(E.y, 1.0, 0.7);\n let phi = 2.0 * 3.14159 * E.x;\n let cosTheta = pow(max(E.y, 0.000001), rough4 / (2.0 - rough4));\n let sinTheta = sqrt(1.0 - cosTheta * cosTheta);\n var h = vec3f(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);\n h = h.x * tangentX + h.y * tangentY + h.z * tangentZ;\n return normalize((2.0 * dot(eyeVector, h)) * h - eyeVector);\n }\n fn getStepOffset(frameMod: f32) -> f32 {\n return (interleavedGradientNoise(fragCoord.xy, frameMod) - 0.5);\n }\n fn computeRayDirUV(rayOriginUV: vec3f, rayLen: f32, rayDirView: vec3f) -> vec3f {\n let rayDirUV = ssrViewToScreen(uniforms.projMatrix, vViewVertex.xyz + rayDirView * rayLen);\n rayDirUV.z = 1.0 / rayDirUV.z;\n rayDirUV -= rayOriginUV;\n let scaleMaxX = min(1.0, 0.99 * (1.0 - rayOriginUV.x) / max(1e-5, rayDirUV.x));\n let scaleMaxY = min(1.0, 0.99 * (1.0 - rayOriginUV.y) / max(1e-5, rayDirUV.y));\n let scaleMinX = min(1.0, 0.99 * rayOriginUV.x / max(1e-5, -rayDirUV.x));\n let scaleMinY = min(1.0, 0.99 * rayOriginUV.y / max(1e-5, -rayDirUV.y));\n return rayDirUV * min(scaleMaxX, scaleMaxY) * min(scaleMinX, scaleMinY);\n }\n fn binarySearch(rayOriginUV: vec3f, rayDirUV: vec3f, startSteps: ptr<function, f32>, endSteps: ptr<function, f32>) -> f32 {\n let steps = (*startSteps + *endSteps) * 0.5;\n let sampleUV = rayOriginUV + rayDirUV * steps;\n let z = fetchDepth(sampleUV.xy);\n let depth = linearizeDepth(z);\n let sampleDepth = -1.0 / sampleUV.z;\n *startSteps = select(steps, *startSteps, depth > sampleDepth);\n *endSteps = select(*endSteps, steps, depth > sampleDepth);\n return steps;\n }\n fn rayTrace(\n rayOriginUV: vec3f,\n rayLen: f32,\n depthTolerance: f32,\n rayDirView: vec3f,\n roughness: f32,\n frameMod: f32\n ) -> vec4f {\n let checkSteps = 20;\n let invNumSteps = 1.0 / f32(checkSteps);\n depthTolerance *= invNumSteps;\n let rayDirUV = computeRayDirUV(rayOriginUV, rayLen, rayDirView);\n let sampleTime = invNumSteps;\n var diffSampleW = vec3f(0.0, sampleTime, 1.0);\n var sampleUV: vec3f;\n var hit = false;\n var hitDepth = 1.0;\n var steps: f32;\n for (var i = 0; i < checkSteps; i++) {\n sampleUV = rayOriginUV + rayDirUV * diffSampleW.y;\n let z = fetchDepth(sampleUV.xy);\n let depth = linearizeDepth(z);\n let sampleDepth = -1.0 / sampleUV.z;\n let validDepth = clamp(sign(0.999 - z), 0.0, 1.0);\n var depthDiff = validDepth * (sampleDepth - depth);\n depthDiff *= clamp(sign(abs(depthDiff) - rayLen * invNumSteps * invNumSteps), 0.0, 1.0);\n hit = abs(depthDiff + depthTolerance) < depthTolerance;\n let timeLerp = clamp(diffSampleW.x / (diffSampleW.x - depthDiff), 0.0, 1.0);\n let hitTime = select(1.0, (diffSampleW.y + timeLerp * invNumSteps - invNumSteps), hit);\n diffSampleW.z = min(diffSampleW.z, hitTime);\n diffSampleW.x = depthDiff;\n if (hit) {\n var startSteps = diffSampleW.y - invNumSteps;\n var endSteps = diffSampleW.y;\n steps = binarySearch(rayOriginUV, rayDirUV, &startSteps, &endSteps);\n steps = binarySearch(rayOriginUV, rayDirUV, &startSteps, &endSteps);\n steps = binarySearch(rayOriginUV, rayDirUV, &startSteps, &endSteps);\n hitDepth = steps;\n break;\n }\n diffSampleW.y += invNumSteps;\n }\n return vec4f(rayOriginUV + rayDirUV * hitDepth, 1.0 - hitDepth);\n }\n fn fetchColorInRay(\n resRay: vec4f,\n maskSsr: f32,\n specularEnvironment: vec3f,\n specularColor: vec3f,\n roughness: f32\n ) -> vec4f {\n let AB = mix(uniforms.outputFovInfo[0], uniforms.outputFovInfo[1], resRay.x);\n resRay.xyz = vec3f(mix(AB.xy, AB.zw, resRay.y), 1.0) * -1.0 / resRay.z;\n resRay.xyz = (uniforms.reprojViewProjMatrix * vec4f(resRay.xyz, 1.0)).xyw;\n resRay.xy /= resRay.z;\n let maskEdge = clamp(6.0 - 6.0 * max(abs(resRay.x), abs(resRay.y)), 0.0, 1.0);\n resRay.xy = 0.5 + 0.5 * resRay.xy;\n let fetchColor = specularColor * fetchColorLod(roughness * (1.0 - resRay.w), resRay.xy);\n return vec4f(mix(specularEnvironment, fetchColor, maskSsr * maskEdge), 1.0);\n }\n fn ssr(\n fragCoord: vec2f,\n specularEnvironment: vec3f,\n specularColor: vec3f,\n roughness: f32,\n normal: vec3f,\n eyeVector: vec3f\n ) -> vec3f {\n let taaSS = 0.0;\n var result = vec4f(0.0);\n var rough4 = roughness * roughness;\n rough4 = rough4 * rough4;\n let upVector = select(vec3f(1.0, 0.0, 0.0), vec3f(0.0, 0.0, 1.0), abs(normal.z) < 0.999);\n let tangentX = normalize(cross(upVector, normal));\n let tangentY = cross(normal, tangentX);\n var maskSsr = shaderUniforms.ssrFactor * clamp(-4.0 * dot(eyeVector, normal) + 3.8, 0.0, 1.0);\n maskSsr *= clamp(4.7 - roughness * 5.0, 0.0, 1.0);\n let rayOriginUV = ssrViewToScreen(shaderUniforms.projMatrix, vViewVertex.xyz);\n rayOriginUV.z = 1.0 / rayOriginUV.z;\n let rayDirView = importanceSampling(fragCoord, taaSS, tangentX, tangentY, normal, eyeVector, rough4);\n let rayLen = mix(shaderUniforms.cameraNearFar.y + vViewVertex.z, -vViewVertex.z - shaderUniforms.cameraNearFar.x, rayDirView.z * 0.5 + 0.5);\n let depthTolerance = 0.5 * rayLen;\n var resRay: vec4f;\n if (dot(rayDirView, normal) > 0.001 && maskSsr > 0.0) {\n resRay = rayTrace(rayOriginUV, rayLen, depthTolerance, rayDirView, roughness, taaSS);\n if (resRay.w > 0.0) {\n result += fetchColorInRay(resRay, maskSsr, specularEnvironment, specularColor, roughness);\n }\n }\n return select(specularEnvironment, result.rgb / result.w, result.w > 0.0);\n }\n#endif\nfn sRGBTransferOETF(value: vec4f) -> vec4f {\n let isLow: vec3<bool> = value.rgb <= vec3f(0.0031308);\n let highPart: vec3f = pow(value.rgb, vec3f(0.41666)) * 1.055 - vec3f(0.055);\n let lowPart: vec3f = value.rgb * 12.92;\n let rgb: vec3f = select(highPart, lowPart, isLow);\n return vec4f(rgb, value.a);\n}\nfn linearToOutputTexel(value: vec4f) -> vec4f {\n return sRGBTransferOETF(value);\n}\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n materialUniforms = initMaterial(vertexOutput);\n var glFragColor: vec4f;\n let eyeVector = normalize(shaderUniforms.cameraPosition - vertexOutput.vModelVertex);\n #if HAS_DOUBLE_SIDE\n let frontNormal = select(-normalize(vertexOutput.vModelNormal), normalize(vertexOutput.vModelNormal), gl_FrontFacing);\n #else\n let frontNormal = normalize(vertexOutput.vModelNormal);\n #endif\n let f0 = 0.08 * uniforms.specularF0;\n let metal = getMaterialMetalness();\n var materialDiffuse = getMaterialAlbedo();\n #if SHADING_MODEL_SPECULAR_GLOSSINESS\n let materialSpecular = materialUniforms.specularColor;\n #else\n let materialSpecular = mix(vec3f(f0), materialDiffuse, metal);\n #endif\n materialDiffuse *= 1.0 - metal;\n let materialF90 = clamp(50.0 * materialSpecular.g, 0.0, 1.0);\n var materialRoughness = getMaterialRoughness();\n if (uniforms.specularAAVariance > 0.0) {\n materialRoughness = normalFiltering(materialRoughness, frontNormal);\n }\n let materialEmit = getMaterialEmitColor();\n var materialNormal = getMaterialNormalMap();\n #if HAS_TANGENT\n #if HAS_NORMAL_MAP || HAS_TERRAIN_NORMAL\n materialNormal = transformNormal(uniforms.normalMapFactor, materialNormal, vertexOutput.vModelTangent.xyz, vertexOutput.vModelBiTangent, frontNormal);\n #endif\n #endif\n var diffuse = vec3f(0.0);\n var specular = vec3f(0.0);\n #if HAS_IBL_LIGHTING\n diffuse = materialDiffuse * computeDiffuseSPH(materialNormal) * 0.5;\n #else\n diffuse = materialDiffuse * shaderUniforms.ambientColor;\n #endif\n let NoV = dot(materialNormal, eyeVector);\n specular = computeIBLSpecular(materialNormal, eyeVector, NoV, materialRoughness, materialSpecular, frontNormal, materialF90, materialDiffuse);\n #ifdef MESH_ENV_EXPO\n let environmentExposure = materialUniforms.environmentExposure;\n #else\n let environmentExposure = shaderUniforms.environmentExposure;\n #endif\n var specularAO = 1.0;\n let materialAO = getMaterialOcclusion();\n diffuse *= environmentExposure * materialAO;\n #if HAS_IBL_LIGHTING\n specularAO = computeSpecularAO(materialAO, NoV);\n #endif\n #if HAS_SSR\n var ssrfrontNormal = normalize(select(-vertexOutput.vViewNormal, vertexOutput.vViewNormal, gl_FrontFacing));\n var viewNormal = ssrfrontNormal;\n #if HAS_TANGENT\n #if HAS_NORMAL_MAP || HAS_TERRAIN_NORMAL\n var ssrTangent = select(-vertexOutput.vViewTangent, vertexOutput.vViewTangent, gl_FrontFacing);\n ssrTangent.xyz = normalize(ssrTangent.xyz);\n let ssrBinormal = normalize(cross(ssrfrontNormal, ssrTangent.xyz)) * ssrTangent.w;\n viewNormal = transformNormal(uniforms.normalMapFactor, materialNormal, ssrTangent.xyz, ssrBinormal, ssrfrontNormal);\n #endif\n #endif\n specular = ssr(vertexOutput.position, specular, materialSpecular * specularAO, materialRoughness, viewNormal, -normalize(vertexOutput.vViewVertex.xyz));\n #endif\n specular *= environmentExposure * specularAO;\n let modelNormal = vertexOutput.vModelNormal;\n let lightDir = -shaderUniforms.light0_viewDirection;\n let dotNL = saturate(dot(lightDir, materialNormal));\n let lambertResult = computeLambert(materialNormal, eyeVector, dotNL, max(0.045, materialRoughness), materialDiffuse, materialSpecular, shaderUniforms.light0_diffuse.rgb, lightDir, materialF90);\n var ambientDiffuse = lambertResult.diffuse;\n var ambientSpecular = lambertResult.specular;\n #if HAS_SHADOWING && !HAS_BLOOM\n let shadowCoeff = shadow_computeShadow(vertexOutput);\n ambientDiffuse = shadow_blend(ambientDiffuse, shadowCoeff).rgb;\n ambientSpecular = shadow_blend(ambientSpecular, shadowCoeff).rgb;\n #endif\n diffuse += ambientDiffuse;\n specular += ambientSpecular;\n diffuse += materialEmit;\n var frag = specular + diffuse;\n if (uniforms.outputSRGB == 1.0) {\n frag = linearTosRGB(frag);\n }\n #if HAS_SKIN_MAP\n let skinColor = getMaterialSkinColor();\n frag = frag.rgb * (1.0 - skinColor.a) + skinColor.rgb * skinColor.a;\n #if HAS_SHADOWING && !HAS_BLOOM\n frag = shadow_blend(rgb, shadowCoeff).rgb;\n #endif\n #endif\n var alpha = getMaterialAlpha();\n if (alpha < uniforms.alphaTest) {\n discard;\n }\n #if ALPHA_MODE\n #if ALPHA_MODE == 1\n if (alpha < uniforms.alphaCutoff) {\n discard;\n } else {\n alpha = 1.0;\n }\n #else\n alpha = 1.0;\n #endif\n #endif\n #if IS_LINE_EXTRUSION\n alpha *= uniforms.lineOpacity;\n #else\n alpha *= uniforms.polygonOpacity;\n #endif\n glFragColor = vec4f(frag * alpha, alpha);\n #ifdef HAS_VERTEX_COLOR\n glFragColor *= vertexColor_get(vertexOutput);\n #endif\n #ifdef HAS_EXCAVATE_ANALYSIS\n glFragColor = excavateColor(glFragColor);\n #endif\n #ifdef HAS_SNOW\n let snowColor = snow(glFragColor, getMaterialNormalMap(), 1.0);\n glFragColor = vec4f(snowColor, glFragColor.a);\n #endif\n if (uniforms.contrast != 1.0) {\n glFragColor = contrastMatrix(uniforms.contrast) * glFragColor;\n }\n if (length(uniforms.hsv) > 0.0) {\n glFragColor = hsv_apply4(glFragColor, uniforms.hsv);\n }\n #ifdef OUTPUT_NORMAL\n glFragColor = vec4f(frontNormal, 1.0);\n #endif\n #if HAS_HIGHLIGHT_OPACITY || HAS_HIGHLIGHT_COLOR\n glFragColor = highlight_blendColor(glFragColor, vertexOutput);\n #endif\n #ifdef HAS_LAYER_OPACITY\n glFragColor *= shaderUniforms.layerOpacity;\n #endif\n #ifdef HAS_MASK_EXTENT\n glFragColor = setMask(glFragColor);\n #endif\n return glFragColor;\n}";
60
+ var glStandardFrag = "#include <hsv_frag>\n#include <srgb_frag>\n#include <highlight_frag>\n#include <snow_frag>\n#include <mask_frag>\n#include <terrain_normal_frag>\n#include <vertex_color_frag>\n#include <excavate_frag>\n#include <compute_texcoord_frag>\n#if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_frag>\n#endif\n#define PI 3.141593\n#define RECIPROCAL_PI 1.0\nstruct MaterialUniforms {\n roughnessMetalness: vec2f,\n albedo: vec3f,\n alpha: f32,\n normal: vec3f,\n emit: vec3f,\n ao: f32,\n specularColor: vec3f,\n glossiness: f32,\n skinColor: vec4f,\n #ifdef MESH_ENV_EXPO\n environmentExposure: f32,\n #endif\n};\nvar<private> materialUniforms: MaterialUniforms;\nstruct SceneUniforms {\n alphaTest: f32,\n emissiveFactor: vec3f,\n baseColorFactor: vec4f,\n baseColorIntensity: f32,\n emitColorFactor: f32,\n occlusionFactor: f32,\n roughnessFactor: f32,\n metallicFactor: f32,\n normalMapFactor: f32,\n specularF0: f32,\n emitMultiplicative: f32,\n normalMapFlipY: f32,\n outputSRGB: f32,\n contrast: f32,\n hsv: vec3f,\n specularAAVariance: f32,\n specularAAThreshold: f32,\n #if HAS_SSR\n invProjMatrix: mat4x4f,\n outputFovInfo: array<vec4f, 2>,\n reprojViewProjMatrix: mat4x4f,\n #endif\n #ifndef HAS_COLOR\n #ifdef IS_LINE_EXTRUSION\n lineColor: vec4f,\n #else\n polygonFill: vec4f,\n #endif\n #endif\n #ifdef HAS_PATTERN\n #ifndef HAS_PATTERN_ANIM\n linePatternAnimSpeed: f32,\n #endif\n #ifndef HAS_PATTERN_GAP\n linePatternGap: f32,\n #endif\n linePatternGapColor: vec4f,\n flipY: f32,\n animSpeedScale: f32,\n uvScale: vec2f,\n atlasSize: vec2f,\n #endif\n #ifdef IS_LINE_EXTRUSION\n lineOpacity: f32,\n #else\n polygonOpacity: f32,\n #endif\n};\nstruct ShaderUniforms {\n #if HAS_IBL_LIGHTING\n hdrHSV: vec3f,\n diffuseSPH: array<vec3f, 9>,\n prefilterMiplevel: vec2f,\n prefilterSize: vec2f,\n #else\n ambientColor: vec3f,\n #endif\n cameraPosition: vec3f,\n cameraNearFar: vec2f,\n #ifndef MESH_ENV_EXPO\n environmentExposure: f32,\n #endif\n environmentTransform: mat3x3f,\n light0_viewDirection: vec3f,\n light0_diffuse: vec4f,\n #if HAS_LAYER_OPACITY\n layerOpacity: f32,\n #endif\n #if HAS_SSR\n outSize: vec2f,\n ssrFactor: f32,\n ssrQuality: f32,\n projMatrix: mat4x4f,\n #endif\n #ifdef HAS_PATTERN\n currentTime: f32,\n #endif\n}\n@group(0) @binding($b) var<uniform> uniforms: SceneUniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\n#if HAS_ALBEDO_MAP\n @group(0) @binding($b) var baseColorTexture: texture_2d<f32>;\n @group(0) @binding($b) var baseColorTextureSampler: sampler;\n#endif\n#if HAS_METALLICROUGHNESS_MAP\n @group(0) @binding($b) var metallicRoughnessTexture: texture_2d<f32>;\n @group(0) @binding($b) var metallicRoughnessTextureSampler: sampler;\n#endif\n#if HAS_EMISSIVE_MAP\n @group(0) @binding($b) var emissiveTexture: texture_2d<f32>;\n @group(0) @binding($b) var emissiveTextureSampler: sampler;\n#endif\n#if HAS_AO_MAP\n @group(0) @binding($b) var occlusionTexture: texture_2d<f32>;\n @group(0) @binding($b) var occlusionTextureSampler: sampler;\n#endif\n#if HAS_NORMAL_MAP && HAS_TANGENT\n @group(0) @binding($b) var normalTexture: texture_2d<f32>;\n @group(0) @binding($b) var normalTextureSampler: sampler;\n#endif\n#if HAS_SKIN_MAP\n @group(0) @binding($b) var skinTexture: texture_2d<f32>;\n @group(0) @binding($b) var skinTextureSampler: sampler;\n#endif\n#if HAS_RANDOM_TEX\n @group(0) @binding($b) var noiseTexture: texture_2d<f32>;\n @group(0) @binding($b) var noiseTextureSampler: sampler;\n#endif\n@group(0) @binding($b) var brdfLUT: texture_2d<f32>;\n@group(0) @binding($b) var brdfLUTSampler: sampler;\n#if HAS_IBL_LIGHTING\n @group(0) @binding($b) var prefilterMap: texture_cube<f32>;\n @group(0) @binding($b) var prefilterMapSampler: sampler;\n#endif\n#if HAS_SSR\n @group(0) @binding($b) var TextureDepth: texture_2d<f32>;\n @group(0) @binding($b) var TextureDepthSampler: sampler;\n @group(0) @binding($b) var TextureReflected: texture_2d<f32>;\n @group(0) @binding($b) var TextureReflectedSampler: sampler;\n#endif\n#if HAS_BUMP_MAP && HAS_TANGENT\n @group(0) @binding($b) var bumpTexture: texture_2d<f32>;\n @group(0) @binding($b) var bumpSampler: sampler;\n#endif\n#if HAS_PATTERN\n @group(0) @binding($b) var linePatternFile: texture_2d<f32>;\n @group(0) @binding($b) var linePatternFileSampler: sampler;\n#endif\nfn sum(v: vec3f) -> f32 {\n return v.x + v.y + v.z;\n}\nfn fetchTexture(tex: texture_2d<f32>, tex_sampler: sampler, uv: vec2f) -> vec4f {\n#ifdef HAS_RANDOM_TEX\n let origin = uniforms.uvOrigin; let uv1 = uv + origin - (origin % vec2f(1.0));\n let randomSeed = textureSample(noiseTexture, noiseSampler, 0.005 * uv1).x;\n let duvdx = dpdx(uv1);\n let duvdy = dpdy(uv1);\n let seed = randomSeed * 8.0;\n var seedFract = fract(seed);\n let seedDigit = floor(seed);\n let seedDigitPlusOne = seedDigit + 1.0;\n let offa = sin(vec2f(3.0, 7.0) * seedDigit);\n let offb = sin(vec2f(3.0, 7.0) * seedDigitPlusOne);\n let velocity = 0.5;\n let cola = textureSampleGrad(tex, tex_sampler, uv + velocity * offa, duvdx, duvdy);\n let colb = textureSampleGrad(tex, tex_sampler, uv + velocity * offb, duvdx, duvdy);\n let diffSum = sum(cola.rgb - colb.rgb);\n let t = smoothstep(0.2, 0.8, seedFract - 0.1 * diffSum);\n return mix(cola, colb, t);\n#else\n return textureSample(tex, tex_sampler, uv);\n#endif\n}\nfn getMaterialAlbedo() -> vec3f {\n return materialUniforms.albedo;\n}\nfn getMaterialAlpha() -> f32 {\n return materialUniforms.alpha;\n}\nfn getMaterialMetalness() -> f32 {\n return materialUniforms.roughnessMetalness.y;\n}\nfn getMaterialRoughness() -> f32 {\n #if SHADING_MODEL_SPECULAR_GLOSSINESS\n return 1.0 - materialUniforms.glossiness;\n #else\n return materialUniforms.roughnessMetalness.x;\n #endif\n}\nfn getMaterialEmitColor() -> vec3f {\n return materialUniforms.emit;\n}\nfn getMaterialSkinColor() -> vec4f {\n return materialUniforms.skinColor;\n}\nfn getMaterialNormalMap() -> vec3f {\n return materialUniforms.normal;\n}\nfn getMaterialOcclusion() -> f32 {\n return materialUniforms.ao;\n}\nfn decodeDepth(pack: vec4f) -> f32 {\n return pack.r + pack.g / 255.0;\n}\nfn transformNormal(factor: f32, normalToTransform: vec3f, t: vec3f, b: vec3f, n: vec3f) -> vec3f {\n let normal = vec3f(normalToTransform.xy * factor, normalToTransform.z);\n let tbn = mat3x3f(t, b, n);\n return normalize(tbn * normal);\n}\nfn D_GGX(roughness: f32, normal: vec3f, H: vec3f) -> f32 {\n let NoH = clamp(dot(normal, H), 0.0, 1.0);\n let a = roughness * roughness;\n let a2 = a * a;\n let d = (NoH * a2 - NoH) * NoH + 1.0;\n return a2 / ( PI * d * d);\n}\nfn F_Schlick(f0: vec3f, f90: f32, L: vec3f, H: vec3f) -> vec3f {\n var VoH = clamp(dot(L, H), 0.0, 1.0);\n VoH = pow(1.0 - VoH, 5.0);\n return f90 * VoH + (1.0 - VoH) * f0;\n}\nfn V_SmithGGXCorrelated(normal: vec3f, V: vec3f, roughness: f32, NoL: f32) -> f32 {\n let NoV = clamp(dot(normal, V), 0.0, 1.0);\n let a = roughness * roughness;\n let GGXL = NoV * (NoL * (1.0 - a) + a);\n let GGXV = NoL * (NoV * (1.0 - a) + a);\n return 0.5 / (GGXV + GGXL);\n}\nfn computeSpecularBRDF(roughness: f32, normal: vec3f, V: vec3f, L: vec3f, specular: vec3f, NoL: f32, f90: f32) -> vec3f {\n let H = normalize(V + L);\n let D = D_GGX(roughness, normal, H);\n let V_S = V_SmithGGXCorrelated(normal, V, roughness, NoL);\n let F = F_Schlick(specular, f90, L, H);\n return (D * V_S * PI) * F;\n}\nfn BRDF_Lambert(diffuseColor: vec3f) -> vec3f {\n return RECIPROCAL_PI * diffuseColor;\n}\nstruct LambertLight {\n diffuse: vec3f,\n specular: vec3f\n}\nfn computeLambert(\n normal: vec3f,\n V: vec3f,\n NoL: f32,\n roughness: f32,\n materialDiffuse: vec3f,\n specular: vec3f,\n lightColor: vec3f,\n L: vec3f,\n f90: f32\n) -> LambertLight {\n var lambert: LambertLight;\n if (NoL <= 0.0) {\n lambert.diffuse = vec3f(0.0);\n lambert.specular = vec3f(0.0);\n return lambert;\n }\n let a = NoL * lightColor;\n let brdf = computeSpecularBRDF(roughness, normal, V, L, specular, NoL, f90);\n lambert.specular = a * brdf;\n lambert.diffuse = a * BRDF_Lambert(materialDiffuse);\n return lambert;\n}\n#if HAS_IBL_LIGHTING\n fn computeDiffuseSPH(normal: vec3f) -> vec3f {\n let n = shaderUniforms.environmentTransform * normal;\n let diffuseSPH = shaderUniforms.diffuseSPH;\n let x = n.x;\n let y = n.y;\n let z = n.z;\n let result = (\n diffuseSPH[0] +\n diffuseSPH[1] * x +\n diffuseSPH[2] * y +\n diffuseSPH[3] * z +\n diffuseSPH[4] * z * x +\n diffuseSPH[5] * y * z +\n diffuseSPH[6] * y * x +\n diffuseSPH[7] * (3.0 * z * z - 1.0) +\n diffuseSPH[8] * (x*x - y*y)\n );\n if (length(shaderUniforms.hdrHSV) > 0.0) {\n return hsv_apply3(result, shaderUniforms.hdrHSV);\n }\n return max(result, vec3f(0.0));\n }\n fn fetchEnvMap(roughness: f32, R: vec3f) -> vec3f {\n let dir = R;\n let maxLevels = shaderUniforms.prefilterMiplevel.x;\n let lod = min(maxLevels, roughness * shaderUniforms.prefilterMiplevel.y);\n var envLight = textureSampleLevel(prefilterMap, prefilterMapSampler, dir, lod).rgb;\n if (length(shaderUniforms.hdrHSV) > 0.0) {\n envLight = hsv_apply3(envLight, shaderUniforms.hdrHSV);\n }\n return envLight;\n }\n fn getIBLEnvMap(N: vec3f, V: vec3f, roughness: f32, frontNormal: vec3f, materialDiffuse: vec3f) -> vec3f {\n let smoothness = 1.0 - roughness;\n let R = mix(N, reflect(-V, N), smoothness * (sqrt(smoothness) + roughness));\n let factor = clamp(1.0 + dot(R, frontNormal), 0.0, 1.0);\n let prefilteredEnvColor = fetchEnvMap(roughness, shaderUniforms.environmentTransform * R) * factor * factor;\n return prefilteredEnvColor;\n }\n#else\n fn getIBLEnvMap(normal: vec3f, eyeVector: vec3f, roughness: f32, frontNormal: vec3f, materialDiffuse: vec3f) -> vec3f {\n return shaderUniforms.ambientColor * BRDF_Lambert(materialDiffuse);\n }\n#endif\nfn computeBRDF(spec: vec3f, roughness: f32, NoV: f32, f90: f32) -> vec3f {\n let rgba = fetchTexture(brdfLUT, brdfLUTSampler, vec2f(NoV, roughness)) * vec4f(255.0, 65280.0, 255.0, 65280.0);\n let b = (rgba[3] + rgba[2]);\n let a = (rgba[1] + rgba[0]);\n return (spec * a + b * f90) / 65535.0;\n}\nfn computeIBLSpecular(\n normal: vec3f,\n eyeVector: vec3f,\n NoV: f32,\n roughness: f32,\n specular: vec3f,\n frontNormal: vec3f,\n f90: f32,\n materialDiffuse: vec3f\n) -> vec3f {\n return getIBLEnvMap(normal, eyeVector, roughness, frontNormal, materialDiffuse) * computeBRDF(specular, roughness, NoV, f90);\n}\nfn computeSpecularAO(ao: f32, NoV: f32) -> f32 {\n let d = NoV + ao;\n return clamp((d * d) - 1.0 + ao, 0.0, 1.0);\n}\n#ifdef HAS_PATTERN\n fn computeUV(input: VertexOutput, texCoord: vec2f) -> vec2f {\n let uv = texCoord % 1.0;\n let uvStart = vec2f(input.vTexInfo.xy);\n let uvSize = vec2f(input.vTexInfo.zw);\n return (uvStart + uv * uvSize) / uniforms.atlasSize;\n }\n#endif\nfn initMaterial(vertexOutput: VertexOutput) -> MaterialUniforms {\n var materialUniforms: MaterialUniforms;\n var uv: vec2f;\n#ifdef HAS_MAP\n uv = computeTexCoord(vertexOutput.vTexCoord, vertexOutput);\n#endif\n#ifdef HAS_UV_FLIP\n uv.y = 1.0 - uv.y;\n#endif\n#if HAS_BUMP_MAP && HAS_TANGENT\n uv = bumpUV(uv, normalize(vertexOutput.vTangentViewPos - vertexOutput.vTangentFragPos));\n#endif\n materialUniforms.albedo = uniforms.baseColorIntensity * uniforms.baseColorFactor.rgb;\n materialUniforms.alpha = uniforms.baseColorFactor.a * vertexOutput.vOpacity;\n#if HAS_PATTERN\n var linesofar = vertexOutput.vLinesofar;\n let uvSize = vertexOutput.vTexInfo.zw;\n#ifdef HAS_PATTERN_GAP\n let myGap = vertexOutput.vLinePatternGap;\n#else\n let myGap = uniforms.linePatternGap;\n#endif\n#ifdef HAS_PATTERN_ANIM\n let myAnimSpeed = vertexOutput.vLinePatternAnimSpeed;\n#else\n let myAnimSpeed = uniforms.linePatternAnimSpeed;\n#endif\n let patternWidth = ceil(uvSize.x * vertexOutput.vPatternHeight / uvSize.y);\n let plusGapWidth = patternWidth * (1.0 + myGap);\n let animSpeed = myAnimSpeed / uniforms.animSpeedScale;\n linesofar += (shaderUniforms.currentTime * -animSpeed * 0.2) % plusGapWidth;\n let patternx = (linesofar / plusGapWidth) % 1.0;\n let patterny = (uniforms.flipY * vertexOutput.vNormalY) % 1.0;\n let texCoord = vec2f(patternx * (1.0 + myGap) * uniforms.uvScale[0], patterny * uniforms.uvScale[1]);\n uv = computeUV(vertexOutput, texCoord);\n var patternColor = fetchTexture(linePatternFile, linePatternFileSampler, uv);\n let inGap = clamp(sign(1.0 / (1.0 + myGap) - patternx) + 0.000001, 0.0, 1.0);\n patternColor = mix(uniforms.linePatternGapColor, patternColor, inGap);\n#ifdef IS_SQUARE_TUBE\n let v = clamp(sign(abs(vertexOutput.vNormalY) - 0.999999), 0.0, 1.0);\n patternColor = mix(patternColor, vec4(1.0), v);\n#endif\n materialUniforms.albedo *= patternColor.rgb;\n materialUniforms.alpha *= patternColor.a;\n#endif\n#if HAS_ALBEDO_MAP\n let baseColor = fetchTexture(baseColorTexture, baseColorTextureSampler, uv);\n materialUniforms.albedo *= sRGBToLinear(baseColor.rgb);\n materialUniforms.alpha *= baseColor.a;\n#endif\n#if HAS_SKIN_MAP\n let skinColorValue = fetchTexture(skinTexture, skinTextureSampler, uv);\n materialUniforms.skinColor = skinColorValue;\n#endif\n#if HAS_COLOR0\n materialUniforms.albedo *= vertexOutput.vColor0.rgb;\n#if COLOR0_SIZE == 4\n materialUniforms.alpha *= vertexOutput.vColor0.a;\n#endif\n#endif\n#if HAS_COLOR\n materialUniforms.albedo *= vertexOutput.vColor.rgb;\n materialUniforms.alpha *= vertexOutput.vColor.a;\n#elif IS_LINE_EXTRUSION\n materialUniforms.albedo *= uniforms.lineColor.rgb;\n materialUniforms.alpha *= uniforms.lineColor.a;\n#else\n materialUniforms.albedo *= uniforms.polygonFill.rgb;\n materialUniforms.alpha *= uniforms.polygonFill.a;\n#endif\n#if HAS_INSTANCE_COLOR\n materialUniforms.albedo *= vertexOutput.vInstanceColor.rgb;\n materialUniforms.alpha *= vertexOutput.vInstanceColor.a;\n#endif\n#if HAS_METALLICROUGHNESS_MAP\n let mrSample = fetchTexture(metallicRoughnessTexture, metallicRoughnessTextureSampler, uv).gb;\n materialUniforms.roughnessMetalness = mrSample * vec2(uniforms.roughnessFactor, uniforms.metallicFactor);\n#else\n materialUniforms.roughnessMetalness = vec2(uniforms.roughnessFactor, uniforms.metallicFactor);\n#endif\n materialUniforms.emit = uniforms.emissiveFactor;\n#if HAS_EMISSIVE_MAP\n if (uniforms.emitMultiplicative == 1.0) {\n materialUniforms.emit *= sRGBToLinear(fetchTexture(emissiveTexture, emissiveTextureSampler, uv).rgb);\n } else {\n materialUniforms.emit += sRGBToLinear(fetchTexture(emissiveTexture, emissiveTextureSampler, uv).rgb);\n }\n#endif\n materialUniforms.emit *= uniforms.emitColorFactor;\n#if HAS_AO_MAP\n let aoTexCoord = computeTexCoord(vertexOutput.vTexCoord1, vertexOutput);\n materialUniforms.ao = fetchTexture(occlusionTexture, occlusionTextureSampler, aoTexCoord).r;\n#else\n materialUniforms.ao = 1.0;\n#endif\n materialUniforms.ao *= uniforms.occlusionFactor;\n#if HAS_NORMAL_MAP && HAS_TANGENT\n var nmap = fetchTexture(normalTexture, normalTextureSampler, uv).xyz * 2.0 - 1.0;\n nmap.y = select(nmap.y, -nmap.y, uniforms.normalMapFlipY == 1.0);\n materialUniforms.normal = nmap;\n#else\n materialUniforms.normal = normalize(vertexOutput.vModelNormal);\n#endif\n#if HAS_TERRAIN_NORMAL && HAS_TANGENT\n var nmap = convertTerrainHeightToNormalMap(uv);\n nmap.y = select(nmap.y, -nmap.y, uniforms.normalMapFlipY == 1.0);\n materialUniforms.normal = nmap;\n#endif\n#if SHADING_MODEL_SPECULAR_GLOSSINESS\n materialUniforms.albedo *= uniforms.diffuseFactor.rgb;\n materialUniforms.alpha *= uniforms.diffuseFactor.a;\n#if HAS_DIFFUSE_MAP\n let diffuse = fetchTexture(diffuseTexture, diffuseTextureSampler, uv);\n materialUniforms.albedo *= sRGBToLinear(diffuse.rgb);\n materialUniforms.alpha *= diffuse.a;\n#endif\n materialUniforms.specularColor = uniforms.specularFactor;\n materialUniforms.glossiness = uniforms.glossinessFactor;\n#if HAS_SPECULARGLOSSINESS_MAP\n let specularGlossiness = fetchTexture(specularGlossinessTexture, specularGlossinessTextureSampler, uv);\n materialUniforms.specularColor *= sRGBToLinear(specularGlossiness.rgb);\n materialUniforms.glossiness *= specularGlossiness.a;\n#endif\n#endif\n return materialUniforms;\n}\nfn HDR_ACES(x: vec3f) -> vec3f {\n const a = 2.51;\n const b = 0.03;\n const c = 2.43;\n const d = 0.59;\n const e = 0.14;\n return (x * (a * x + b)) / (x * (c * x + d) + e);\n}\nfn tonemap(color: vec3f) -> vec3f {\n let tonemapped = HDR_ACES(color);\n return pow(tonemapped, vec3f(1.0/2.2));\n}\nfn normalFiltering(roughness: f32, worldNormal: vec3f) -> f32 {\n let du = dpdx(worldNormal);\n let dv = dpdy(worldNormal);\n let variance = uniforms.specularAAVariance * (dot(du, du) + dot(dv, dv));\n let kernelRoughness = min(2.0 * variance, uniforms.specularAAThreshold);\n let squareRoughness = saturate(roughness * roughness + kernelRoughness);\n return sqrt(squareRoughness);\n}\n#if HAS_SSR\n fn ssrViewToScreen(projection: mat4x4f, viewVertex: vec3f) -> vec3f {\n let projected = projection * vec4f(viewVertex, 1.0);\n return vec3f(0.5 + 0.5 * projected.xy / projected.w, projected.w);\n }\n fn fetchColorLod(level: f32, uv: vec2f) -> vec3f {\n return textureSampleLevel(TextureReflected, TextureReflectedSampler, uv, level).rgb;\n }\n fn linearizeDepth(depth: f32) -> f32 {\n let projection = uniforms.projMatrix;\n let z = depth * 2.0 - 1.0; return -projection[3].z / (z + projection[2].z);\n }\n fn fetchDepth(uv: vec2f) -> f32 {\n let depth = decodeDepth(textureSample(TextureDepth, TextureDepthSampler, uv));\n return depth;\n }\n fn interleavedGradientNoise(fragCoord: vec2f, frameMod: f32) -> f32 {\n let magic = vec3f(0.06711056, 0.00583715, 52.9829189);\n return fract(magic.z * fract(dot(fragCoord.xy + frameMod * vec2f(47.0, 17.0) * 0.695, magic.xy))) * 0.5;\n }\n fn importanceSampling(\n fragCoord: vec2f,\n frameMod: f32,\n tangentX: vec3f,\n tangentY: vec3f,\n tangentZ: vec3f,\n eyeVector: vec3f,\n rough4: f32\n ) -> vec3f {\n var E: vec2f;\n E.x = interleavedGradientNoise(fragCoord.yx, frameMod);\n E.y = fract(E.x * 52.9829189);\n E.y = mix(E.y, 1.0, 0.7);\n let phi = 2.0 * 3.14159 * E.x;\n let cosTheta = pow(max(E.y, 0.000001), rough4 / (2.0 - rough4));\n let sinTheta = sqrt(1.0 - cosTheta * cosTheta);\n var h = vec3f(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);\n h = h.x * tangentX + h.y * tangentY + h.z * tangentZ;\n return normalize((2.0 * dot(eyeVector, h)) * h - eyeVector);\n }\n fn getStepOffset(frameMod: f32) -> f32 {\n return (interleavedGradientNoise(fragCoord.xy, frameMod) - 0.5);\n }\n fn computeRayDirUV(rayOriginUV: vec3f, rayLen: f32, rayDirView: vec3f) -> vec3f {\n let rayDirUV = ssrViewToScreen(uniforms.projMatrix, vViewVertex.xyz + rayDirView * rayLen);\n rayDirUV.z = 1.0 / rayDirUV.z;\n rayDirUV -= rayOriginUV;\n let scaleMaxX = min(1.0, 0.99 * (1.0 - rayOriginUV.x) / max(1e-5, rayDirUV.x));\n let scaleMaxY = min(1.0, 0.99 * (1.0 - rayOriginUV.y) / max(1e-5, rayDirUV.y));\n let scaleMinX = min(1.0, 0.99 * rayOriginUV.x / max(1e-5, -rayDirUV.x));\n let scaleMinY = min(1.0, 0.99 * rayOriginUV.y / max(1e-5, -rayDirUV.y));\n return rayDirUV * min(scaleMaxX, scaleMaxY) * min(scaleMinX, scaleMinY);\n }\n fn binarySearch(rayOriginUV: vec3f, rayDirUV: vec3f, startSteps: ptr<function, f32>, endSteps: ptr<function, f32>) -> f32 {\n let steps = (*startSteps + *endSteps) * 0.5;\n let sampleUV = rayOriginUV + rayDirUV * steps;\n let z = fetchDepth(sampleUV.xy);\n let depth = linearizeDepth(z);\n let sampleDepth = -1.0 / sampleUV.z;\n *startSteps = select(steps, *startSteps, depth > sampleDepth);\n *endSteps = select(*endSteps, steps, depth > sampleDepth);\n return steps;\n }\n fn rayTrace(\n rayOriginUV: vec3f,\n rayLen: f32,\n depthTolerance: f32,\n rayDirView: vec3f,\n roughness: f32,\n frameMod: f32\n ) -> vec4f {\n let checkSteps = 20;\n let invNumSteps = 1.0 / f32(checkSteps);\n depthTolerance *= invNumSteps;\n let rayDirUV = computeRayDirUV(rayOriginUV, rayLen, rayDirView);\n let sampleTime = invNumSteps;\n var diffSampleW = vec3f(0.0, sampleTime, 1.0);\n var sampleUV: vec3f;\n var hit = false;\n var hitDepth = 1.0;\n var steps: f32;\n for (var i = 0; i < checkSteps; i++) {\n sampleUV = rayOriginUV + rayDirUV * diffSampleW.y;\n let z = fetchDepth(sampleUV.xy);\n let depth = linearizeDepth(z);\n let sampleDepth = -1.0 / sampleUV.z;\n let validDepth = clamp(sign(0.999 - z), 0.0, 1.0);\n var depthDiff = validDepth * (sampleDepth - depth);\n depthDiff *= clamp(sign(abs(depthDiff) - rayLen * invNumSteps * invNumSteps), 0.0, 1.0);\n hit = abs(depthDiff + depthTolerance) < depthTolerance;\n let timeLerp = clamp(diffSampleW.x / (diffSampleW.x - depthDiff), 0.0, 1.0);\n let hitTime = select(1.0, (diffSampleW.y + timeLerp * invNumSteps - invNumSteps), hit);\n diffSampleW.z = min(diffSampleW.z, hitTime);\n diffSampleW.x = depthDiff;\n if (hit) {\n var startSteps = diffSampleW.y - invNumSteps;\n var endSteps = diffSampleW.y;\n steps = binarySearch(rayOriginUV, rayDirUV, &startSteps, &endSteps);\n steps = binarySearch(rayOriginUV, rayDirUV, &startSteps, &endSteps);\n steps = binarySearch(rayOriginUV, rayDirUV, &startSteps, &endSteps);\n hitDepth = steps;\n break;\n }\n diffSampleW.y += invNumSteps;\n }\n return vec4f(rayOriginUV + rayDirUV * hitDepth, 1.0 - hitDepth);\n }\n fn fetchColorInRay(\n resRay: vec4f,\n maskSsr: f32,\n specularEnvironment: vec3f,\n specularColor: vec3f,\n roughness: f32\n ) -> vec4f {\n let AB = mix(uniforms.outputFovInfo[0], uniforms.outputFovInfo[1], resRay.x);\n resRay.xyz = vec3f(mix(AB.xy, AB.zw, resRay.y), 1.0) * -1.0 / resRay.z;\n resRay.xyz = (uniforms.reprojViewProjMatrix * vec4f(resRay.xyz, 1.0)).xyw;\n resRay.xy /= resRay.z;\n let maskEdge = clamp(6.0 - 6.0 * max(abs(resRay.x), abs(resRay.y)), 0.0, 1.0);\n resRay.xy = 0.5 + 0.5 * resRay.xy;\n let fetchColor = specularColor * fetchColorLod(roughness * (1.0 - resRay.w), resRay.xy);\n return vec4f(mix(specularEnvironment, fetchColor, maskSsr * maskEdge), 1.0);\n }\n fn ssr(\n fragCoord: vec2f,\n specularEnvironment: vec3f,\n specularColor: vec3f,\n roughness: f32,\n normal: vec3f,\n eyeVector: vec3f\n ) -> vec3f {\n let taaSS = 0.0;\n var result = vec4f(0.0);\n var rough4 = roughness * roughness;\n rough4 = rough4 * rough4;\n let upVector = select(vec3f(1.0, 0.0, 0.0), vec3f(0.0, 0.0, 1.0), abs(normal.z) < 0.999);\n let tangentX = normalize(cross(upVector, normal));\n let tangentY = cross(normal, tangentX);\n var maskSsr = shaderUniforms.ssrFactor * clamp(-4.0 * dot(eyeVector, normal) + 3.8, 0.0, 1.0);\n maskSsr *= clamp(4.7 - roughness * 5.0, 0.0, 1.0);\n let rayOriginUV = ssrViewToScreen(shaderUniforms.projMatrix, vViewVertex.xyz);\n rayOriginUV.z = 1.0 / rayOriginUV.z;\n let rayDirView = importanceSampling(fragCoord, taaSS, tangentX, tangentY, normal, eyeVector, rough4);\n let rayLen = mix(shaderUniforms.cameraNearFar.y + vViewVertex.z, -vViewVertex.z - shaderUniforms.cameraNearFar.x, rayDirView.z * 0.5 + 0.5);\n let depthTolerance = 0.5 * rayLen;\n var resRay: vec4f;\n if (dot(rayDirView, normal) > 0.001 && maskSsr > 0.0) {\n resRay = rayTrace(rayOriginUV, rayLen, depthTolerance, rayDirView, roughness, taaSS);\n if (resRay.w > 0.0) {\n result += fetchColorInRay(resRay, maskSsr, specularEnvironment, specularColor, roughness);\n }\n }\n return select(specularEnvironment, result.rgb / result.w, result.w > 0.0);\n }\n#endif\nfn sRGBTransferOETF(value: vec4f) -> vec4f {\n let isLow: vec3<bool> = value.rgb <= vec3f(0.0031308);\n let highPart: vec3f = pow(value.rgb, vec3f(0.41666)) * 1.055 - vec3f(0.055);\n let lowPart: vec3f = value.rgb * 12.92;\n let rgb: vec3f = select(highPart, lowPart, isLow);\n return vec4f(rgb, value.a);\n}\nfn linearToOutputTexel(value: vec4f) -> vec4f {\n return sRGBTransferOETF(value);\n}\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n materialUniforms = initMaterial(vertexOutput);\n var glFragColor: vec4f;\n let eyeVector = normalize(shaderUniforms.cameraPosition - vertexOutput.vModelVertex);\n #if HAS_DOUBLE_SIDE\n let frontNormal = select(-normalize(vertexOutput.vModelNormal), normalize(vertexOutput.vModelNormal), gl_FrontFacing);\n #else\n let frontNormal = normalize(vertexOutput.vModelNormal);\n #endif\n let f0 = 0.08 * uniforms.specularF0;\n let metal = getMaterialMetalness();\n var materialDiffuse = getMaterialAlbedo();\n #if SHADING_MODEL_SPECULAR_GLOSSINESS\n let materialSpecular = materialUniforms.specularColor;\n #else\n let materialSpecular = mix(vec3f(f0), materialDiffuse, metal);\n #endif\n materialDiffuse *= 1.0 - metal;\n let materialF90 = clamp(50.0 * materialSpecular.g, 0.0, 1.0);\n var materialRoughness = getMaterialRoughness();\n if (uniforms.specularAAVariance > 0.0) {\n materialRoughness = normalFiltering(materialRoughness, frontNormal);\n }\n let materialEmit = getMaterialEmitColor();\n var materialNormal = getMaterialNormalMap();\n #if HAS_TANGENT\n #if HAS_NORMAL_MAP || HAS_TERRAIN_NORMAL\n materialNormal = transformNormal(uniforms.normalMapFactor, materialNormal, vertexOutput.vModelTangent.xyz, vertexOutput.vModelBiTangent, frontNormal);\n #endif\n #endif\n var diffuse = vec3f(0.0);\n var specular = vec3f(0.0);\n #if HAS_IBL_LIGHTING\n diffuse = materialDiffuse * computeDiffuseSPH(materialNormal) * 0.5;\n #else\n diffuse = materialDiffuse * shaderUniforms.ambientColor;\n #endif\n let NoV = dot(materialNormal, eyeVector);\n specular = computeIBLSpecular(materialNormal, eyeVector, NoV, materialRoughness, materialSpecular, frontNormal, materialF90, materialDiffuse);\n #ifdef MESH_ENV_EXPO\n let environmentExposure = materialUniforms.environmentExposure;\n #else\n let environmentExposure = shaderUniforms.environmentExposure;\n #endif\n var specularAO = 1.0;\n let materialAO = getMaterialOcclusion();\n diffuse *= environmentExposure * materialAO;\n #if HAS_IBL_LIGHTING\n specularAO = computeSpecularAO(materialAO, NoV);\n #endif\n #if HAS_SSR\n var ssrfrontNormal = normalize(select(-vertexOutput.vViewNormal, vertexOutput.vViewNormal, gl_FrontFacing));\n var viewNormal = ssrfrontNormal;\n #if HAS_TANGENT\n #if HAS_NORMAL_MAP || HAS_TERRAIN_NORMAL\n var ssrTangent = select(-vertexOutput.vViewTangent, vertexOutput.vViewTangent, gl_FrontFacing);\n ssrTangent.xyz = normalize(ssrTangent.xyz);\n let ssrBinormal = normalize(cross(ssrfrontNormal, ssrTangent.xyz)) * ssrTangent.w;\n viewNormal = transformNormal(uniforms.normalMapFactor, materialNormal, ssrTangent.xyz, ssrBinormal, ssrfrontNormal);\n #endif\n #endif\n specular = ssr(vertexOutput.position, specular, materialSpecular * specularAO, materialRoughness, viewNormal, -normalize(vertexOutput.vViewVertex.xyz));\n #endif\n specular *= environmentExposure * specularAO;\n let modelNormal = vertexOutput.vModelNormal;\n let lightDir = -shaderUniforms.light0_viewDirection;\n let dotNL = saturate(dot(lightDir, materialNormal));\n let lambertResult = computeLambert(materialNormal, eyeVector, dotNL, max(0.045, materialRoughness), materialDiffuse, materialSpecular, shaderUniforms.light0_diffuse.rgb, lightDir, materialF90);\n var ambientDiffuse = lambertResult.diffuse;\n var ambientSpecular = lambertResult.specular;\n #if HAS_SHADOWING && !HAS_BLOOM\n let shadowCoeff = shadow_computeShadow(vertexOutput);\n ambientDiffuse = shadow_blend(ambientDiffuse, shadowCoeff).rgb;\n ambientSpecular = shadow_blend(ambientSpecular, shadowCoeff).rgb;\n #endif\n diffuse += ambientDiffuse;\n specular += ambientSpecular;\n diffuse += materialEmit;\n var frag = specular + diffuse;\n if (uniforms.outputSRGB == 1.0) {\n frag = linearTosRGB(frag);\n }\n #if HAS_SKIN_MAP\n let skinColor = getMaterialSkinColor();\n frag = frag.rgb * (1.0 - skinColor.a) + skinColor.rgb * skinColor.a;\n #if HAS_SHADOWING && !HAS_BLOOM\n frag = shadow_blend(frag.rgb, shadowCoeff).rgb;\n #endif\n #endif\n var alpha = getMaterialAlpha();\n if (alpha < uniforms.alphaTest) {\n discard;\n }\n #if ALPHA_MODE\n #if ALPHA_MODE == 1\n if (alpha < uniforms.alphaCutoff) {\n discard;\n } else {\n alpha = 1.0;\n }\n #else\n alpha = 1.0;\n #endif\n #endif\n #if IS_LINE_EXTRUSION\n alpha *= uniforms.lineOpacity;\n #else\n alpha *= uniforms.polygonOpacity;\n #endif\n glFragColor = vec4f(frag * alpha, alpha);\n #ifdef HAS_VERTEX_COLOR\n glFragColor *= vertexColor_get(vertexOutput);\n #endif\n #ifdef HAS_EXCAVATE_ANALYSIS\n glFragColor = excavateColor(glFragColor);\n #endif\n #ifdef HAS_SNOW\n let snowColor = snow(glFragColor, getMaterialNormalMap(), 1.0);\n glFragColor = vec4f(snowColor, glFragColor.a);\n #endif\n if (uniforms.contrast != 1.0) {\n glFragColor = contrastMatrix(uniforms.contrast) * glFragColor;\n }\n if (length(uniforms.hsv) > 0.0) {\n glFragColor = hsv_apply4(glFragColor, uniforms.hsv);\n }\n #ifdef OUTPUT_NORMAL\n glFragColor = vec4f(frontNormal, 1.0);\n #endif\n #if HAS_HIGHLIGHT_OPACITY || HAS_HIGHLIGHT_COLOR\n glFragColor = highlight_blendColor(glFragColor, vertexOutput);\n #endif\n #ifdef HAS_LAYER_OPACITY\n glFragColor *= shaderUniforms.layerOpacity;\n #endif\n #ifdef HAS_MASK_EXTENT\n glFragColor = setMask(glFragColor);\n #endif\n return glFragColor;\n}";
61
61
 
62
- var glStandardVert = "#include <highlight_vert>\n#include <line_extrusion_vert>\n#include <get_output>\n#include <vsm_shadow_vert>\n#include <vertex_color_vert>\n#ifdef PICKING_MODE\n #include <fbo_picking_vert>\n#endif\n#include <excavate_vert>\n#include <common_pack_float>\nstruct VertexInput {\n #include <position_vert>\n #if HAS_MAP || HAS_TERRAIN_FLAT_MASK\n #ifdef HAS_DRACO_TEXCOORD\n @location($i) aTexCoord: vec2u,\n #else\n @location($i) aTexCoord: vec2f,\n #endif\n #endif\n #if HAS_MAP\n #ifdef HAS_I3S_UVREGION\n @location($i) uvRegion: vec4f,\n #endif\n #if HAS_AO_MAP\n @location($i) aTexCoord1: vec2f,\n #endif\n #endif\n #if HAS_COLOR\n @location($i) aColor: vec4u,\n #endif\n #ifdef HAS_OPACITY\n @location($i) aOpacity: u32,\n #endif\n #if HAS_COLOR0\n #if COLOR0_SIZE == 3\n @location($i) aColor0: vec3u,\n #else\n @location($i) aColor0: vec4u,\n #endif\n #endif\n #if HAS_TANGENT\n @location($i) aTangent: vec4f,\n #elif HAS_NORMAL\n #ifdef NORMAL_IS_INT\n @location($i) aNormal: vec4i,\n #elif NORMAL_IS_UINT\n @location($i) aNormal: vec4u,\n #else\n @location($i) aNormal: vec3f,\n #endif\n #endif\n}\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n #ifdef HAS_SSR\n @location($o) vViewNormal: vec3f,\n #ifdef HAS_TANGENT\n @location($o) vViewTangent: vec4f,\n #endif\n #endif\n @location($o) vModelNormal: vec3f,\n @location($o) vViewVertex: vec4f,\n #if HAS_TANGENT\n @location($o) vModelTangent: vec4f,\n @location($o) vModelBiTangent: vec3f,\n #endif\n @location($o) vModelVertex: vec3f,\n #if HAS_MAP\n @location($o) vTexCoord: vec2f,\n #ifdef HAS_AO_MAP\n @location($o) vTexCoord1: vec2f,\n #endif\n #ifdef HAS_I3S_UVREGION\n @location($o) vUvRegion: vec4f,\n #endif\n #endif\n #if HAS_COLOR\n @location($o) vColor: vec4f,\n #endif\n @location($o) vOpacity: f32,\n #if HAS_COLOR0\n @location($o) vColor0: vec4f,\n #endif\n #if HAS_BUMP_MAP && HAS_TANGENT\n @location($o) vTangentViewPos: vec3f,\n @location($o) vTangentFragPos: vec3f,\n #endif\n}\nstruct ShaderUniforms {\n cameraPosition: vec3f,\n projMatrix: mat4x4f,\n}\nstruct Uniforms {\n uvOrigin: vec2f,\n uvScale: vec2f,\n uvOffset: vec2f,\n uvRotation: f32,\n modelMatrix: mat4x4f,\n modelViewMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n modelNormalMatrix: mat3x3f,\n #ifdef HAS_SSR\n modelViewNormalMatrix: mat3x3f,\n #endif\n};\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\nvar<private> Vertex: vec3f;\nvar<private> Normal: vec3f;\nvar<private> Tangent: vec4f;\nconst mid = 0.5;\nfn toTangentFrame(q: vec4f) -> vec3f {\n return vec3f(0.0, 0.0, 1.0) +\n vec3f(2.0, -2.0, -2.0) * q.x * q.zwx +\n vec3f(2.0, 2.0, -2.0) * q.y * q.wzy;\n}\nstruct TangentFrame {\n n: vec3f,\n t: vec3f\n}\nfn toTangentFrameWithTangent(q: vec4f) -> TangentFrame {\n var out: TangentFrame;\n out.n = toTangentFrame(q);\n out.t = vec3f(1.0, 0.0, 0.0) +\n vec3f(-2.0, 2.0, -2.0) * q.y * q.yxw +\n vec3f(-2.0, 2.0, 2.0) * q.z * q.zwx;\n return out;\n}\nfn rotateUV(uv: vec2f, rotation: f32) -> vec2f {\n return vec2f(\n cos(rotation) * (uv.x - mid) + sin(rotation) * (uv.y - mid) + mid,\n cos(rotation) * (uv.y - mid) - sin(rotation) * (uv.x - mid) + mid\n );\n}\n#if HAS_MAP\nfn transformTexcoord(uv: vec2f) -> vec2f {\n let decodedTexCoord = decode_getTexcoord(uv);\n #ifdef HAS_RANDOM_TEX\n let origin = uniforms.uvOrigin;\n let texCoord = decodedTexCoord * uniforms.uvScale + uniforms.uvOffset;\n return (origin % 1.0) + texCoord;\n #else\n var origin = uniforms.uvOrigin;\n var texCoord = decodedTexCoord * uniforms.uvScale;\n if (uniforms.uvRotation != 0.0) {\n origin = rotateUV(origin, uniforms.uvRotation);\n texCoord = rotateUV(texCoord, uniforms.uvRotation);\n }\n return (origin % 1.0) + texCoord + uniforms.uvOffset;\n #endif\n}\n#endif\nfn transposeMat3(inMat: mat3x3f) -> mat3x3f {\n let i0 = inMat[0];\n let i1 = inMat[1];\n let i2 = inMat[2];\n return mat3x3f(\n vec3f(i0.x, i1.x, i2.x),\n vec3f(i0.y, i1.y, i2.y),\n vec3f(i0.z, i1.z, i2.z)\n );\n}\n@vertex\nfn main(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let localPositionMatrix = getPositionMatrix(input, &output, uniforms.positionMatrix);\n #ifdef IS_LINE_EXTRUSION\n let linePosition = getLineExtrudePosition(vec3f(input.aPosition.xyz), input);\n let localVertex = getPosition(linePosition, input);\n #else\n let localVertex = getPosition(vec3f(input.aPosition.xyz), input);\n #endif\n output.vModelVertex = (uniforms.modelMatrix * localVertex).xyz;\n let position = localPositionMatrix * localVertex;\n let viewVertex = uniforms.modelViewMatrix * position;\n output.vViewVertex = viewVertex;\n #ifdef HAS_MASK_EXTENT\n output.position = shaderUniforms.projMatrix * getMaskPosition(position, uniforms.modelMatrix);\n #else\n output.position = shaderUniforms.projMatrix * viewVertex;\n #endif\n #ifdef PICKING_MODE\n var alpha = 1.0;\n #if HAS_COLOR\n alpha *= f32(input.aColor.a);\n #endif\n #if HAS_COLOR0 && COLOR0_SIZE == 4\n alpha *= f32(input.aColor0.a);\n #endif\n fbo_picking_setData(input, &output, output.position.w, alpha != 0.0);\n #else\n #if HAS_MAP\n output.vTexCoord = transformTexcoord(input.aTexCoord.xy);\n #ifdef HAS_AO_MAP\n output.vTexCoord1 = transformTexcoord(input.aTexCoord1);\n #endif\n #ifdef HAS_I3S_UVREGION\n output.vUvRegion = input.uvRegion / 65535.0;\n #endif\n #endif\n #if HAS_TANGENT || HAS_NORMAL\n let positionNormalMatrix = mat3x3f(\n localPositionMatrix[0].xyz,\n localPositionMatrix[1].xyz,\n localPositionMatrix[2].xyz\n );\n let normalMatrix = uniforms.modelNormalMatrix * positionNormalMatrix;\n #if HAS_TANGENT\n let tangentFrame = toTangentFrameWithTangent(input.aTangent);\n Normal = tangentFrame.n;\n let t = tangentFrame.t;\n output.vModelTangent = vec4f(normalMatrix * t, input.aTangent.w);\n #else\n Normal = decode_getNormal(vec3f(input.aNormal.xyz));\n #endif\n let localNormal = Normal;\n output.vModelNormal = normalMatrix * localNormal;\n #else\n Normal = vec3f(0);\n output.vModelNormal = vec3f(0);\n #endif\n #if HAS_TANGENT\n output.vModelBiTangent = cross(output.vModelNormal, output.vModelTangent.xyz) * sign(input.aTangent.w);\n #endif\n #ifdef HAS_SSR\n let ssrNormalMatrix = uniforms.modelViewNormalMatrix * positionNormalMatrix;\n output.vViewNormal = ssrNormalMatrix * Normal;\n #if HAS_TANGENT\n let localTangent = vec4f(t, input.aTangent.w);\n output.vViewTangent = vec4f(ssrNormalMatrix * localTangent.xyz, localTangent.w);\n #endif\n #endif\n #if HAS_COLOR\n output.vColor = vec4f(input.aColor) / 255.0;\n #endif\n #ifdef HAS_OPACITY\n output.vOpacity = f32(input.aOpacity) / 255.0;\n #else\n output.vOpacity = 1.0;\n #endif\n #if HAS_HIGHLIGHT_OPACITY || HAS_HIGHLIGHT_COLOR\n highlight_setVarying(input, &output);\n #endif\n #if HAS_COLOR0\n #if COLOR0_SIZE == 3\n output.vColor0 = vec4f(vec3f(input.aColor0), 255.0) / 255.0;\n #else\n output.vColor0 = vec4f(input.aColor0) / 255.0;\n #endif\n #endif\n #if HAS_SHADOWING && !HAS_BLOOM\n shadow_computeShadowPars(position, &output);\n #endif\n #if HAS_BUMP_MAP && HAS_TANGENT\n let TBN = transposeMat3(mat3x3f(output.vModelTangent.xyz, output.vModelBiTangent, output.vModelNormal));\n output.vTangentViewPos = TBN * shaderUniforms.cameraPosition;\n output.vTangentFragPos = TBN * output.vModelVertex;\n #endif\n #ifdef HAS_VERTEX_COLOR\n vertexColor_update(input, &output);\n #endif\n #ifdef HAS_EXCAVATE_ANALYSIS\n output.vCoordinateTexcoord = getCoordinateTexcoord(position, uniforms.modelMatrix);\n output.vExcavateHeight = getWorldHeight(position, uniforms.modelMatrix);\n #endif\n #endif\n return output;\n}";
62
+ var glStandardVert = "#include <highlight_vert>\n#include <line_extrusion_vert>\n#include <get_output>\n#include <vsm_shadow_vert>\n#include <vertex_color_vert>\n#ifdef PICKING_MODE\n #include <fbo_picking_vert>\n#endif\n#include <excavate_vert>\n#include <common_pack_float>\nstruct VertexInput {\n #include <position_vert>\n #if HAS_MAP || HAS_TERRAIN_FLAT_MASK\n #ifdef HAS_DRACO_TEXCOORD || HAS_COMPRESSED_INT16_TEXCOORD_0\n @location($i) aTexCoord: vec2i,\n #else\n @location($i) aTexCoord: vec2f,\n #endif\n #endif\n #if HAS_MAP\n #ifdef HAS_I3S_UVREGION\n @location($i) uvRegion: vec4f,\n #endif\n #if HAS_AO_MAP\n @location($i) aTexCoord1: vec2f,\n #endif\n #endif\n #if HAS_COLOR\n @location($i) aColor: vec4u,\n #endif\n #ifdef HAS_OPACITY\n @location($i) aOpacity: u32,\n #endif\n #if HAS_COLOR0\n #if COLOR0_SIZE == 3\n @location($i) aColor0: vec3u,\n #else\n @location($i) aColor0: vec4u,\n #endif\n #endif\n #if HAS_TANGENT\n @location($i) aTangent: vec4f,\n #elif HAS_NORMAL\n #ifdef NORMAL_IS_INT\n @location($i) aNormal: vec4i,\n #elif NORMAL_IS_UINT\n @location($i) aNormal: vec4u,\n #else\n @location($i) aNormal: vec3f,\n #endif\n #endif\n}\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n #ifdef HAS_SSR\n @location($o) vViewNormal: vec3f,\n #ifdef HAS_TANGENT\n @location($o) vViewTangent: vec4f,\n #endif\n #endif\n @location($o) vModelNormal: vec3f,\n @location($o) vViewVertex: vec4f,\n #if HAS_TANGENT\n @location($o) vModelTangent: vec4f,\n @location($o) vModelBiTangent: vec3f,\n #endif\n @location($o) vModelVertex: vec3f,\n #if HAS_MAP\n @location($o) vTexCoord: vec2f,\n #ifdef HAS_AO_MAP\n @location($o) vTexCoord1: vec2f,\n #endif\n #ifdef HAS_I3S_UVREGION\n @location($o) vUvRegion: vec4f,\n #endif\n #endif\n #if HAS_COLOR\n @location($o) vColor: vec4f,\n #endif\n @location($o) vOpacity: f32,\n #if HAS_COLOR0\n @location($o) vColor0: vec4f,\n #endif\n #if HAS_BUMP_MAP && HAS_TANGENT\n @location($o) vTangentViewPos: vec3f,\n @location($o) vTangentFragPos: vec3f,\n #endif\n}\nstruct ShaderUniforms {\n cameraPosition: vec3f,\n projMatrix: mat4x4f,\n}\nstruct Uniforms {\n uvOrigin: vec2f,\n uvScale: vec2f,\n uvOffset: vec2f,\n uvRotation: f32,\n modelMatrix: mat4x4f,\n modelViewMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n modelNormalMatrix: mat3x3f,\n #ifdef HAS_SSR\n modelViewNormalMatrix: mat3x3f,\n #endif\n};\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\nvar<private> Vertex: vec3f;\nvar<private> Normal: vec3f;\nvar<private> Tangent: vec4f;\nconst mid = 0.5;\nfn toTangentFrame(q: vec4f) -> vec3f {\n return vec3f(0.0, 0.0, 1.0) +\n vec3f(2.0, -2.0, -2.0) * q.x * q.zwx +\n vec3f(2.0, 2.0, -2.0) * q.y * q.wzy;\n}\nstruct TangentFrame {\n n: vec3f,\n t: vec3f\n}\nfn toTangentFrameWithTangent(q: vec4f) -> TangentFrame {\n var out: TangentFrame;\n out.n = toTangentFrame(q);\n out.t = vec3f(1.0, 0.0, 0.0) +\n vec3f(-2.0, 2.0, -2.0) * q.y * q.yxw +\n vec3f(-2.0, 2.0, 2.0) * q.z * q.zwx;\n return out;\n}\nfn rotateUV(uv: vec2f, rotation: f32) -> vec2f {\n return vec2f(\n cos(rotation) * (uv.x - mid) + sin(rotation) * (uv.y - mid) + mid,\n cos(rotation) * (uv.y - mid) - sin(rotation) * (uv.x - mid) + mid\n );\n}\n#if HAS_MAP\nfn transformTexcoord(uv: vec2f) -> vec2f {\n let decodedTexCoord = decode_getTexcoord(uv);\n #ifdef HAS_RANDOM_TEX\n let origin = uniforms.uvOrigin;\n let texCoord = decodedTexCoord * uniforms.uvScale + uniforms.uvOffset;\n return (origin % 1.0) + texCoord;\n #else\n var origin = uniforms.uvOrigin;\n var texCoord = decodedTexCoord * uniforms.uvScale;\n if (uniforms.uvRotation != 0.0) {\n origin = rotateUV(origin, uniforms.uvRotation);\n texCoord = rotateUV(texCoord, uniforms.uvRotation);\n }\n return (origin % 1.0) + texCoord + uniforms.uvOffset;\n #endif\n}\n#endif\nfn transposeMat3(inMat: mat3x3f) -> mat3x3f {\n let i0 = inMat[0];\n let i1 = inMat[1];\n let i2 = inMat[2];\n return mat3x3f(\n vec3f(i0.x, i1.x, i2.x),\n vec3f(i0.y, i1.y, i2.y),\n vec3f(i0.z, i1.z, i2.z)\n );\n}\n@vertex\nfn main(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let localPositionMatrix = getPositionMatrix(input, &output, uniforms.positionMatrix);\n #ifdef IS_LINE_EXTRUSION\n let linePosition = getLineExtrudePosition(vec3f(input.aPosition.xyz), input);\n let localVertex = getPosition(linePosition, input);\n #else\n let localVertex = getPosition(vec3f(input.aPosition.xyz), input);\n #endif\n output.vModelVertex = (uniforms.modelMatrix * localVertex).xyz;\n let position = localPositionMatrix * localVertex;\n let viewVertex = uniforms.modelViewMatrix * position;\n output.vViewVertex = viewVertex;\n #ifdef HAS_MASK_EXTENT\n output.position = shaderUniforms.projMatrix * getMaskPosition(position, uniforms.modelMatrix);\n #else\n output.position = shaderUniforms.projMatrix * viewVertex;\n #endif\n #ifdef PICKING_MODE\n var alpha = 1.0;\n #if HAS_COLOR\n alpha *= f32(input.aColor.a);\n #endif\n #if HAS_COLOR0 && COLOR0_SIZE == 4\n alpha *= f32(input.aColor0.a);\n #endif\n fbo_picking_setData(input, &output, output.position.w, alpha != 0.0);\n #else\n #if HAS_MAP\n output.vTexCoord = transformTexcoord(vec2f(input.aTexCoord.xy));\n #ifdef HAS_AO_MAP\n output.vTexCoord1 = transformTexcoord(vec2f(input.aTexCoord1.xy));\n #endif\n #ifdef HAS_I3S_UVREGION\n output.vUvRegion = input.uvRegion / 65535.0;\n #endif\n #endif\n #if HAS_TANGENT || HAS_NORMAL\n let positionNormalMatrix = mat3x3f(\n localPositionMatrix[0].xyz,\n localPositionMatrix[1].xyz,\n localPositionMatrix[2].xyz\n );\n let normalMatrix = uniforms.modelNormalMatrix * positionNormalMatrix;\n #if HAS_TANGENT\n let tangentFrame = toTangentFrameWithTangent(input.aTangent);\n Normal = tangentFrame.n;\n let t = tangentFrame.t;\n output.vModelTangent = vec4f(normalMatrix * t, input.aTangent.w);\n #else\n Normal = decode_getNormal(vec3f(input.aNormal.xyz));\n #endif\n let localNormal = Normal;\n output.vModelNormal = normalMatrix * localNormal;\n #else\n Normal = vec3f(0);\n output.vModelNormal = vec3f(0);\n #endif\n #if HAS_TANGENT\n output.vModelBiTangent = cross(output.vModelNormal, output.vModelTangent.xyz) * sign(input.aTangent.w);\n #endif\n #ifdef HAS_SSR\n let ssrNormalMatrix = uniforms.modelViewNormalMatrix * positionNormalMatrix;\n output.vViewNormal = ssrNormalMatrix * Normal;\n #if HAS_TANGENT\n let localTangent = vec4f(t, input.aTangent.w);\n output.vViewTangent = vec4f(ssrNormalMatrix * localTangent.xyz, localTangent.w);\n #endif\n #endif\n #if HAS_COLOR\n output.vColor = vec4f(input.aColor) / 255.0;\n #endif\n #ifdef HAS_OPACITY\n output.vOpacity = f32(input.aOpacity) / 255.0;\n #else\n output.vOpacity = 1.0;\n #endif\n #if HAS_HIGHLIGHT_OPACITY || HAS_HIGHLIGHT_COLOR\n highlight_setVarying(input, &output);\n #endif\n #if HAS_COLOR0\n #if COLOR0_SIZE == 3\n output.vColor0 = vec4f(vec3f(input.aColor0), 255.0) / 255.0;\n #else\n output.vColor0 = vec4f(input.aColor0) / 255.0;\n #endif\n #endif\n #if HAS_SHADOWING && !HAS_BLOOM\n shadow_computeShadowPars(position, &output);\n #endif\n #if HAS_BUMP_MAP && HAS_TANGENT\n let TBN = transposeMat3(mat3x3f(output.vModelTangent.xyz, output.vModelBiTangent, output.vModelNormal));\n output.vTangentViewPos = TBN * shaderUniforms.cameraPosition;\n output.vTangentFragPos = TBN * output.vModelVertex;\n #endif\n #ifdef HAS_VERTEX_COLOR\n vertexColor_update(input, &output);\n #endif\n #ifdef HAS_EXCAVATE_ANALYSIS\n output.vCoordinateTexcoord = getCoordinateTexcoord(position, uniforms.modelMatrix);\n output.vExcavateHeight = getWorldHeight(position, uniforms.modelMatrix);\n #endif\n #endif\n return output;\n}";
63
63
 
64
- var glBloomCombineFrag = "\nstruct BloomCombineUniforms {\n bloomFactor: f32,\n bloomRadius: f32,\n rgbmRange: f32,\n enableAA: f32,\n outputSize: vec2f,\n};\n@group(0) @binding($b) var<uniform> uniforms: BloomCombineUniforms;\n@group(0) @binding($b) var TextureBloomBlur1: texture_2d<f32>;\n@group(0) @binding($b) var TextureBloomBlur1Sampler: sampler;\n@group(0) @binding($b) var TextureBloomBlur2: texture_2d<f32>;\n@group(0) @binding($b) var TextureBloomBlur2Sampler: sampler;\n@group(0) @binding($b) var TextureBloomBlur3: texture_2d<f32>;\n@group(0) @binding($b) var TextureBloomBlur3Sampler: sampler;\n@group(0) @binding($b) var TextureBloomBlur4: texture_2d<f32>;\n@group(0) @binding($b) var TextureBloomBlur4Sampler: sampler;\n@group(0) @binding($b) var TextureBloomBlur5: texture_2d<f32>;\n@group(0) @binding($b) var TextureBloomBlur5Sampler: sampler;\n#ifdef HAS_MULTISAMPLED\n@group(0) @binding($b) var TextureInput: texture_multisampled_2d<f32>;\n@group(0) @binding($b) var TextureSource: texture_multisampled_2d<f32>;\n#else\n@group(0) @binding($b) var TextureInput: texture_2d<f32>;\n@group(0) @binding($b) var TextureSource: texture_2d<f32>;\n#endif\n@group(0) @binding($b) var TextureInputSampler: sampler;\n@group(0) @binding($b) var TextureSourceSampler: sampler;\nvar<private> gTexCoord: vec2f;\n#include <srgb_frag>\nfn decodeRGBM(color: vec4f, range: f32) -> vec3f {\n if (range <= 0.0) {\n return color.rgb;\n }\n return range * color.rgb * color.a;\n}\nfn getRadiusFactored(value: f32, middle: f32) -> f32 {\n return mix(value, middle * 2.0 - value, uniforms.bloomRadius);\n}\nfn fetchSourceTexel(uv: vec2f) -> vec4f {\n#ifdef HAS_MULTISAMPLED\n return textureLoad(TextureSource, vec2i(uv * vec2f(uniforms.outputSize)), 0);\n#else\n return textureSample(TextureSource, TextureSourceSampler, uv);\n#endif\n}\nfn fetchInputTexel(uv: vec2f) -> vec4f {\n#ifdef HAS_MULTISAMPLED\n return textureLoad(TextureInput, vec2i(uv * vec2f(uniforms.outputSize)), 0);\n#else\n return textureSample(TextureInput, TextureInputSampler, uv);\n#endif\n}\nfn bloomCombine() -> vec4f {\n var bloom: vec3f = vec3f(0.0);\n let midVal: f32 = 0.6;\n let factor1: f32 = 1.1;\n let factor2: f32 = 0.9;\n let factor3: f32 = 0.6;\n let factor4: f32 = 0.3;\n let factor5: f32 = 0.1;\n bloom += (vec4f(decodeRGBM(textureSample(TextureBloomBlur1, TextureBloomBlur1Sampler, gTexCoord), uniforms.rgbmRange), 1.0)).rgb * getRadiusFactored(factor1, midVal);\n bloom += (vec4f(decodeRGBM(textureSample(TextureBloomBlur2, TextureBloomBlur2Sampler, gTexCoord), uniforms.rgbmRange), 1.0)).rgb * getRadiusFactored(factor2, midVal);\n bloom += (vec4f(decodeRGBM(textureSample(TextureBloomBlur3, TextureBloomBlur3Sampler, gTexCoord), uniforms.rgbmRange), 1.0)).rgb * getRadiusFactored(factor3, midVal);\n bloom += (vec4f(decodeRGBM(textureSample(TextureBloomBlur4, TextureBloomBlur4Sampler, gTexCoord), uniforms.rgbmRange), 1.0)).rgb * getRadiusFactored(factor4, midVal);\n bloom += (vec4f(decodeRGBM(textureSample(TextureBloomBlur5, TextureBloomBlur5Sampler, gTexCoord), uniforms.rgbmRange), 1.0)).rgb * getRadiusFactored(factor5, midVal);\n var bloomInputColor: vec4f;\n if (uniforms.enableAA == 1.0) {\n } else {\n bloomInputColor = fetchInputTexel(gTexCoord);\n }\n bloomInputColor = vec4f(mix(vec3f(0.0), bloomInputColor.rgb, sign(bloomInputColor.a)), bloomInputColor.a);\n let srcColor = fetchSourceTexel(gTexCoord);\n let bloomAlpha: f32 = sqrt((bloom.r + bloom.g + bloom.b) / 3.0);\n let bloomColor: vec4f = vec4f(linearTosRGB(bloom * uniforms.bloomFactor), bloomAlpha);\n return bloomInputColor + srcColor * (1.0 - bloomInputColor.a) + bloomColor;\n}\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n let fragCoord = vec2f(vertexOutput.position.xy);\n gTexCoord = fragCoord / uniforms.outputSize;\n let color = bloomCombine();\n return color;\n}";
64
+ var glBloomCombineFrag = "\nstruct BloomCombineUniforms {\n bloomFactor: f32,\n bloomRadius: f32,\n rgbmRange: f32,\n enableAA: f32,\n outputSize: vec2f,\n};\n@group(0) @binding($b) var<uniform> uniforms: BloomCombineUniforms;\n@group(0) @binding($b) var TextureBloomBlur1: texture_2d<f32>;\n@group(0) @binding($b) var TextureBloomBlur1Sampler: sampler;\n@group(0) @binding($b) var TextureBloomBlur2: texture_2d<f32>;\n@group(0) @binding($b) var TextureBloomBlur2Sampler: sampler;\n@group(0) @binding($b) var TextureBloomBlur3: texture_2d<f32>;\n@group(0) @binding($b) var TextureBloomBlur3Sampler: sampler;\n@group(0) @binding($b) var TextureBloomBlur4: texture_2d<f32>;\n@group(0) @binding($b) var TextureBloomBlur4Sampler: sampler;\n@group(0) @binding($b) var TextureBloomBlur5: texture_2d<f32>;\n@group(0) @binding($b) var TextureBloomBlur5Sampler: sampler;\n@group(0) @binding($b) var TextureInput: texture_2d<f32>;\n@group(0) @binding($b) var TextureSource: texture_2d<f32>;\n@group(0) @binding($b) var TextureInputSampler: sampler;\n@group(0) @binding($b) var TextureSourceSampler: sampler;\nvar<private> gTexCoord: vec2f;\n#include <srgb_frag>\nfn decodeRGBM(color: vec4f, range: f32) -> vec3f {\n if (range <= 0.0) {\n return color.rgb;\n }\n return range * color.rgb * color.a;\n}\nfn getRadiusFactored(value: f32, middle: f32) -> f32 {\n return mix(value, middle * 2.0 - value, uniforms.bloomRadius);\n}\nfn fetchSourceTexel(uv: vec2f) -> vec4f {\n return textureSample(TextureSource, TextureSourceSampler, uv);\n}\nfn fetchInputTexel(uv: vec2f) -> vec4f {\n return textureSample(TextureInput, TextureInputSampler, uv);\n}\nfn bloomCombine() -> vec4f {\n var bloom: vec3f = vec3f(0.0);\n let midVal: f32 = 0.6;\n let factor1: f32 = 1.1;\n let factor2: f32 = 0.9;\n let factor3: f32 = 0.6;\n let factor4: f32 = 0.3;\n let factor5: f32 = 0.1;\n bloom += (vec4f(decodeRGBM(textureSample(TextureBloomBlur1, TextureBloomBlur1Sampler, gTexCoord), uniforms.rgbmRange), 1.0)).rgb * getRadiusFactored(factor1, midVal);\n bloom += (vec4f(decodeRGBM(textureSample(TextureBloomBlur2, TextureBloomBlur2Sampler, gTexCoord), uniforms.rgbmRange), 1.0)).rgb * getRadiusFactored(factor2, midVal);\n bloom += (vec4f(decodeRGBM(textureSample(TextureBloomBlur3, TextureBloomBlur3Sampler, gTexCoord), uniforms.rgbmRange), 1.0)).rgb * getRadiusFactored(factor3, midVal);\n bloom += (vec4f(decodeRGBM(textureSample(TextureBloomBlur4, TextureBloomBlur4Sampler, gTexCoord), uniforms.rgbmRange), 1.0)).rgb * getRadiusFactored(factor4, midVal);\n bloom += (vec4f(decodeRGBM(textureSample(TextureBloomBlur5, TextureBloomBlur5Sampler, gTexCoord), uniforms.rgbmRange), 1.0)).rgb * getRadiusFactored(factor5, midVal);\n var bloomInputColor: vec4f;\n if (uniforms.enableAA == 1.0) {\n } else {\n bloomInputColor = fetchInputTexel(gTexCoord);\n }\n bloomInputColor = vec4f(mix(vec3f(0.0), bloomInputColor.rgb, sign(bloomInputColor.a)), bloomInputColor.a);\n let srcColor = fetchSourceTexel(gTexCoord);\n let bloomAlpha: f32 = sqrt((bloom.r + bloom.g + bloom.b) / 3.0);\n let bloomColor: vec4f = vec4f(linearTosRGB(bloom * uniforms.bloomFactor), bloomAlpha);\n return bloomInputColor + srcColor * (1.0 - bloomInputColor.a) + bloomColor;\n}\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n let fragCoord = vec2f(vertexOutput.position.xy);\n gTexCoord = fragCoord / uniforms.outputSize;\n let color = bloomCombine();\n return color;\n}";
65
65
 
66
- var glBlur0Frag = "struct GaussianBlur0Uniforms {\n rgbmRange: f32,\n blurDir: vec2f,\n pixelRatio: vec2f,\n outputSize: vec2f,\n outSize: vec2f,\n inputRGBM: f32,\n luminThreshold: f32,\n};\n@group(0) @binding($b) var<uniform> uniforms: GaussianBlur0Uniforms;\n#ifdef HAS_MULTISAMPLED\n@binding($b) @group(0) var TextureBlurInput: texture_multisampled_2d<f32>;\n#else\n@binding($b) @group(0) var TextureBlurInput: texture_2d<f32>;\n#endif\n@group(0) @binding($b) var TextureBlurInputSampler: sampler;\nconst colorBright = vec3f(0.2126, 0.7152, 0.0722);\nfn getLuminance(color: vec3f) -> f32 {\n return dot(color, colorBright);\n}\nfn extractBright(color: vec4f) -> vec4f {\n let f = max(sign(getLuminance(color.rgb) - uniforms.luminThreshold), 0.0);\n return color * f;\n}\nfn encodeRGBM(color: vec3f, range: f32) -> vec4f {\n var rgbm: vec4f;\n let col = color / range;\n rgbm.a = clamp(max(max(col.r, col.g), max(col.b, 1e-6)), 0.0, 1.0);\n rgbm.a = ceil(rgbm.a * 255.0) / 255.0;\n rgbm = vec4f(col / rgbm.a, rgbm.a);\n return rgbm;\n}\nfn decodeRGBM(color: vec4f, range: f32) -> vec3f {\n if uniforms.inputRGBM == 0.0 {\n return color.rgb;\n }\n return range * color.rgb * color.a;\n}\nfn fetchSourceTexel(uv: vec2f) -> vec4f {\n#ifdef HAS_MULTISAMPLED\n return textureLoad(TextureBlurInput, vec2i(uv * vec2f(uniforms.outSize)), 0);\n#else\n return textureSample(TextureBlurInput, TextureBlurInputSampler, uv);\n#endif\n}\nfn gaussianBlur(gTexCoord: vec2f) -> vec4f {\n var pixel = 0.375 * extractBright(vec4f(decodeRGBM(fetchSourceTexel(gTexCoord), uniforms.rgbmRange), 1.0)).rgb;\n let blurDirection = uniforms.pixelRatio.xy * uniforms.blurDir.xy / uniforms.outputSize.xy;\n let offset = blurDirection * 1.2;\n pixel += 0.3125 * extractBright(vec4f(decodeRGBM(fetchSourceTexel(gTexCoord + offset), uniforms.rgbmRange), 1.0)).rgb;\n pixel += 0.3125 * extractBright(vec4f(decodeRGBM(fetchSourceTexel(gTexCoord - offset), uniforms.rgbmRange), 1.0)).rgb;\n return vec4f(pixel, 1.0);\n}\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n let gTexCoord = vertexOutput.position.xy / uniforms.outputSize.xy;\n var color = gaussianBlur(gTexCoord);\n color = encodeRGBM(color.rgb, uniforms.rgbmRange);\n return color;\n}";
66
+ var glBlur0Frag = "struct GaussianBlur0Uniforms {\n rgbmRange: f32,\n blurDir: vec2f,\n pixelRatio: vec2f,\n outputSize: vec2f,\n outSize: vec2f,\n inputRGBM: f32,\n luminThreshold: f32,\n};\n@group(0) @binding($b) var<uniform> uniforms: GaussianBlur0Uniforms;\n@binding($b) @group(0) var TextureBlurInput: texture_2d<f32>;\n@group(0) @binding($b) var TextureBlurInputSampler: sampler;\nconst colorBright = vec3f(0.2126, 0.7152, 0.0722);\nfn getLuminance(color: vec3f) -> f32 {\n return dot(color, colorBright);\n}\nfn extractBright(color: vec4f) -> vec4f {\n let f = max(sign(getLuminance(color.rgb) - uniforms.luminThreshold), 0.0);\n return color * f;\n}\nfn encodeRGBM(color: vec3f, range: f32) -> vec4f {\n var rgbm: vec4f;\n let col = color / range;\n rgbm.a = clamp(max(max(col.r, col.g), max(col.b, 1e-6)), 0.0, 1.0);\n rgbm.a = ceil(rgbm.a * 255.0) / 255.0;\n rgbm = vec4f(col / rgbm.a, rgbm.a);\n return rgbm;\n}\nfn decodeRGBM(color: vec4f, range: f32) -> vec3f {\n if uniforms.inputRGBM == 0.0 {\n return color.rgb;\n }\n return range * color.rgb * color.a;\n}\nfn fetchSourceTexel(uv: vec2f) -> vec4f {\n return textureSample(TextureBlurInput, TextureBlurInputSampler, uv);\n}\nfn gaussianBlur(gTexCoord: vec2f) -> vec4f {\n var pixel = 0.375 * extractBright(vec4f(decodeRGBM(fetchSourceTexel(gTexCoord), uniforms.rgbmRange), 1.0)).rgb;\n let blurDirection = uniforms.pixelRatio.xy * uniforms.blurDir.xy / uniforms.outputSize.xy;\n let offset = blurDirection * 1.2;\n pixel += 0.3125 * extractBright(vec4f(decodeRGBM(fetchSourceTexel(gTexCoord + offset), uniforms.rgbmRange), 1.0)).rgb;\n pixel += 0.3125 * extractBright(vec4f(decodeRGBM(fetchSourceTexel(gTexCoord - offset), uniforms.rgbmRange), 1.0)).rgb;\n return vec4f(pixel, 1.0);\n}\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n let gTexCoord = vertexOutput.position.xy / uniforms.outputSize.xy;\n var color = gaussianBlur(gTexCoord);\n color = encodeRGBM(color.rgb, uniforms.rgbmRange);\n return color;\n}";
67
67
 
68
68
  var glBlur1Frag = "struct GaussianBlurUniforms {\n rgbmRange: f32,\n blurDir: vec2f,\n pixelRatio: vec2f,\n outputSize: vec2f,\n};\n@group(0) @binding($b) var<uniform> uniforms: GaussianBlurUniforms;\n@group(0) @binding($b) var TextureBlurInput: texture_2d<f32>;\n@group(0) @binding($b) var TextureBlurInputSampler: sampler;\n#include <rgbm_frag>\nfn gaussianBlur(gTexCoord: vec2f) -> vec4f {\n var pixel = 0.3125 * vec4f(decodeRGBM(textureSample(TextureBlurInput, TextureBlurInputSampler, gTexCoord), uniforms.rgbmRange), 1.0).rgb;\n let blurDirection = uniforms.pixelRatio.xy * uniforms.blurDir.xy / uniforms.outputSize.xy;\n let offset = blurDirection * 1.2857142857142858;\n pixel += 0.328125 * vec4f(decodeRGBM(textureSample(TextureBlurInput, TextureBlurInputSampler, gTexCoord + offset), uniforms.rgbmRange), 1.0).rgb;\n pixel += 0.328125 * vec4f(decodeRGBM(textureSample(TextureBlurInput, TextureBlurInputSampler, gTexCoord - offset), uniforms.rgbmRange), 1.0).rgb;\n return vec4f(pixel, 1.0);\n}\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n let gTexCoord = vertexOutput.position.xy / uniforms.outputSize.xy;\n var color = gaussianBlur(gTexCoord);\n color = encodeRGBM(color.rgb, uniforms.rgbmRange);\n return color;\n}";
69
69
 
@@ -77,13 +77,13 @@ var glBlur5Frag = "#include <rgbm_frag>\nstruct GaussianBlurUniforms {\n rgbm
77
77
 
78
78
  var glBlur6Frag = "#include <rgbm_frag>\nstruct GaussianBlurUniforms {\n rgbmRange: f32,\n blurDir: vec2f,\n outSize: vec2f,\n pixelRatio: vec2f,\n outputSize: vec2f,\n};\n@group(0) @binding($b) var<uniform> uniforms: GaussianBlurUniforms;\n@group(0) @binding($b) var TextureBlurInput: texture_2d<f32>;\n@group(0) @binding($b) var TextureBlurInputSampler: sampler;\nfn gaussianBlur(gTexCoord: vec2f) -> vec4f {\n var pixel = 0.196380615234375 * vec4f(decodeRGBM(textureSample(TextureBlurInput, TextureBlurInputSampler, gTexCoord), uniforms.rgbmRange), 1.0).rgb;\n var blurDirection = uniforms.pixelRatio.xy * uniforms.blurDir.xy / uniforms.outputSize.xy;\n blurDirection = blurDirection * uniforms.outSize.y * 0.00075;\n var offset = blurDirection * 1.411764705882353;\n pixel += 0.2967529296875 * vec4f(decodeRGBM(textureSample(TextureBlurInput, TextureBlurInputSampler, gTexCoord + offset), uniforms.rgbmRange), 1.0).rgb;\n pixel += 0.2967529296875 * vec4f(decodeRGBM(textureSample(TextureBlurInput, TextureBlurInputSampler, gTexCoord - offset), uniforms.rgbmRange), 1.0).rgb;\n offset = blurDirection * 3.2941176470588234;\n pixel += 0.09442138671875 * vec4f(decodeRGBM(textureSample(TextureBlurInput, TextureBlurInputSampler, gTexCoord + offset), uniforms.rgbmRange), 1.0).rgb;\n pixel += 0.09442138671875 * vec4f(decodeRGBM(textureSample(TextureBlurInput, TextureBlurInputSampler, gTexCoord - offset), uniforms.rgbmRange), 1.0).rgb;\n offset = blurDirection * 5.176470588235294;\n pixel += 0.0103759765625 * vec4f(decodeRGBM(textureSample(TextureBlurInput, TextureBlurInputSampler, gTexCoord + offset), uniforms.rgbmRange), 1.0).rgb;\n pixel += 0.0103759765625 * vec4f(decodeRGBM(textureSample(TextureBlurInput, TextureBlurInputSampler, gTexCoord - offset), uniforms.rgbmRange), 1.0).rgb;\n return vec4f(pixel, 1.0);\n}\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n let gTexCoord = vertexOutput.position.xy / uniforms.outputSize.xy;\n var color = gaussianBlur(gTexCoord);\n color = encodeRGBM(color.rgb, uniforms.rgbmRange);\n return color;\n}";
79
79
 
80
- var glBoxShadowBlurFrag = "#include <common_pack_float>\nstruct Uniforms {\n resolution: vec2f\n};\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\n#ifdef HAS_MULTISAMPLED\n@binding($b) @group(0) var textureSource: texture_multisampled_2d<f32>;\n#else\n@binding($b) @group(0) var textureSource: texture_2d<f32>;\n#endif\n@group(0) @binding($b) var textureSourceSampler: sampler;\nfn sign_positive(x: f32) -> f32 {\n return select(0.0, 1.0, x > 0.0);\n}\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n var c: f32 = 0.0;\n var weight: f32 = 0.0;\n let offset = BOXBLUR_OFFSET;\n for (var x: i32 = -offset; x <= offset; x++) {\n for (var y: i32 = -offset; y <= offset; y++) {\n var uv: vec2f = vertexOutput.vTexCoord + vec2f(f32(x) / uniforms.resolution.x, f32(y) / uniforms.resolution.y);\n uv = clamp(uv, vec2f(0.0), vec2f(1.0));\n #ifdef HAS_MULTISAMPLED\n let texColor = textureLoad(textureSource, vec2i(uv * vec2f(uniforms.resolution)), 0);\n #else\n let texColor = textureSample(textureSource, textureSourceSampler, uv);\n #endif\n let depth = common_decodeDepth(texColor);\n let s = max(0.0, sign_positive(1.0 - depth));\n weight += sign(depth) * s;\n c += depth;\n }\n }\n let avgDepth: f32 = c / max(1.0, weight);\n let encodedDepth = common_encodeDepth(avgDepth);\n return encodedDepth;\n}";
80
+ var glBoxShadowBlurFrag = "#include <common_pack_float>\nstruct Uniforms {\n resolution: vec2f\n};\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\n#ifdef HAS_MULTISAMPLED\n@binding($b) @group(0) var depthTextureSource: texture_multisampled_2d<f32>;\n#else\n@binding($b) @group(0) var depthTextureSource: texture_2d<f32>;\n#endif\n@group(0) @binding($b) var depthTextureSourceSampler: sampler;\nfn sign_positive(x: f32) -> f32 {\n return select(0.0, 1.0, x > 0.0);\n}\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n var c: f32 = 0.0;\n var weight: f32 = 0.0;\n let offset = BOXBLUR_OFFSET;\n for (var x: i32 = -offset; x <= offset; x++) {\n for (var y: i32 = -offset; y <= offset; y++) {\n var uv: vec2f = vertexOutput.vTexCoord + vec2f(f32(x) / uniforms.resolution.x, f32(y) / uniforms.resolution.y);\n uv = clamp(uv, vec2f(0.0), vec2f(1.0));\n #ifdef HAS_MULTISAMPLED\n let texColor = textureLoad(depthTextureSource, vec2i(uv * vec2f(uniforms.resolution)), 0);\n #else\n let texColor = textureSample(depthTextureSource, depthTextureSourceSampler, uv);\n #endif\n let depth = common_decodeDepth(texColor);\n let s = max(0.0, sign_positive(1.0 - depth));\n weight += sign(depth) * s;\n c += depth;\n }\n }\n let avgDepth: f32 = c / max(1.0, weight);\n let encodedDepth = common_encodeDepth(avgDepth);\n return encodedDepth;\n}";
81
81
 
82
82
  var glCopyDepthFrag = "#define SHADER_NAME COPY_DEPTH\n#include <common_pack_float>\nstruct CopyDepthUniforms {\n textureSize: vec2f,\n};\n@group(0) @binding($b) var<uniform> uniforms: CopyDepthUniforms;\n#ifdef HAS_MULTISAMPLED\n @group(0) @binding($b) var TextureDepth: texture_depth_multisampled_2d;\n#else\n @group(0) @binding($b) var TextureDepth: texture_depth_2d;\n#endif\n@group(0) @binding($b) var TextureDepthSampler: sampler;\n@fragment\nfn main(\n vertexOutput: VertexOutput\n) -> @location(0) vec4f {\n let uv = vertexOutput.vTexCoord;\n #ifdef HAS_MULTISAMPLED\n let depth = textureLoad(TextureDepth, vec2i(uv * uniforms.textureSize), 0);\n #else\n let depth = textureSample(TextureDepth, TextureDepthSampler, uv);\n #endif\n var fragColor = common_encodeDepth(depth);\n return fragColor;\n}";
83
83
 
84
- var glCopyFrag = "struct SharpenUniforms {\n size: vec2f,\n enableSharpen: f32,\n sharpFactor: f32,\n pixelRatio: f32,\n};\n@group(0) @binding($b) var<uniform> uniforms: SharpenUniforms;\n#ifdef HAS_MULTISAMPLED\n@binding($b) @group(0) var texture: texture_multisampled_2d<f32>;\n#else\n@binding($b) @group(0) var texture: texture_2d<f32>;\n#endif\n@group(0) @binding($b) var textureSampler: sampler;\nvar<private> gTexCoord: vec2f;\nfn fetchSourceTexel(uv: vec2f) -> vec4f {\n#ifdef HAS_MULTISAMPLED\n return textureLoad(texture, vec2i(uv * vec2f(uniforms.size)), 0);\n#else\n return textureSample(texture, textureSampler, uv);\n#endif\n}\nfn sharpColorFactor(color: vec3f, sharp: f32) -> vec3f {\n let off = uniforms.pixelRatio / uniforms.size;\n var count: f32 = 0.0;\n var rgbNW = fetchSourceTexel(gTexCoord + off * vec2f(-1.0, -1.0));\n rgbNW = vec4f(select(vec3f(0.0), rgbNW.rgb, rgbNW.a > 0.0), rgbNW.a);\n count += select(0.0, 1.0, rgbNW.a > 0.0);\n var rgbSE = fetchSourceTexel(gTexCoord + off * vec2f(1.0, 1.0));\n rgbSE = vec4f(select(vec3f(0.0), rgbSE.rgb, rgbSE.a > 0.0), rgbSE.a);\n count += select(0.0, 1.0, rgbSE.a > 0.0);\n var rgbNE = fetchSourceTexel(gTexCoord + off * vec2f(1.0, -1.0));\n rgbNE = vec4f(select(vec3f(0.0), rgbNE.rgb, rgbNE.a > 0.0), rgbNE.a);\n count += select(0.0, 1.0, rgbNE.a > 0.0);\n var rgbSW = fetchSourceTexel(gTexCoord + off * vec2f(-1.0, 1.0));\n rgbSW = vec4f(select(vec3f(0.0), rgbSW.rgb, rgbSW.a > 0.0), rgbSW.a);\n count += select(0.0, 1.0, rgbSW.a > 0.0);\n return color + sharp * (count * color - rgbNW.rgb - rgbNE.rgb - rgbSW.rgb - rgbSE.rgb);\n}\n@fragment\nfn main(\n input : VertexOutput,\n) -> @location(0) vec4f {\n gTexCoord = input.position.xy / uniforms.size;\n var color = fetchSourceTexel(gTexCoord);\n if (uniforms.enableSharpen == 1.0) {\n color = vec4f(sharpColorFactor(color.rgb, uniforms.sharpFactor), color.a);\n }\n return color;\n}";
84
+ var glCopyFrag = "struct SharpenUniforms {\n size: vec2f,\n enableSharpen: f32,\n sharpFactor: f32,\n pixelRatio: f32,\n};\n@group(0) @binding($b) var<uniform> uniforms: SharpenUniforms;\n@binding($b) @group(0) var texture: texture_2d<f32>;\n@group(0) @binding($b) var textureSampler: sampler;\nvar<private> gTexCoord: vec2f;\nfn fetchSourceTexel(uv: vec2f) -> vec4f {\n return textureSample(texture, textureSampler, uv);\n}\nfn sharpColorFactor(color: vec3f, sharp: f32) -> vec3f {\n let off = uniforms.pixelRatio / uniforms.size;\n var count: f32 = 0.0;\n var rgbNW = fetchSourceTexel(gTexCoord + off * vec2f(-1.0, -1.0));\n rgbNW = vec4f(select(vec3f(0.0), rgbNW.rgb, rgbNW.a > 0.0), rgbNW.a);\n count += select(0.0, 1.0, rgbNW.a > 0.0);\n var rgbSE = fetchSourceTexel(gTexCoord + off * vec2f(1.0, 1.0));\n rgbSE = vec4f(select(vec3f(0.0), rgbSE.rgb, rgbSE.a > 0.0), rgbSE.a);\n count += select(0.0, 1.0, rgbSE.a > 0.0);\n var rgbNE = fetchSourceTexel(gTexCoord + off * vec2f(1.0, -1.0));\n rgbNE = vec4f(select(vec3f(0.0), rgbNE.rgb, rgbNE.a > 0.0), rgbNE.a);\n count += select(0.0, 1.0, rgbNE.a > 0.0);\n var rgbSW = fetchSourceTexel(gTexCoord + off * vec2f(-1.0, 1.0));\n rgbSW = vec4f(select(vec3f(0.0), rgbSW.rgb, rgbSW.a > 0.0), rgbSW.a);\n count += select(0.0, 1.0, rgbSW.a > 0.0);\n return color + sharp * (count * color - rgbNW.rgb - rgbNE.rgb - rgbSW.rgb - rgbSE.rgb);\n}\n@fragment\nfn main(\n input : VertexOutput,\n) -> @location(0) vec4f {\n gTexCoord = input.position.xy / uniforms.size;\n var color = fetchSourceTexel(gTexCoord);\n if (uniforms.enableSharpen == 1.0) {\n color = vec4f(sharpColorFactor(color.rgb, uniforms.sharpFactor), color.a);\n }\n return color;\n}";
85
85
 
86
- var glFxaaFrag = "struct FxaaUniforms {\n enableFXAA: f32,\n enableToneMapping: f32,\n enableSharpen: f32,\n resolution: vec2f,\n pixelRatio: f32,\n sharpFactor: f32,\n #ifdef HAS_OUTLINE_TEX\n highlightFactor: f32,\n outlineFactor: f32,\n outlineWidth: f32,\n outlineColor: vec3f,\n #endif\n};\n@binding($b) @group(0) var<uniform> uniforms: FxaaUniforms;\n#ifdef HAS_MULTISAMPLED\n@binding($b) @group(0) var textureSource: texture_multisampled_2d<f32>;\n#else\n@binding($b) @group(0) var textureSource: texture_2d<f32>;\n#endif\n@binding($b) @group(0) var textureSourceSampler: sampler;\n#ifdef HAS_OUTLINE_TEX\n#ifdef HAS_MULTISAMPLED\n@binding($b) @group(0) var textureOutline: texture_multisampled_2d<f32>;\n#else\n@binding($b) @group(0) var textureOutline: texture_2d<f32>;\n#endif\n@binding($b) @group(0) var textureOutlineSampler: sampler;\n#endif\nvar<private> gTexCoord: vec2f;\nfn fetchSourceTexel(uv: vec2f) -> vec4f {\n let flipUV = vec2f(uv.x, 1.0 - uv.y);\n#ifdef HAS_MULTISAMPLED\n return textureLoad(textureSource, vec2i(flipUV * vec2f(uniforms.resolution)), 0);\n#else\n return textureSample(textureSource, textureSourceSampler, flipUV);\n#endif\n}\n#ifdef HAS_OUTLINE_TEX\n fn fetchOutlineTexel(uv: vec2f) -> vec4f {\n let flipUV = vec2f(uv.x, 1.0 - uv.y);\n #ifdef HAS_MULTISAMPLED\n return textureLoad(textureOutline, vec2i(flipUV * vec2f(uniforms.resolution)), 0);\n #else\n return textureSample(textureOutline, textureOutlineSampler, flipUV);\n #endif\n }\n#endif\nfn readFXAATexture(uv: vec2f) -> vec4f {\n return fetchSourceTexel(uv);\n}\nfn sharpColorFactor(color: vec3f, sharp: f32) -> vec3f {\n let off = uniforms.pixelRatio / uniforms.resolution;\n var count: f32 = 0.0;\n let rgbNW = fetchSourceTexel(gTexCoord + off * vec2f(-1.0, -1.0));\n let rgbNW_rgb = select(vec3f(0.0), rgbNW.rgb, rgbNW.a > 0.0);\n count += select(0.0, 1.0, rgbNW.a > 0.0);\n let rgbSE = fetchSourceTexel(gTexCoord + off * vec2f(1.0, 1.0));\n let rgbSE_rgb = select(vec3f(0.0), rgbSE.rgb, rgbSE.a > 0.0);\n count += select(0.0, 1.0, rgbSE.a > 0.0);\n let rgbNE = fetchSourceTexel(gTexCoord + off * vec2f(1.0, -1.0));\n let rgbNE_rgb = select(vec3f(0.0), rgbNE.rgb, rgbNE.a > 0.0);\n count += select(0.0, 1.0, rgbNE.a > 0.0);\n let rgbSW = fetchSourceTexel(gTexCoord + off * vec2f(-1.0, 1.0));\n let rgbSW_rgb = select(vec3f(0.0), rgbSW.rgb, rgbSW.a > 0.0);\n count += select(0.0, 1.0, rgbSW.a > 0.0);\n return color + sharp * (count * color - rgbNW_rgb - rgbNE_rgb - rgbSW_rgb - rgbSE_rgb);\n}\nfn sharpen(color: vec4f) -> vec4f {\n return vec4f(sharpColorFactor(color.rgb, uniforms.sharpFactor), color.a);\n}\nfn HDR_ACES(x: vec3f) -> vec3f {\n let a: f32 = 2.51;\n let b: f32 = 0.03;\n let c: f32 = 2.43;\n let d: f32 = 0.59;\n let e: f32 = 0.14;\n return (x * (a * x + b)) / (x * (c * x + d) + e);\n}\nfn tonemap(color: vec3f) -> vec3f {\n var result = color / (color + vec3f(1.0));\n result = pow(result, vec3f(1.0 / 2.2));\n return result;\n}\n#ifdef HAS_OUTLINE_TEX\nfn outline() -> vec4f {\n let offsetx = uniforms.pixelRatio / uniforms.resolution.x * uniforms.outlineWidth;\n let offsety = uniforms.pixelRatio / uniforms.resolution.y * uniforms.outlineWidth;\n let fac0: f32 = 2.0;\n let fac1: f32 = 1.0;\n let texel0 = fetchOutlineTexel(gTexCoord + vec2f(offsetx, offsety));\n let texel1 = fetchOutlineTexel(gTexCoord + vec2f(offsetx, 0.0));\n let texel2 = fetchOutlineTexel(gTexCoord + vec2f(offsetx, -offsety));\n let texel3 = fetchOutlineTexel(gTexCoord + vec2f(0.0, -offsety));\n let texel4 = fetchOutlineTexel(gTexCoord + vec2f(-offsetx, -offsety));\n let texel5 = fetchOutlineTexel(gTexCoord + vec2f(-offsetx, 0.0));\n let texel6 = fetchOutlineTexel(gTexCoord + vec2f(-offsetx, offsety));\n let texel7 = fetchOutlineTexel(gTexCoord + vec2f(0.0, offsety));\n let rowx = -fac0 * texel5 + fac0 * texel1 + -fac1 * texel6 + fac1 * texel0 + -fac1 * texel4 + fac1 * texel2;\n let rowy = -fac0 * texel3 + fac0 * texel7 + -fac1 * texel4 + fac1 * texel6 + -fac1 * texel2 + fac1 * texel0;\n let magSqr = sqrt(dot(rowy, rowy) + dot(rowx, rowx));\n let infMag = magSqr < 1.0 / 65025.0;\n let texelCenter = fetchOutlineTexel(gTexCoord).r * uniforms.outlineColor;\n if (all(texelCenter == vec3f(0.0)) || (uniforms.highlightFactor == 0.0 && infMag)) {\n return vec4f(0.0);\n }\n let finalFactor = select(min(1.0, sqrt(magSqr) * uniforms.outlineFactor), uniforms.highlightFactor, infMag);\n return finalFactor * vec4f(texelCenter, 1.0);\n}\nfn composeOutline(color: vec4f) -> vec4f {\n let outlineColor = outline();\n return outlineColor + color * (1.0 - outlineColor.a);\n}\n#endif\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n gTexCoord = vertexOutput.vTexCoord;\n var color: vec4f;\n if (uniforms.enableFXAA == 1.0) {\n color = readFXAATexture(vertexOutput.vTexCoord);\n } else {\n color = readFXAATexture(vertexOutput.vTexCoord);\n }\n if (uniforms.enableSharpen == 1.0) {\n color = sharpen(color);\n }\n if (uniforms.enableToneMapping == 1.0) {\n color = vec4(tonemap(color.rgb), color.a);\n }\n #ifdef HAS_OUTLINE_TEX\n color = composeOutline(color);\n #endif\n return color;\n}";
86
+ var glFxaaFrag = "struct FxaaUniforms {\n enableFXAA: f32,\n enableToneMapping: f32,\n enableSharpen: f32,\n resolution: vec2f,\n pixelRatio: f32,\n sharpFactor: f32,\n #ifdef HAS_OUTLINE_TEX\n highlightFactor: f32,\n outlineFactor: f32,\n outlineWidth: f32,\n outlineColor: vec3f,\n #endif\n};\n@binding($b) @group(0) var<uniform> uniforms: FxaaUniforms;\n@binding($b) @group(0) var textureSource: texture_2d<f32>;\n@binding($b) @group(0) var textureSourceSampler: sampler;\n#ifdef HAS_OUTLINE_TEX\n@binding($b) @group(0) var textureOutline: texture_2d<f32>;\n@binding($b) @group(0) var textureOutlineSampler: sampler;\n#endif\nvar<private> gTexCoord: vec2f;\nfn fetchSourceTexel(uv: vec2f) -> vec4f {\n let flipUV = vec2f(uv.x, 1.0 - uv.y);\n return textureSample(textureSource, textureSourceSampler, flipUV);\n}\n#ifdef HAS_OUTLINE_TEX\n fn fetchOutlineTexel(uv: vec2f) -> vec4f {\n let flipUV = vec2f(uv.x, 1.0 - uv.y);\n return textureSample(textureOutline, textureOutlineSampler, flipUV);\n }\n#endif\nfn readFXAATexture(uv: vec2f) -> vec4f {\n return fetchSourceTexel(uv);\n}\nfn sharpColorFactor(color: vec3f, sharp: f32) -> vec3f {\n let off = uniforms.pixelRatio / uniforms.resolution;\n var count: f32 = 0.0;\n let rgbNW = fetchSourceTexel(gTexCoord + off * vec2f(-1.0, -1.0));\n let rgbNW_rgb = select(vec3f(0.0), rgbNW.rgb, rgbNW.a > 0.0);\n count += select(0.0, 1.0, rgbNW.a > 0.0);\n let rgbSE = fetchSourceTexel(gTexCoord + off * vec2f(1.0, 1.0));\n let rgbSE_rgb = select(vec3f(0.0), rgbSE.rgb, rgbSE.a > 0.0);\n count += select(0.0, 1.0, rgbSE.a > 0.0);\n let rgbNE = fetchSourceTexel(gTexCoord + off * vec2f(1.0, -1.0));\n let rgbNE_rgb = select(vec3f(0.0), rgbNE.rgb, rgbNE.a > 0.0);\n count += select(0.0, 1.0, rgbNE.a > 0.0);\n let rgbSW = fetchSourceTexel(gTexCoord + off * vec2f(-1.0, 1.0));\n let rgbSW_rgb = select(vec3f(0.0), rgbSW.rgb, rgbSW.a > 0.0);\n count += select(0.0, 1.0, rgbSW.a > 0.0);\n return color + sharp * (count * color - rgbNW_rgb - rgbNE_rgb - rgbSW_rgb - rgbSE_rgb);\n}\nfn sharpen(color: vec4f) -> vec4f {\n return vec4f(sharpColorFactor(color.rgb, uniforms.sharpFactor), color.a);\n}\nfn HDR_ACES(x: vec3f) -> vec3f {\n let a: f32 = 2.51;\n let b: f32 = 0.03;\n let c: f32 = 2.43;\n let d: f32 = 0.59;\n let e: f32 = 0.14;\n return (x * (a * x + b)) / (x * (c * x + d) + e);\n}\nfn tonemap(color: vec3f) -> vec3f {\n var result = color / (color + vec3f(1.0));\n result = pow(result, vec3f(1.0 / 2.2));\n return result;\n}\n#ifdef HAS_OUTLINE_TEX\nfn outline() -> vec4f {\n let offsetx = uniforms.pixelRatio / uniforms.resolution.x * uniforms.outlineWidth;\n let offsety = uniforms.pixelRatio / uniforms.resolution.y * uniforms.outlineWidth;\n let fac0: f32 = 2.0;\n let fac1: f32 = 1.0;\n let texel0 = fetchOutlineTexel(gTexCoord + vec2f(offsetx, offsety));\n let texel1 = fetchOutlineTexel(gTexCoord + vec2f(offsetx, 0.0));\n let texel2 = fetchOutlineTexel(gTexCoord + vec2f(offsetx, -offsety));\n let texel3 = fetchOutlineTexel(gTexCoord + vec2f(0.0, -offsety));\n let texel4 = fetchOutlineTexel(gTexCoord + vec2f(-offsetx, -offsety));\n let texel5 = fetchOutlineTexel(gTexCoord + vec2f(-offsetx, 0.0));\n let texel6 = fetchOutlineTexel(gTexCoord + vec2f(-offsetx, offsety));\n let texel7 = fetchOutlineTexel(gTexCoord + vec2f(0.0, offsety));\n let rowx = -fac0 * texel5 + fac0 * texel1 + -fac1 * texel6 + fac1 * texel0 + -fac1 * texel4 + fac1 * texel2;\n let rowy = -fac0 * texel3 + fac0 * texel7 + -fac1 * texel4 + fac1 * texel6 + -fac1 * texel2 + fac1 * texel0;\n let magSqr = sqrt(dot(rowy, rowy) + dot(rowx, rowx));\n let infMag = magSqr < 1.0 / 65025.0;\n let texelCenter = fetchOutlineTexel(gTexCoord).r * uniforms.outlineColor;\n if (all(texelCenter == vec3f(0.0)) || (uniforms.highlightFactor == 0.0 && infMag)) {\n return vec4f(0.0);\n }\n let finalFactor = select(min(1.0, sqrt(magSqr) * uniforms.outlineFactor), uniforms.highlightFactor, infMag);\n return finalFactor * vec4f(texelCenter, 1.0);\n}\nfn composeOutline(color: vec4f) -> vec4f {\n let outlineColor = outline();\n return outlineColor + color * (1.0 - outlineColor.a);\n}\n#endif\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n gTexCoord = vertexOutput.vTexCoord;\n var color: vec4f;\n if (uniforms.enableFXAA == 1.0) {\n color = readFXAATexture(vertexOutput.vTexCoord);\n } else {\n color = readFXAATexture(vertexOutput.vTexCoord);\n }\n if (uniforms.enableSharpen == 1.0) {\n color = sharpen(color);\n }\n if (uniforms.enableToneMapping == 1.0) {\n color = vec4(tonemap(color.rgb), color.a);\n }\n #ifdef HAS_OUTLINE_TEX\n color = composeOutline(color);\n #endif\n return color;\n}";
87
87
 
88
88
  var glImageFrag = "struct Scene {\n opacity : f32,\n baseColor : vec4f,\n alphaTest : f32,\n}\n@group(0) @binding(1) var<uniform> scene: Scene;\n@group(0) @binding(2) var baseColorTextureSampler: sampler;\n@group(0) @binding(3) var baseColorTexture: texture_2d<f32>;\n#if HAS_DEBUG\n @group(0) @binding(4) var debugTextureSampler: sampler;\n @group(0) @binding(5) var debugTexture: texture_2d<f32>;\n#endif\n@fragment\nfn main(\n input : VertexOutput,\n) -> @location(0) vec4f {\n var fragColor = textureSample(baseColorTexture, baseColorTextureSampler, input.vTexCoord);\n fragColor *= scene.baseColor;\n #if HAS_DEBUG\n var debugColor = textureSample(debugTexture, debugTextureSampler, input.vTexCoord);\n fragColor = vec4f(\n debugColor.rgb + fragColor.rgb * (1.0 - debugColor.a),\n debugColor.a + fragColor.a * (1.0 - debugColor.a)\n );\n #endif\n if (fragColor.a < scene.alphaTest) {\n discard;\n }\n return fragColor * scene.opacity;\n}";
89
89
 
@@ -95,7 +95,7 @@ var glPhongVert = "struct VertexInput {\n#include <position_vert>\n#ifdef HAS_MA
95
95
 
96
96
  var glQuadFrag = "#define SHADER_NAME QUAD\nstruct QuadFragUniforms {\n outputSize: vec2f,\n inputSize: vec2f,\n};\n@group(0) @binding($b) var<uniform> uniforms: QuadFragUniforms;\n#ifdef HAS_MULTISAMPLED\n @group(0) @binding($b) var TextureInput: texture_multisampled_2d<f32>;\n#else\n @group(0) @binding($b) var TextureInput: texture_2d<f32>;\n#endif\n@group(0) @binding($b) var TextureInputSampler: sampler;\n@fragment\nfn main(\n vertexOutput: VertexOutput\n) -> @location(0) vec4f {\n let uv = vertexOutput.position.xy;\n #ifdef HAS_MULTISAMPLED\n let color = textureLoad(TextureInput, vec2i(uv / uniforms.outputSize * uniforms.inputSize), 0);\n #else\n let color = textureSample(TextureInput, TextureInputSampler, uv / uniforms.outputSize);\n #endif\n return color;\n}";
97
97
 
98
- var glQuadVert = "struct VertexOutput {\n @builtin(position) position : vec4f,\n @location($o) vTexCoord: vec2f\n}\n@vertex\nfn main(\n @location($i) aPosition: vec2f,\n @location($i) aTexCoord: vec2f\n) -> VertexOutput {\n var output: VertexOutput;\n output.position = vec4f(aPosition, 0., 1.);\n output.vTexCoord = aTexCoord;\n return output;\n}";
98
+ var glQuadVert = "struct VertexOutput {\n @builtin(position) position : vec4f,\n @location($o) vTexCoord: vec2f\n}\n@vertex\nfn main(\n @location($i) aPosition: vec2f,\n @location($i) aTexCoord: vec2f,\n) -> VertexOutput {\n var output: VertexOutput;\n output.position = vec4f(aPosition, 0., 1.);\n output.vTexCoord = aTexCoord;\n return output;\n}";
99
99
 
100
100
  var glShadowDisplayFrag = "#include <vsm_shadow_frag>\nstruct ShadowDisplayUniforms3 {\n color: vec3f,\n};\n@group(0) @binding($b) var<uniform> uniforms: ShadowDisplayUniforms3;\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n let visibility = shadow_computeShadow(vertexOutput);\n let alpha = 1.0 - visibility;\n return vec4f(uniforms.color * alpha, alpha);\n}";
101
101
 
@@ -103,7 +103,7 @@ var glShadowDisplayVert = "#include <vsm_shadow_vert>\nstruct VertexInput {\n
103
103
 
104
104
  var glVsmMappingFrag = "#ifdef PACK_FLOAT\n #include <common_pack_float>\n#endif\nstruct FragmentOutput {\n @location(0) color: vec4f,\n};\n@fragment\nfn main(\n vertexOutput: VertexOutput\n) -> @location(0) vec4f {\n var color: vec4f;\n #if USE_ESM\n #ifdef PACK_FLOAT\n color = common_encodeDepth(vertexOutput.position.z);\n #else\n color = vec4f(vertexOutput.position.z, 0.0, 0.0, 1.0);\n #endif\n #endif\n return color;\n}";
105
105
 
106
- var glVsmMappingVert = "#include <line_extrusion_vert>\n#include <get_output>\nstruct ShadowMappingUniforms {\n lightProjViewModelMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n modelMatrix: mat4x4f,\n};\nstruct VertexInput {\n #include <position_vert>\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f\n};\n@group(0) @binding($b) var<uniform> uniforms: ShadowMappingUniforms;\n@vertex\nfn main(\n vertexInput: VertexInput\n) -> VertexOutput {\n var output: VertexOutput;\n let localPositionMatrix = getPositionMatrix(vertexInput, &output, uniforms.positionMatrix);\n #ifdef IS_LINE_EXTRUSION\n let linePosition = getLineExtrudePosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n let localVertex = getPosition(linePosition, vertexInput);\n #else\n let localVertex = getPosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n #endif\n output.position = uniforms.lightProjViewModelMatrix * localPositionMatrix * localVertex;\n return output;\n}";
106
+ var glVsmMappingVert = "#include <line_extrusion_vert>\n#include <get_output>\nstruct ShadowMappingUniforms {\n lightProjViewModelMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n modelMatrix: mat4x4f,\n};\nstruct VertexInput {\n #include <position_vert>\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n};\n@group(0) @binding($b) var<uniform> uniforms: ShadowMappingUniforms;\n@vertex\nfn main(\n vertexInput: VertexInput\n) -> VertexOutput {\n var output: VertexOutput;\n let localPositionMatrix = getPositionMatrix(vertexInput, &output, uniforms.positionMatrix);\n #ifdef IS_LINE_EXTRUSION\n let linePosition = getLineExtrudePosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n let localVertex = getPosition(linePosition, vertexInput);\n #else\n let localVertex = getPosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n #endif\n output.position = uniforms.lightProjViewModelMatrix * localPositionMatrix * localVertex;\n return output;\n}";
107
107
 
108
108
  var glSkyboxFrag = "#include <hsv_frag>\nstruct SkyboxUniforms {\n hsv: vec3f,\n #ifdef USE_AMBIENT\n diffuseSPH: array<vec3f, 9>,\n #else\n bias: f32,\n size: f32,\n #endif\n environmentExposure: f32,\n backgroundIntensity: f32,\n};\n@group(0) @binding($b) var<uniform> uniforms: SkyboxUniforms;\n#ifndef USE_AMBIENT\n @group(0) @binding($b) var cubeMap: texture_cube<f32>;\n @group(0) @binding($b) var cubeMapSampler: sampler;\n#endif\nfn textureCubeFixed(tex: texture_cube<f32>, texSampler: sampler, R: vec3f, size: f32, bias: f32) -> vec4f {\n var dir: vec3f = R;\n return textureSampleLevel(tex, texSampler, dir, bias);\n}\nfn computeDiffuseSPH(normal: vec3f, diffuseSPH: array<vec3f, 9>) -> vec3f {\n let x: f32 = normal.x;\n let y: f32 = normal.y;\n let z: f32 = normal.z;\n var result: vec3f = (\n diffuseSPH[0] +\n diffuseSPH[1] * x +\n diffuseSPH[2] * y +\n diffuseSPH[3] * z +\n diffuseSPH[4] * z * x +\n diffuseSPH[5] * y * z +\n diffuseSPH[6] * y * x +\n diffuseSPH[7] * (3.0 * z * z - 1.0) +\n diffuseSPH[8] * (x * x - y * y)\n );\n return max(result, vec3f(0.0));\n}\nfn pseudoRandom(fragCoord: vec2f) -> f32 {\n var p3: vec3f = fract(vec3f(fragCoord.x, fragCoord.y, fragCoord.x) * 0.1031);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.x + p3.y) * p3.z);\n}\n#if TONE_MAPPING\n const toneMappingExposure: f32 = 1.0;\n fn RRTAndODTFit(v: vec3f) -> vec3f {\n let a: vec3f = v * (v + 0.0245786) - 0.000090537;\n let b: vec3f = v * (0.983729 * v + 0.4329510) + 0.238081;\n return a / b;\n }\n fn ACESFilmicToneMapping(color: vec3f) -> vec3f {\n const ACESInputMat: mat3x3f = mat3x3f(\n vec3f(0.59719, 0.07600, 0.02840),\n vec3f(0.35458, 0.90834, 0.13383),\n vec3f(0.04823, 0.01566, 0.83777)\n );\n const ACESOutputMat: mat3x3f = mat3x3f(\n vec3f(1.60475, -0.10208, -0.00327),\n vec3f(-0.53108, 1.10813, -0.07276),\n vec3f(-0.07367, -0.00605, 1.07602)\n );\n var adjustedColor: vec3f = color * toneMappingExposure / 0.6;\n adjustedColor = ACESInputMat * adjustedColor;\n adjustedColor = RRTAndODTFit(adjustedColor);\n adjustedColor = ACESOutputMat * adjustedColor;\n return clamp(adjustedColor, 0, 1);\n }\n fn toneMapping(color: vec3f) -> vec3f {\n return ACESFilmicToneMapping(color);\n }\n fn sRGBTransferOETF(value: vec4f) -> vec4f {\n var result: vec3f;\n let threshold: vec3f = vec3f(0.0031308);\n for (var i: i32 = 0; i < 3; i++) {\n if (value[i] <= threshold[i]) {\n result[i] = value[i] * 12.92;\n } else {\n result[i] = pow(value[i], 0.41666) * 1.055 - 0.055;\n }\n }\n return vec4f(result, value.a);\n }\n fn linearToOutputTexel(value: vec4f) -> vec4f {\n return sRGBTransferOETF(value);\n }\n#endif\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n var envColor: vec4f;\n #ifdef USE_AMBIENT\n var normal: vec3f = normalize(\n vertexOutput.vWorldPos +\n mix(-0.5/255.0, 0.5/255.0, pseudoRandom(vertexOutput.fragCoord.xy)) * 2.0\n );\n envColor = vec4f(computeDiffuseSPH(normal, uniforms.diffuseSPH), 1.0);\n #else\n envColor = textureCubeFixed(\n cubeMap,\n cubeMapSampler,\n vertexOutput.vWorldPos,\n uniforms.size,\n uniforms.bias\n );\n #endif\n var rgb = envColor.rgb;\n rgb *= uniforms.environmentExposure;\n rgb *= uniforms.backgroundIntensity;\n if (length(uniforms.hsv) > 0.0) {\n rgb = hsv_apply3(clamp(rgb, vec3f(0.0), vec3f(1.0)), uniforms.hsv);\n }\n #if TONE_MAPPING\n rgb = toneMapping(rgb);\n let fragColor = linearToOutputTexel(vec4f(rgb, envColor.a));\n #else\n let fragColor = vec4f(rgb, envColor.a);\n #endif\n return fragColor;\n}";
109
109
 
@@ -119,27 +119,31 @@ var glRainVert = "#include <get_output>\nstruct VertexInput {\n @location($i)
119
119
 
120
120
  var glRipplesFrag = "struct RippleEffectUniforms {\n rippleRadius: f32,\n density: f32,\n time: f32,\n};\n@group(0) @binding($b) var<uniform> uniforms: RippleEffectUniforms;\nfn hash3(p: vec2f) -> vec3f {\n let q = vec3f(\n dot(p, vec2f(127.1, 311.7)),\n dot(p, vec2f(269.5, 183.3)),\n dot(p, vec2f(419.2, 371.9))\n );\n return fract(sin(q) * 43758.5453);\n}\nfn noise(x: vec2f) -> f32 {\n let v = x * uniforms.density / 4000.0;\n let p = floor(v);\n let f = fract(v);\n var va: f32 = 0.0;\n for (var j: i32 = -4; j <= 4; j++) {\n for (var i: i32 = -4; i <= 4; i++) {\n let g = vec2f(f32(i), f32(j));\n let o = hash3(p + g);\n let r = g - f + o.xy;\n let d = sqrt(dot(r, r));\n let ripple = max(mix(smoothstep(0.99, 0.999, max(cos(d - uniforms.time * 2.0 + (o.x + o.y) * 5.0), 0.0)), 0.0, d), 0.0);\n va += ripple;\n }\n }\n return va;\n}\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n let uv = vertexOutput.vTexCoord;\n let radius = 24.0 / (uniforms.rippleRadius * 0.01);\n let f = noise(radius * uv) * smoothstep(0.0, 0.4, sin(uv.x * 3.151592) * sin(uv.y * 3.141592));\n let normal = vec3f(-dpdx(f), -dpdy(f), -dpdy(f));\n return vec4f(normal, 1.0);\n}";
121
121
 
122
- var glFogFrag = "struct WeatherUniforms {\n time: f32,\n resolution: vec2f,\n #ifdef HAS_SNOW\n snowIntensity: f32,\n #endif\n #ifdef HAS_FOG\n fogColor: vec3f,\n #endif\n};\n@group(0) @binding($b) var<uniform> uniforms: WeatherUniforms;\n#ifdef HAS_RAIN\n @group(0) @binding($b) var ripplesMapSampler: sampler;\n @group(0) @binding($b) var ripplesMap: texture_2d<f32>;\n#endif\n@group(0) @binding($b) var sceneMapSampler: sampler;\n#ifdef HAS_MULTISAMPLED\n @group(0) @binding($b) var sceneMap: texture_multisampled_2d<f32>;\n#else\n @group(0) @binding($b) var sceneMap: texture_2d<f32>;\n#endif\n@group(0) @binding($b) var mixFactorMapSampler: sampler;\n#ifdef HAS_MULTISAMPLED_MAP\n @group(0) @binding($b) var mixFactorMap: texture_multisampled_2d<f32>;\n#else\n @group(0) @binding($b) var mixFactorMap: texture_2d<f32>;\n#endif\nconst HASHSCALE1 = 0.1031;\nconst HASHSCALE3 = vec3f(0.1031, 0.1030, 0.0973);\nconst HASHSCALE4 = vec4f(0.1031, 0.1030, 0.0973, 0.1099);\nconst SIZE_RATE = 0.5;\nconst XSPEED = 0.2;\nconst YSPEED = 0.5;\nconst LAYERS = 20.0;\nfn lerp(a: f32, b: f32, w: f32) -> f32 {\n return a + w * (b - a);\n}\nfn Hash11(p: f32) -> f32 {\n var p3 = fract(vec3f(p) * HASHSCALE1);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.x + p3.y) * p3.z);\n}\nfn Hash22(p: vec2f) -> vec2f {\n var p3 = fract(vec3f(p.x, p.y, p.x) * HASHSCALE3);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.xx + p3.yz) * p3.zy);\n}\nfn Rand22(co: vec2f) -> vec2f {\n let x = fract(sin(dot(co, vec2f(122.9898, 783.233))) * 43758.5453);\n let y = fract(sin(dot(co, vec2f(457.6537, 537.2793))) * 37573.5913);\n return vec2f(x, y);\n}\n#ifdef HAS_SNOW\n fn SnowSingleLayer(uv: vec2f, layer: f32) -> vec3f {\n var uv_mut = uv * (2.0 + layer);\n let speedX = XSPEED * uniforms.snowIntensity;\n let xOffset = uv_mut.y * (((Hash11(layer) * 2.0 - 1.0) * 0.5 + 1.0) * speedX);\n let yOffset = YSPEED * uniforms.time;\n uv_mut += vec2f(xOffset, yOffset);\n let rgrid = Hash22(floor(uv_mut) + (31.1759 * layer));\n uv_mut = fract(uv_mut);\n uv_mut -= (rgrid * 2.0 - 1.0) * 0.35;\n uv_mut -= 0.5;\n let r = length(uv_mut);\n let circleSize = 0.05 * (1.0 + 0.3 * sin(uniforms.time * SIZE_RATE));\n let val = smoothstep(circleSize, -circleSize, r);\n let col = vec3f(val, val, val) * rgrid.x;\n return col;\n }\n fn snowFlower(fragCoord: vec2f) -> vec3f {\n var acc = vec3f(0.0, 0.0, 0.0);\n var uv = fragCoord / uniforms.resolution;\n uv.y = 1.0 - uv.y;\n uv *= vec2f(uniforms.resolution.x / uniforms.resolution.y, 1.0);\n let layers = LAYERS * uniforms.snowIntensity;\n for (var i: f32 = 0.0; i < layers; i += 1.0) {\n acc += SnowSingleLayer(uv, i);\n }\n return acc;\n }\n fn snow(sceneColor: vec4f, normalColor: vec4f, height: f32) -> vec3f {\n let snowIntense = normalColor.b;\n let fixedC = vec3f(1.0, 1.0, 1.0);\n if (height < 1.0) {\n let r = lerp(0.5, fixedC.x, snowIntense);\n let g = lerp(0.5, fixedC.y, snowIntense);\n let b = lerp(0.5, fixedC.z, snowIntense);\n return vec3f(r, g, b);\n } else {\n let r = lerp(sceneColor.r, fixedC.x, snowIntense);\n let g = lerp(sceneColor.g, fixedC.y, snowIntense);\n let b = lerp(sceneColor.b, fixedC.z, snowIntense);\n return vec3f(r, g, b);\n }\n }\n#endif\n@fragment\nfn main(\n vertexOutput: VertexOutput\n) -> @location(0) vec4f {\n var uv = vertexOutput.vTexCoord;\n uv.y = 1.0 - uv.y;\n #ifdef HAS_MULTISAMPLED\n var sceneColor = textureLoad(sceneMap, vec2i(uv * uniforms.resolution), 0);\n #else\n var sceneColor = textureSample(sceneMap, sceneMapSampler, uv);\n #endif\n var glFragColor = sceneColor;\n #ifdef HAS_MULTISAMPLED_MAP\n let mixFactorColor = textureLoad(mixFactorMap, vec2i(uv * uniforms.resolution), 0);\n #else\n let mixFactorColor = textureSample(mixFactorMap, mixFactorMapSampler, uv);\n #endif\n #ifdef HAS_RAIN\n let ripplesColor = textureSample(ripplesMap, ripplesMapSampler, uv);\n if (mixFactorColor.g < 1.0) {\n sceneColor = mix(sceneColor, ripplesColor, 0.4);\n }\n glFragColor = sceneColor;\n #endif\n #ifdef HAS_SNOW\n let fragCoord = vertexOutput.position.xy;\n let snowFlowerColor = snowFlower(fragCoord);\n glFragColor = vec4f(sceneColor.rgb + snowFlowerColor, sceneColor.a);\n #endif\n #ifdef HAS_FOG\n let mixFactor = mixFactorColor.r;\n let mixColor = mix(uniforms.fogColor, glFragColor.rgb, mixFactor);\n glFragColor = vec4f(mixColor, sceneColor.a);\n #endif\n return glFragColor;\n}";
122
+ var glFogFrag = "struct WeatherUniforms {\n time: f32,\n resolution: vec2f,\n #ifdef HAS_SNOW\n snowIntensity: f32,\n #endif\n #ifdef HAS_FOG\n fogColor: vec3f,\n #endif\n};\n@group(0) @binding($b) var<uniform> uniforms: WeatherUniforms;\n#ifdef HAS_RAIN\n @group(0) @binding($b) var ripplesMapSampler: sampler;\n @group(0) @binding($b) var ripplesMap: texture_2d<f32>;\n#endif\n@group(0) @binding($b) var sceneMapSampler: sampler;\n@group(0) @binding($b) var sceneMap: texture_2d<f32>;\n@group(0) @binding($b) var mixFactorMapSampler: sampler;\n@group(0) @binding($b) var mixFactorMap: texture_2d<f32>;\nconst HASHSCALE1 = 0.1031;\nconst HASHSCALE3 = vec3f(0.1031, 0.1030, 0.0973);\nconst HASHSCALE4 = vec4f(0.1031, 0.1030, 0.0973, 0.1099);\nconst SIZE_RATE = 0.5;\nconst XSPEED = 0.2;\nconst YSPEED = 0.5;\nconst LAYERS = 20.0;\nfn lerp(a: f32, b: f32, w: f32) -> f32 {\n return a + w * (b - a);\n}\nfn Hash11(p: f32) -> f32 {\n var p3 = fract(vec3f(p) * HASHSCALE1);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.x + p3.y) * p3.z);\n}\nfn Hash22(p: vec2f) -> vec2f {\n var p3 = fract(vec3f(p.x, p.y, p.x) * HASHSCALE3);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.xx + p3.yz) * p3.zy);\n}\nfn Rand22(co: vec2f) -> vec2f {\n let x = fract(sin(dot(co, vec2f(122.9898, 783.233))) * 43758.5453);\n let y = fract(sin(dot(co, vec2f(457.6537, 537.2793))) * 37573.5913);\n return vec2f(x, y);\n}\n#ifdef HAS_SNOW\n fn SnowSingleLayer(uv: vec2f, layer: f32) -> vec3f {\n var uv_mut = uv * (2.0 + layer);\n let speedX = XSPEED * uniforms.snowIntensity;\n let xOffset = uv_mut.y * (((Hash11(layer) * 2.0 - 1.0) * 0.5 + 1.0) * speedX);\n let yOffset = YSPEED * uniforms.time;\n uv_mut += vec2f(xOffset, yOffset);\n let rgrid = Hash22(floor(uv_mut) + (31.1759 * layer));\n uv_mut = fract(uv_mut);\n uv_mut -= (rgrid * 2.0 - 1.0) * 0.35;\n uv_mut -= 0.5;\n let r = length(uv_mut);\n let circleSize = 0.05 * (1.0 + 0.3 * sin(uniforms.time * SIZE_RATE));\n let val = smoothstep(circleSize, -circleSize, r);\n let col = vec3f(val, val, val) * rgrid.x;\n return col;\n }\n fn snowFlower(fragCoord: vec2f) -> vec3f {\n var acc = vec3f(0.0, 0.0, 0.0);\n var uv = fragCoord / uniforms.resolution;\n uv.y = 1.0 - uv.y;\n uv *= vec2f(uniforms.resolution.x / uniforms.resolution.y, 1.0);\n let layers = LAYERS * uniforms.snowIntensity;\n for (var i: f32 = 0.0; i < layers; i += 1.0) {\n acc += SnowSingleLayer(uv, i);\n }\n return acc;\n }\n fn snow(sceneColor: vec4f, normalColor: vec4f, height: f32) -> vec3f {\n let snowIntense = normalColor.b;\n let fixedC = vec3f(1.0, 1.0, 1.0);\n if (height < 1.0) {\n let r = lerp(0.5, fixedC.x, snowIntense);\n let g = lerp(0.5, fixedC.y, snowIntense);\n let b = lerp(0.5, fixedC.z, snowIntense);\n return vec3f(r, g, b);\n } else {\n let r = lerp(sceneColor.r, fixedC.x, snowIntense);\n let g = lerp(sceneColor.g, fixedC.y, snowIntense);\n let b = lerp(sceneColor.b, fixedC.z, snowIntense);\n return vec3f(r, g, b);\n }\n }\n#endif\n@fragment\nfn main(\n vertexOutput: VertexOutput\n) -> @location(0) vec4f {\n var uv = vertexOutput.vTexCoord;\n uv.y = 1.0 - uv.y;\n var sceneColor = textureSample(sceneMap, sceneMapSampler, uv);\n var glFragColor = sceneColor;\n let mixFactorColor = textureSample(mixFactorMap, mixFactorMapSampler, uv);\n #ifdef HAS_RAIN\n let ripplesColor = textureSample(ripplesMap, ripplesMapSampler, uv);\n if (mixFactorColor.g < 1.0) {\n sceneColor = mix(sceneColor, ripplesColor, 0.4);\n }\n glFragColor = sceneColor;\n #endif\n #ifdef HAS_SNOW\n let fragCoord = vertexOutput.position.xy;\n let snowFlowerColor = snowFlower(fragCoord);\n glFragColor = vec4f(sceneColor.rgb + snowFlowerColor, sceneColor.a);\n #endif\n #ifdef HAS_FOG\n let mixFactor = mixFactorColor.r;\n let mixColor = mix(uniforms.fogColor, glFragColor.rgb, mixFactor);\n glFragColor = vec4f(mixColor, sceneColor.a);\n #endif\n return glFragColor;\n}";
123
123
 
124
- var glFogMixFactorVert = "#include <get_output>\nstruct Uniforms {\n modelMatrix: mat4x4f,\n modelViewMatrix: mat4x4f,\n positionMatrix: mat4x4f\n};\nstruct ShaderUniforms {\n projMatrix: mat4x4f,\n}\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\nstruct VertexInput {\n #include <position_vert>\n @location($i) aTexCoord: vec2f\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location($o) vWorldPosition: vec4f,\n};\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let localPositionMatrix: mat4x4f = getPositionMatrix(vertexInput, &output, uniforms.positionMatrix);\n let localPosition: vec4f = localPositionMatrix * getPosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n output.position = shaderUniforms.projMatrix * uniforms.modelViewMatrix * localPosition;\n let worldPosition = uniforms.modelMatrix * localPosition;\n output.vWorldPosition = worldPosition;\n return output;\n}";
124
+ var glFogMixFactorVert = "#include <get_output>\nstruct Uniforms {\n modelMatrix: mat4x4f,\n modelViewMatrix: mat4x4f,\n positionMatrix: mat4x4f\n};\nstruct ShaderUniforms {\n projMatrix: mat4x4f,\n}\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\nstruct VertexInput {\n #include <position_vert>\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location($o) vWorldPosition: vec4f,\n};\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let localPositionMatrix: mat4x4f = getPositionMatrix(vertexInput, &output, uniforms.positionMatrix);\n let localPosition: vec4f = localPositionMatrix * getPosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n output.position = shaderUniforms.projMatrix * uniforms.modelViewMatrix * localPosition;\n let worldPosition = uniforms.modelMatrix * localPosition;\n output.vWorldPosition = worldPosition;\n return output;\n}";
125
125
 
126
126
  var glFogMixFactorFrag = "struct FogEffectUniforms {\n fogDist: vec2f,\n cameraPosition: vec3f,\n rainDepth: f32,\n};\n@group(0) @binding($b) var<uniform> uniforms: FogEffectUniforms;\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n let worldPosition = vertexOutput.vWorldPosition;\n let dir = vec3f(\n worldPosition.x - uniforms.cameraPosition.x,\n worldPosition.y - uniforms.cameraPosition.y,\n worldPosition.z - uniforms.cameraPosition.z\n );\n let dist = length(dir);\n let fogFactor = clamp(1.0 - (dist - uniforms.fogDist.x) / (uniforms.fogDist.y - uniforms.fogDist.x), 0.0, 1.0);\n var gl_FragColor: vec4f;\n if (worldPosition.z < uniforms.rainDepth) {\n gl_FragColor = vec4f(fogFactor, 0.0, 0.0, 1.0);\n } else {\n gl_FragColor = vec4f(fogFactor, 1.0, 0.0, 1.0);\n }\n return gl_FragColor;\n}";
127
127
 
128
- var layer3dtilesPickingVert = "#include <get_output>\n#include <fbo_picking_vert>\nstruct Uniforms {\n modelMatrix: mat4x4f,\n #ifdef HAS_MASK_EXTENT\n modelViewMatrix: mat4x4f,\n #endif\n positionMatrix: mat4x4f\n};\nstruct ShaderUniforms {\n projMatrix: mat4x4f,\n}\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\nstruct VertexInput {\n #include <position_vert>\n #if HAS_COLOR\n @location($i) aColor: vec4u,\n #endif\n #if HAS_COLOR0\n #if COLOR0_SIZE == 3\n @location($i) aColor0: vec3u,\n #else\n @location($i) aColor0: vec4u,\n #endif\n #endif\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location($o) viewpoint: vec4f,\n};\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let localPositionMatrix: mat4x4f = getPositionMatrix(vertexInput, &output, uniforms.positionMatrix);\n let localVertex = getPosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n let position: vec4f = localPositionMatrix * localVertex;\n let viewVertex = uniforms.modelMatrix * position;\n let projMatrix = shaderUniforms.projMatrix;\n #ifdef HAS_MASK_EXTENT\n output.position = projMatrix * getMaskPosition(position, uniforms.modelMatrix);\n #else\n output.position = projMatrix * viewVertex;\n #endif\n var alpha = 1.0;\n #if HAS_COLOR\n alpha *= vertexInput.aColor.a;\n #endif\n #if HAS_COLOR0 && COLOR0_SIZE == 4\n alpha *= vertexInput.aColor0.a;\n #endif\n fbo_picking_setData(vertexInput, &output, output.position.w, alpha != 0.0);\n return output;\n}";
128
+ var layer3dtilesPickingVert = "#include <get_output>\n#include <fbo_picking_vert>\nstruct Uniforms {\n modelViewMatrix: mat4x4f,\n #ifdef HAS_MASK_EXTENT\n modelMatrix: mat4x4f,\n #endif\n positionMatrix: mat4x4f\n};\nstruct ShaderUniforms {\n projMatrix: mat4x4f,\n}\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\nstruct VertexInput {\n #include <position_vert>\n #if HAS_COLOR\n @location($i) aColor: vec4u,\n #endif\n #if HAS_COLOR0\n #if COLOR0_SIZE == 3\n @location($i) aColor0: vec3u,\n #else\n @location($i) aColor0: vec4u,\n #endif\n #endif\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location($o) viewpoint: vec4f,\n};\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let localPositionMatrix: mat4x4f = getPositionMatrix(vertexInput, &output, uniforms.positionMatrix);\n let localVertex = getPosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n let position: vec4f = localPositionMatrix * localVertex;\n let viewVertex = uniforms.modelViewMatrix * position;\n let projMatrix = shaderUniforms.projMatrix;\n #ifdef HAS_MASK_EXTENT\n output.position = projMatrix * getMaskPosition(position, uniforms.modelMatrix);\n #else\n output.position = projMatrix * viewVertex;\n #endif\n var alpha = 1.0;\n #if HAS_COLOR\n alpha *= vertexInput.aColor.a;\n #endif\n #if HAS_COLOR0 && COLOR0_SIZE == 4\n alpha *= vertexInput.aColor0.a;\n #endif\n fbo_picking_setData(vertexInput, &output, output.position.w, alpha != 0.0);\n return output;\n}";
129
+
130
+ var layer3dtilesPntsVert = "const SHIFT_RIGHT_11 = 1.0 / 2048.0;\nconst SHIFT_RIGHT_5 = 1.0 / 32.0;\nconst SHIFT_LEFT_11 = 2048.0;\nconst SHIFT_LEFT_5 = 32.0;\nconst NORMALIZE_6 = 1.0 / 64.0;\nconst NORMALIZE_5 = 1.0 / 32.0;\nstruct PointUniforms {\n pointColor: vec4f,\n pointSize: f32,\n projViewModelMatrix: mat4x4f,\n pointOpacity: f32,\n #ifdef HAS_NORMAL\n lightDir: vec3f,\n modelNormalMatrix: mat3x3f,\n positionMatrix: mat4x4f,\n #endif\n};\n@group(0) @binding($b) var<uniform> uniforms: PointUniforms;\nstruct VertexInput {\n #ifdef HAS_POSITION\n #include <position_vert>\n #endif\n #if HAS_RGB\n @location($i) RGB: vec3u,\n #elif HAS_RGBA\n @location($i) RGBA: vec4u,\n #elif HAS_RGB565\n RGB565: u32,\n #endif\n #ifdef HAS_NORMAL\n #ifdef HAS_NORMAL_OCT16P\n @location($i) NORMAL_OCT16P: vec2f,\n #else\n @location($i) NORMAL: vec3f,\n #endif\n #endif\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location($o) vColor: vec4f,\n};\nfn signNotZero(value: f32) -> f32 {\n return select(-1.0, 1.0, value >= 0.0);\n}\nfn signNotZero_vec2(value: vec2f) -> vec2f {\n return vec2f(signNotZero(value.x), signNotZero(value.y));\n}\nfn octDecode(encoded: vec2f, range: f32) -> vec3f {\n if (encoded.x == 0.0 && encoded.y == 0.0) {\n return vec3f(0.0, 0.0, 0.0);\n }\n var decoded = encoded / range * 2.0 - 1.0;\n var v = vec3f(decoded.x, decoded.y, 1.0 - abs(decoded.x) - abs(decoded.y));\n if (v.z < 0.0) {\n v = vec3f((1.0 - abs(v.yx)) * signNotZero_vec2(v.xy), v.z);\n }\n return normalize(v);\n}\nfn octDecode_simple(encoded: vec2f) -> vec3f {\n return octDecode(encoded, 255.0);\n}\nfn getLambertDiffuse(lightDir: vec3f, normal: vec3f) -> f32 {\n return max(dot(-lightDir, normal), 0.0);\n}\n#ifdef PICKING_MODE\n #include <fbo_picking_vert>\n#endif\n#include <draco_decode_vert>\n@vertex\nfn main(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n #ifdef HAS_POSITION\n var localPos = decode_getPosition(vec3f(input.aPosition.xyz));\n #endif\n output.position = uniforms.projViewModelMatrix * vec4f(localPos, 1.0);\n #ifdef PICKING_MODE\n fbo_picking_setData(input, &output, output.position.w, true);\n #else\n #if HAS_RGB\n output.vColor = vec4f(vec3f(input.RGB) / 255.0, 1.0) * uniforms.pointOpacity;\n #elif HAS_RGBA\n output.vColor = vec4f(vec4f(input.RGBA) / 255.0) * uniforms.pointOpacity;\n #elif HAS_RGB565\n var compressed = f32(input.RGB565);\n var r = floor(compressed * SHIFT_RIGHT_11);\n compressed -= r * SHIFT_LEFT_11;\n var g = floor(compressed * SHIFT_RIGHT_5);\n compressed -= g * SHIFT_LEFT_5;\n var b = compressed;\n var rgb = vec3f(r * NORMALIZE_5, g * NORMALIZE_6, b * NORMALIZE_5);\n output.vColor = vec4f(rgb, 1.0);\n #else\n output.vColor = uniforms.pointColor;\n #endif\n #ifdef HAS_NORMAL\n var positionNormalMatrix = mat3x3f(uniforms.positionMatrix);\n var normalMatrix = uniforms.modelNormalMatrix * positionNormalMatrix;\n #ifdef HAS_NORMAL_OCT16P\n var localNormal = octDecode_simple(input.NORMAL_OCT16P);\n #else\n var localNormal = input.NORMAL;\n #endif\n var normal = normalize(normalMatrix * localNormal);\n var colorStrength = getLambertDiffuse(uniforms.lightDir, normal);\n colorStrength = max(colorStrength, 0.5);\n output.vColor *= colorStrength;\n #endif\n #endif\n return output;\n}";
131
+
132
+ var layer3dtilesPntsFrag = "#define SHADER_NAME PNTS\nstruct FragmentUniforms {\n layerOpacity: f32,\n};\n@group(0) @binding($b) var<uniform> uniforms: FragmentUniforms;\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n var fragColor = vertexOutput.vColor;\n #ifdef HAS_LAYER_OPACITY\n fragColor *= uniforms.layerOpacity;\n #endif\n return fragColor;\n}";
129
133
 
130
134
  var layerVideoVideoFrag = "struct FragUniforms {\n opacity: f32\n}\n@group(0) @binding($b) var videoTexture: texture_2d<f32>;\n@group(0) @binding($b) var videoTextureSampler: sampler;\n@group(0) @binding($b) var<uniform> fragUniforms: FragUniforms;\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n let color = textureSample(videoTexture, videoTextureSampler, vertexOutput.vTexCoords);\n return color * fragUniforms.opacity;\n}";
131
135
 
132
136
  var layerVideoVideoVert = "#include <get_output>\nstruct Uniforms {\n modelMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n projViewModelMatrix: mat4x4f,\n};\n@group(0) @binding($b) var<uniform> uniforms: Uniforms;\nstruct VertexInput {\n @location($i) aPosition: vec3f,\n @location($i) aTexCoord: vec2f,\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location($o) vTexCoords: vec2f,\n};\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let localPositionMatrix: mat4x4f = getPositionMatrix(vertexInput, &output, uniforms.positionMatrix);\n let localPosition: vec4f = getPosition(vec3f(vertexInput.aPosition.xyz), vertexInput);\n output.vTexCoords = vertexInput.aTexCoord;\n output.position = uniforms.projViewModelMatrix * localPositionMatrix * localPosition;\n return output;\n}";
133
137
 
134
- var vtBillboardFrag = "struct BillboardFragmentUniforms {\n textureSize: vec2f,\n};\n@group(0) @binding($b) var<uniform> uniforms: BillboardFragmentUniforms;\n@group(0) @binding($b) var billTexture: texture_2d<f32>;\n@group(0) @binding($b) var billTextureSampler: sampler;\n#if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_frag>\n#endif\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n var fragColor: vec4f = textureSample(billTexture, billTextureSampler, vertexOutput.vTexCoord / uniforms.textureSize);\n #if HAS_SHADOWING && !HAS_BLOOM\n let shadowCoeff = shadow_computeShadow(vertexOutput);\n fragColor.rgb = shadow_blend(fragColor.rgb, shadowCoeff);\n #endif\n return fragColor;\n}";
138
+ var vtBillboardFrag = "struct BillboardFragmentUniforms {\n textureSize: vec2f,\n};\n@group(0) @binding($b) var<uniform> uniforms: BillboardFragmentUniforms;\n@group(0) @binding($b) var billTexture: texture_2d<f32>;\n@group(0) @binding($b) var billTextureSampler: sampler;\n#if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_frag>\n#endif\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n var fragColor: vec4f = textureSample(billTexture, billTextureSampler, vertexOutput.vTexCoord / uniforms.textureSize);\n #if HAS_SHADOWING && !HAS_BLOOM\n let shadowCoeff = shadow_computeShadow(vertexOutput);\n fragColor = vec4f(shadow_blend(fragColor.rgb, shadowCoeff), fragColor.a);\n #endif\n return fragColor;\n}";
135
139
 
136
- var vtBillboardVert = "#ifdef HAS_ALTITUDE\n struct VertexInput {\n @location($i) aPosition: vec2i,\n @location($i) aAltitude: f32,\n#else\n struct VertexInput {\n @location($i) aPosition: vec4i,\n#endif\n @location($i) aExtrude: vec2i,\n @location($i) aTexCoord: vec2i,\n @location($i) aQuat: vec4f,\n };\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location($o) vTexCoord: vec2f,\n};\nstruct BillboardUniforms {\n positionMatrix: mat4x4f,\n projViewModelMatrix: mat4x4f,\n extrudeScale: f32,\n};\n@group(0) @binding($b) var<uniform> uniforms: BillboardUniforms;\n#ifdef PICKING_MODE\n #include <fbo_picking_vert>\n#endif\n#include <vt_position_vert>\n#if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_vert>\n#endif\nfn quatToMat4(q: vec4f) -> mat4x4f {\n let x = q.x;\n let y = q.y;\n let z = q.z;\n let w = q.w;\n let x2 = x * x;\n let y2 = y * y;\n let z2 = z * z;\n let xy = x * y;\n let xz = x * z;\n let yz = y * z;\n let wx = w * x;\n let wy = w * y;\n let wz = w * z;\n return mat4x4f(\n 1.0 - 2.0 * (y2 + z2), 2.0 * (xy - wz), 2.0 * (xz + wy), 0.0,\n 2.0 * (xy + wz), 1.0 - 2.0 * (x2 + z2), 2.0 * (yz - wx), 0.0,\n 2.0 * (xz - wy), 2.0 * (yz + wx), 1.0 - 2.0 * (x2 + y2), 0.0,\n 0.0, 0.0, 0.0, 1.0\n );\n}\n@vertex\nfn main(\n input: VertexInput\n) -> VertexOutput {\n var output: VertexOutput;\n let extrude = vec4f(f32(input.aExtrude.x) * uniforms.extrudeScale, 0.0, f32(input.aExtrude.y), 1.0);\n let rotationMat4 = quatToMat4(input.aQuat);\n let offset = (rotationMat4 * extrude).xyz;\n let position = unpackVTPositionOffset(input, offset);\n output.vTexCoord = vec2f(input.aTexCoord);\n output.position = uniforms.projViewModelMatrix * uniforms.positionMatrix * vec4f(position, 1.0);\n #ifdef PICKING_MODE\n fbo_picking_setData(output.position.w, true);\n #elif HAS_SHADOWING && !HAS_BLOOM\n shadow_computeShadowPars(vec4f(position, 1.0), &output);\n #endif\n return output;\n}";
140
+ var vtBillboardVert = "#ifdef HAS_ALTITUDE\n struct VertexInput {\n @location($i) aPosition: vec2i,\n @location($i) aAltitude: f32,\n#else\n struct VertexInput {\n @location($i) aPosition: vec4i,\n#endif\n @location($i) aTranslation: vec3i,\n @location($i) aExtrude: vec2i,\n @location($i) aTexCoord: vec2i,\n @location($i) aQuat: vec4f,\n };\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location($o) vTexCoord: vec2f,\n};\nstruct BillboardUniforms {\n positionMatrix: mat4x4f,\n projViewModelMatrix: mat4x4f,\n extrudeScale: f32,\n};\n@group(0) @binding($b) var<uniform> uniforms: BillboardUniforms;\n#ifdef PICKING_MODE\n #include <fbo_picking_vert>\n#endif\n#include <vt_position_vert>\n#if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_vert>\n#endif\nfn quatToMat4(q: vec4f) -> mat4x4f {\n let x = q.x;\n let y = q.y;\n let z = q.z;\n let w = q.w;\n let x2 = x * x;\n let y2 = y * y;\n let z2 = z * z;\n let xy = x * y;\n let xz = x * z;\n let yz = y * z;\n let wx = w * x;\n let wy = w * y;\n let wz = w * z;\n return mat4x4f(\n 1.0 - 2.0 * (y2 + z2), 2.0 * (xy - wz), 2.0 * (xz + wy), 0.0,\n 2.0 * (xy + wz), 1.0 - 2.0 * (x2 + z2), 2.0 * (yz - wx), 0.0,\n 2.0 * (xz - wy), 2.0 * (yz + wx), 1.0 - 2.0 * (x2 + y2), 0.0,\n 0.0, 0.0, 0.0, 1.0\n );\n}\n@vertex\nfn main(\n input: VertexInput\n) -> VertexOutput {\n var output: VertexOutput;\n let extrude = vec4f(f32(input.aExtrude.x + input.aTranslation.x) * uniforms.extrudeScale, input.aTranslation.y * uniforms.extrudeScale, f32(input.aExtrude.y + input.aTranslation.z), 1.0);\n let rotationMat4 = quatToMat4(input.aQuat);\n let offset = (rotationMat4 * extrude).xyz;\n let position = unpackVTPositionOffset(input, offset);\n output.vTexCoord = vec2f(input.aTexCoord);\n output.position = uniforms.projViewModelMatrix * uniforms.positionMatrix * vec4f(position, 1.0);\n #ifdef PICKING_MODE\n fbo_picking_setData(output.position.w, true);\n #elif HAS_SHADOWING && !HAS_BLOOM\n shadow_computeShadowPars(vec4f(position, 1.0), &output);\n #endif\n return output;\n}";
137
141
 
138
142
  var vtCollisionFrag = "@fragment\nfn main(\n input : VertexOutput,\n) -> @location(0) vec4f {\n return input.vColor;\n}";
139
143
 
140
144
  var vtCollisionVert = "struct Uniforms {\n size: vec2f,\n};\n@binding($b) @group(0) var<uniform> uniforms: Uniforms;\nstruct VertexInput {\n @location($i) aPosition: vec2f,\n @location($i) aVisible: f32,\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location($o) vColor: vec4f,\n};\n@vertex\nfn main(vertexInput: VertexInput) -> VertexOutput {\n var vertexOutput: VertexOutput;\n let uv = (vertexInput.aPosition / uniforms.size - 0.5) * 2.0 * vec2f(1.0, -1.0);\n vertexOutput.position = vec4f(uv, 0.0, 1.0);\n vertexOutput.vColor = mix(\n vec4f(1.0, 0.0, 0.0, 1.5) * 0.5,\n vec4f(0.0, 1.0, 0.0, 1.0) * 0.4,\n vertexInput.aVisible\n );\n return vertexOutput;\n}";
141
145
 
142
- var vtFillFrag = "#define SHADER_NAME FILL\n#if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_frag>\n#endif\nstruct FragmentUniforms {\n #ifdef HAS_PATTERN\n #ifndef HAS_UV_SCALE\n uvScale: vec2f,\n #endif\n #ifndef HAS_UV_OFFSET\n uvOffset: vec2f,\n #endif\n atlasSize: vec2f,\n #endif\n #ifndef HAS_COLOR\n polygonFill: vec4f,\n #endif\n #ifndef HAS_OPACITY\n polygonOpacity: f32,\n #endif\n tileExtent: f32,\n}\nstruct ShaderUniforms {\n layerOpacity: f32,\n}\n@group(0) @binding($b) var<uniform> fragmentUniforms: FragmentUniforms;\n@group(0) @binding($b) var<uniform> uniforms: ShaderUniforms;\n#if HAS_PATTERN\n @group(0) @binding($b) var polygonPatternFile: texture_2d<f32>;\n @group(0) @binding($b) var polygonPatternFileSampler: sampler;\n#endif\n#include <highlight_frag>\n#ifdef HAS_PATTERN\n fn computeUV(vertexOutput: VertexOutput) -> vec2f {\n #ifdef HAS_UV_SCALE\n let myUVScale = vertexOutput.vUVScale;\n #else\n let myUVScale = fragmentUniforms.uvScale;\n #endif\n #ifdef HAS_UV_OFFSET\n let myUVOffset = vertexOutput.vUVOffset;\n #else\n let myUVOffset = fragmentUniforms.uvOffset;\n #endif\n let uv = (vertexOutput.vTexCoord * myUVScale + myUVOffset) % 1.0;\n let uvStart = vertexOutput.vTexInfo.xy;\n let uvSize = vertexOutput.vTexInfo.zw;\n return (uvStart + uv * uvSize) / fragmentUniforms.atlasSize;\n }\n#endif\n@fragment\nfn main(\n #ifdef HAS_PATTERN || HAS_COLOR || HAS_OPACITY || HAS_UV_SCALE || HAS_UV_OFFSET || HAS_HIGHLIGHT_COLOR || HAS_HIGHLIGHT_OPACITY\n vertexOutput: VertexOutput\n #endif\n) -> @location(0) vec4f {\n #ifdef HAS_COLOR\n var color = vertexOutput.vColor;\n #else\n var color = fragmentUniforms.polygonFill;\n #endif\n #ifdef HAS_PATTERN\n let uv = computeUV(vertexOutput);\n var texColor = textureSample(polygonPatternFile, polygonPatternFileSampler, uv);\n if (vertexOutput.vTexInfo.z * vertexOutput.vTexInfo.w > 1.0) {\n color = texColor;\n }\n #endif\n #ifdef HAS_OPACITY\n var outputColor = color * vertexOutput.vOpacity;\n #else\n var outputColor = color * fragmentUniforms.polygonOpacity;\n #endif\n outputColor *= uniforms.layerOpacity;\n #if HAS_SHADOWING && !HAS_BLOOM\n let shadowCoeff = shadow_computeShadow(vertexOutput);\n outputColor.rgb = shadow_blend(outputColor.rgb, shadowCoeff);\n #endif\n #if HAS_HIGHLIGHT_COLOR || HAS_HIGHLIGHT_OPACITY\n outputColor = highlight_blendColor(outputColor, vertexOutput);\n #endif\n return outputColor;\n}";
146
+ var vtFillFrag = "#define SHADER_NAME FILL\n#if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_frag>\n#endif\nstruct FragmentUniforms {\n #ifdef HAS_PATTERN\n #ifndef HAS_UV_SCALE\n uvScale: vec2f,\n #endif\n #ifndef HAS_UV_OFFSET\n uvOffset: vec2f,\n #endif\n atlasSize: vec2f,\n #endif\n #ifndef HAS_COLOR\n polygonFill: vec4f,\n #endif\n #ifndef HAS_OPACITY\n polygonOpacity: f32,\n #endif\n tileExtent: f32,\n}\nstruct ShaderUniforms {\n layerOpacity: f32,\n}\n@group(0) @binding($b) var<uniform> fragmentUniforms: FragmentUniforms;\n@group(0) @binding($b) var<uniform> uniforms: ShaderUniforms;\n#if HAS_PATTERN\n @group(0) @binding($b) var polygonPatternFile: texture_2d<f32>;\n @group(0) @binding($b) var polygonPatternFileSampler: sampler;\n#endif\n#include <highlight_frag>\n#ifdef HAS_PATTERN\n fn computeUV(vertexOutput: VertexOutput) -> vec2f {\n #ifdef HAS_UV_SCALE\n let myUVScale = vertexOutput.vUVScale;\n #else\n let myUVScale = fragmentUniforms.uvScale;\n #endif\n #ifdef HAS_UV_OFFSET\n let myUVOffset = vertexOutput.vUVOffset;\n #else\n let myUVOffset = fragmentUniforms.uvOffset;\n #endif\n let uv = (vertexOutput.vTexCoord * myUVScale + myUVOffset) % 1.0;\n let uvStart = vertexOutput.vTexInfo.xy;\n let uvSize = vertexOutput.vTexInfo.zw;\n return (uvStart + uv * uvSize) / fragmentUniforms.atlasSize;\n }\n#endif\n@fragment\nfn main(\n vertexOutput: VertexOutput\n) -> @location(0) vec4f {\n #ifdef HAS_COLOR\n var color = vertexOutput.vColor;\n #else\n var color = fragmentUniforms.polygonFill;\n #endif\n #ifdef HAS_PATTERN\n let uv = computeUV(vertexOutput);\n var texColor = textureSample(polygonPatternFile, polygonPatternFileSampler, uv);\n if (vertexOutput.vTexInfo.z * vertexOutput.vTexInfo.w > 1.0) {\n color = texColor;\n }\n #endif\n #ifdef HAS_OPACITY\n var outputColor = color * vertexOutput.vOpacity;\n #else\n var outputColor = color * fragmentUniforms.polygonOpacity;\n #endif\n outputColor *= uniforms.layerOpacity;\n #if HAS_SHADOWING && !HAS_BLOOM\n let shadowCoeff = shadow_computeShadow(vertexOutput);\n outputColor = vec4f(shadow_blend(outputColor.rgb, shadowCoeff), outputColor.a);\n #endif\n #if HAS_HIGHLIGHT_COLOR || HAS_HIGHLIGHT_OPACITY\n outputColor = highlight_blendColor(outputColor, vertexOutput);\n #endif\n return outputColor;\n}";
143
147
 
144
148
  var vtFillPickingVert = "struct VertexInput {\n#ifdef HAS_ALTITUDE\n @location($i) aPosition: POSITION_TYPE_2,\n @location($i) aAltitude: f32,\n#else\n @location($i) aPosition: POSITION_TYPE_3,\n#endif\n}\nstruct UniformsStruct {\n projViewModelMatrix: mat4x4f,\n positionMatrix: mat4x4f,\n}\n@group(0) @binding($b) var<uniform> uniforms: UniformsStruct;\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n}\n#include <fbo_picking_vert>\n#include <vt_position_vert>\n@vertex\nfn main(\n input: VertexInput,\n) -> VertexOutput {\n let position = unpackVTPosition(input);\n var output: VertexOutput;\n output.position = uniforms.projViewModelMatrix * uniforms.positionMatrix * vec4f(position, 1.0);\n fbo_picking_setData(input, &output, output.position.w, true);\n return output;\n}";
145
149
 
@@ -149,7 +153,7 @@ var vtLineFrag = "#define DEVICE_PIXEL_RATIO 1.0\n#if HAS_SHADOWING && !HAS_BLOO
149
153
 
150
154
  var vtLineGradientFrag = "#define SHADER_NAME LINE_GRADIENT\n#define DEVICE_PIXEL_RATIO 1.0\n#define MAX_LINE_COUNT 128.0\n#ifdef HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_frag>\n#endif\n#include <highlight_frag>\nstruct LineGradientUniforms {\n layerOpacity: f32,\n #ifdef HAS_TRAIL\n trailSpeed: f32,\n trailLength: f32,\n trailCircle: f32,\n currentTime: f32,\n #endif\n};\nstruct LineFragmentUniforms {\n lineBlur: f32,\n tileExtent: f32,\n lineGradientTextureHeight: f32,\n #ifndef HAS_OPACITY\n lineOpacity: f32,\n #endif\n};\n@group(0) @binding($b) var<uniform> uniforms: LineGradientUniforms;\n@group(0) @binding($b) var<uniform> lineUniforms: LineFragmentUniforms;\n@group(0) @binding($b) var lineGradientTexture: texture_2d<f32>;\n@group(0) @binding($b) var lineGradientTextureSampler: sampler;\n@fragment\nfn main(vertexOutput: VertexOutput) -> @location(0) vec4f {\n #ifndef ENABLE_TILE_STENCIL\n let tileExtent = lineUniforms.tileExtent;\n let clip = sign(tileExtent - min(tileExtent, abs(vertexOutput.vPosition.x))) *\n sign(1.0 + sign(vertexOutput.vPosition.x)) *\n sign(tileExtent - min(tileExtent, abs(vertexOutput.vPosition.y))) *\n sign(1.0 + sign(vertexOutput.vPosition.y));\n if clip == 0.0 {\n discard;\n }\n #endif\n let dist = length(vertexOutput.vNormal) * vertexOutput.vWidth.x;\n let blur2 = (lineUniforms.lineBlur + 1.0 / DEVICE_PIXEL_RATIO) * vertexOutput.vGammaScale;\n let alpha = clamp(min(dist - (vertexOutput.vWidth.y - blur2), vertexOutput.vWidth.x - dist) / blur2, 0.0, 1.0);\n let linesofar = vertexOutput.vLinesofar;\n let texCoord = vec2f(linesofar, (vertexOutput.vGradIndex * 2.0 + 0.5) / lineUniforms.lineGradientTextureHeight);\n var color = textureSample(lineGradientTexture, lineGradientTextureSampler, texCoord) * alpha;\n color = color * max(sign(MAX_LINE_COUNT - vertexOutput.vGradIndex), 0.0);\n #ifdef HAS_TRAIL\n let trailMod = mod(linesofar - uniforms.currentTime * uniforms.trailSpeed * 0.1, uniforms.trailCircle);\n let trailAlpha = select(0.0, mix(0.0, 1.0, trailMod / uniforms.trailLength), trailMod < uniforms.trailLength);\n color = color * trailAlpha;\n #endif\n #ifdef HAS_OPACITY\n let opacity = vertexOutput.vOpacity;\n #else\n let opacity = lineUniforms.lineOpacity;\n #endif\n var fragColor = color * opacity * uniforms.layerOpacity;\n #if HAS_SHADOWING && !HAS_BLOOM\n let shadowCoeff = shadow_computeShadow(vertexOutput);\n fragColor = vec4f(shadow_blend(fragColor.rgb, shadowCoeff).rgb, fragColor.a);\n #endif\n #if HAS_HIGHLIGHT_OPACITY || HAS_HIGHLIGHT_COLOR\n fragColor = highlight_blendColor(fragColor, vertexOutput);\n #endif\n return fragColor;\n}";
151
155
 
152
- var vtLineVert = "#define AA_CLIP_LIMIT 2.0\n#define AA_LINE_WIDTH 16.0\n#define DEVICE_PIXEL_RATIO 1.0\n#define ANTIALIASING 1.0 / 1.0 / 2.0\n#define EXTRUDE_SCALE 63.0\n#define EXTRUDE_MOD 64.0\n#define MAX_LINE_DISTANCE 65535.0\nstruct LineUniforms {\n lineStrokeWidth: f32,\n positionMatrix: mat4x4f,\n projViewModelMatrix: mat4x4f,\n modelMatrix: mat4x4f,\n tileResolution: f32,\n tileRatio: f32,\n lineDx: f32,\n lineDy: f32,\n lineWidth: f32\n};\nstruct ShaderUniforms {\n resolution: f32,\n cameraToCenterDistance: f32,\n canvasSize: vec2f,\n layerScale: f32,\n isRenderingTerrain: f32,\n}\n@group(0) @binding($b) var<uniform> uniforms: LineUniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\nstruct VertexInput {\n#ifdef HAS_ALTITUDE\n @location($i) aPosition: POSITION_TYPE_2,\n @location($i) aAltitude: f32,\n#else\n @location($i) aPosition: POSITION_TYPE_3,\n#endif\n#if HAS_PATTERN || HAS_DASHARRAY\n @location($i) aExtrude: vec4i,\n#else\n @location($i) aExtrude: vec2i,\n#endif\n#if HAS_PATTERN || HAS_DASHARRAY || HAS_GRADIENT || HAS_TRAIL\n @location($i) aLinesofar: LINESOFAR_TYPE,\n#endif\n#ifdef HAS_STROKE_WIDTH\n @location($i) aLineStrokeWidth: u32,\n#endif\n#if HAS_LINE_DX || HAS_LINE_DY\n @location($i) aLineDxDy: vec2i,\n#endif\n#ifdef USE_LINE_OFFSET\n @location($i) aExtrudeOffset: vec2f,\n#endif\n#ifdef HAS_LINE_WIDTH\n @location($i) aLineWidth: u32,\n#endif\n#ifndef PICKING_MODE\n #ifndef HAS_GRADIENT\n #ifdef HAS_COLOR\n @location($i) aColor: vec4u,\n #endif\n #ifdef HAS_PATTERN\n #if HAS_PATTERN_ANIM || HAS_PATTERN_GAP\n @location($i) aLinePattern: vec2i,\n #endif\n @location($i) aTexInfo: vec4u,\n #endif\n #ifdef HAS_DASHARRAY\n #ifdef HAS_DASHARRAY_ATTR\n @location($i) aDasharray: vec4u,\n #endif\n #ifdef HAS_DASHARRAY_COLOR\n @location($i) aDashColor: vec4u,\n #endif\n #endif\n #endif\n #ifdef HAS_STROKE_COLOR\n @location($i) aStrokeColor: vec4u,\n #endif\n #ifdef HAS_OPACITY\n @location($i) aOpacity: u32,\n #endif\n #ifdef HAS_GRADIENT\n @location($i) aGradIndex: u32,\n #endif\n#endif\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n#ifndef PICKING_MODE\n @location($o) vNormal: vec2f,\n @location($o) vWidth: vec2f,\n @location($o) vGammaScale: f32,\n#ifndef ENABLE_TILE_STENCIL\n @location($o) vPosition: vec2f,\n#endif\n @location($o) vVertex: vec3f,\n#if HAS_PATTERN || HAS_DASHARRAY || HAS_GRADIENT || HAS_TRAIL\n @location($o) vLinesofar: f32,\n#endif\n #ifndef HAS_GRADIENT\n #ifdef HAS_COLOR\n @location($o) vColor: vec4f,\n #endif\n #ifdef HAS_PATTERN\n #ifdef HAS_PATTERN_ANIM\n @location($o) vLinePatternAnimSpeed: f32,\n #endif\n #ifdef HAS_PATTERN_GAP\n @location($o) vLinePatternGap: f32,\n #endif\n @location($o) vTexInfo: vec4f,\n #endif\n #ifdef HAS_DASHARRAY\n #ifdef HAS_DASHARRAY_ATTR\n @location($o) vDasharray: vec4f,\n #endif\n #ifdef HAS_DASHARRAY_COLOR\n @location($o) vDashColor: vec4f,\n #endif\n #endif\n #endif\n #ifdef HAS_STROKE_COLOR\n @location($o) vStrokeColor: vec4f,\n #endif\n #ifdef HAS_OPACITY\n @location($o) vOpacity: f32,\n #endif\n #ifdef HAS_GRADIENT\n @location($o) vGradIndex: f32,\n #endif\n#else\n#endif\n};\n#ifndef PICKING_MODE\n #if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_vert>\n #endif\n#else\n #include <fbo_picking_vert>\n#endif\n#include <highlight_vert>\n#include <vt_position_vert>\n@vertex\nfn main(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let position = unpackVTPosition(input);\n let round = abs(f32(input.aExtrude.x)) % 2.0;\n let up = abs(f32(input.aExtrude.y)) % 2.0;\n let lineNormal = vec2f(round, up * 2.0 - 1.0);\n #ifndef PICKING_MODE\n output.vNormal = lineNormal;\n #endif\n let pos4 = vec4f(position, 1.0);\n let vertex = uniforms.projViewModelMatrix * uniforms.positionMatrix * pos4;\n #ifndef PICKING_MODE\n if (shaderUniforms.isRenderingTerrain == 1.0) {\n output.vVertex = (uniforms.positionMatrix * pos4).xyz;\n } else {\n output.vVertex = (uniforms.modelMatrix * uniforms.positionMatrix * pos4).xyz;\n }\n #endif\n#ifdef HAS_STROKE_WIDTH\n let strokeWidth = f32(input.aLineStrokeWidth) / 2.0 * shaderUniforms.layerScale;\n#else\n let strokeWidth = uniforms.lineStrokeWidth;\n#endif\n#ifdef HAS_LINE_WIDTH\n let myLineWidth = f32(input.aLineWidth) / 2.0 * shaderUniforms.layerScale;\n#else\n let myLineWidth = uniforms.lineWidth * shaderUniforms.layerScale;\n#endif\n let halfwidth = myLineWidth / 2.0 + strokeWidth;\n let gapwidth = sign(strokeWidth) * myLineWidth / 2.0;\n let inset = gapwidth + sign(gapwidth) * ANTIALIASING;\n var outset = halfwidth + sign(halfwidth) * ANTIALIASING;\n let extrudeXY = vec2f(input.aExtrude.xy);\n let extrude = extrudeXY / EXTRUDE_SCALE;\n var dist = outset * extrude;\n let resScale = uniforms.tileResolution / shaderUniforms.resolution;\n var localVertex = vec4f(position + vec3f(dist, 0.0) * uniforms.tileRatio / resScale, 1.0);\n output.position = uniforms.projViewModelMatrix * uniforms.positionMatrix * localVertex;\n#ifdef HAS_LINE_DX\n let myLineDx = f32(input.aLineDxDy.x);\n#else\n let myLineDx = uniforms.lineDx;\n#endif\n#ifdef HAS_LINE_DY\n let myLineDy = f32(input.aLineDxDy.y);\n#else\n let myLineDy = uniforms.lineDy;\n#endif\n let projDistance = output.position.w;\n output.position.x += f32(myLineDx) * 2.0 / shaderUniforms.canvasSize.x * projDistance;\n output.position.y += f32(myLineDy) * 2.0 / shaderUniforms.canvasSize.y * projDistance;\n#ifndef PICKING_MODE\n output.vWidth = vec2f(outset, inset);\n if (shaderUniforms.isRenderingTerrain == 1.0) {\n output.vGammaScale = 1.0;\n } else {\n output.vGammaScale = projDistance / shaderUniforms.cameraToCenterDistance;\n }\n #ifndef ENABLE_TILE_STENCIL\n output.vPosition = position.xy;\n #ifdef USE_LINE_OFFSET\n output.vPosition += uniforms.tileRatio * offset / EXTRUDE_SCALE;\n #endif\n #endif\n #if HAS_PATTERN || HAS_DASHARRAY || HAS_GRADIENT\n let aLinesofar = f32(input.aLinesofar);\n #ifdef HAS_GRADIENT\n output.vLinesofar = aLinesofar / MAX_LINE_DISTANCE;\n output.vGradIndex = f32(input.aGradIndex);\n #else\n let linesofar = aLinesofar - halfwidth * f32(input.aExtrude.z) / EXTRUDE_SCALE / resScale * uniforms.tileRatio;\n output.vLinesofar = linesofar / uniforms.tileRatio * resScale;\n #endif\n #endif\n #ifndef HAS_GRADIENT\n #ifdef HAS_COLOR\n output.vColor = vec4f(input.aColor);\n #endif\n #ifdef HAS_DASHARRAY\n #ifdef HAS_DASHARRAY_ATTR\n output.vDasharray = vec4f(input.aDasharray);\n #endif\n #ifdef HAS_DASHARRAY_COLOR\n output.vDashColor = vec4f(input.aDashColor) / 255.0;\n #endif\n #endif\n #ifdef HAS_PATTERN\n output.vTexInfo = vec4f(vec2f(input.aTexInfo.xy), vec2f(input.aTexInfo.zw) + 1.0);\n #ifdef HAS_PATTERN_ANIM\n output.vLinePatternAnimSpeed = f32(input.aLinePattern.x) / 127.0;\n #endif\n #ifdef HAS_PATTERN_GAP\n output.vLinePatternGap = f32(input.aLinePattern.y) / 10.0;\n #endif\n #endif\n #endif\n #ifdef HAS_STROKE_COLOR\n output.vStrokeColor = vec4f(input.aStrokeColor);\n #endif\n #ifdef HAS_OPACITY\n output.vOpacity = f32(input.aOpacity) / 255.0;\n #endif\n #if HAS_SHADOWING && !HAS_BLOOM\n shadow_computeShadowPars(localVertex, &output);\n #endif\n #if HAS_HIGHLIGHT_COLOR || HAS_HIGHLIGHT_OPACITY\n highlight_setVarying(input, &output);\n #endif\n#else\n fbo_picking_setData(input, &output, projDistance, true);\n#endif\n return output;\n}";
156
+ var vtLineVert = "#define AA_CLIP_LIMIT 2.0\n#define AA_LINE_WIDTH 16.0\n#define DEVICE_PIXEL_RATIO 1.0\n#define ANTIALIASING 1.0 / 1.0 / 2.0\n#define EXTRUDE_SCALE 63.0\n#define EXTRUDE_MOD 64.0\n#define MAX_LINE_DISTANCE 65535.0\nstruct LineUniforms {\n lineStrokeWidth: f32,\n positionMatrix: mat4x4f,\n projViewModelMatrix: mat4x4f,\n modelMatrix: mat4x4f,\n tileResolution: f32,\n tileRatio: f32,\n lineDx: f32,\n lineDy: f32,\n lineWidth: f32\n};\nstruct ShaderUniforms {\n resolution: f32,\n cameraToCenterDistance: f32,\n canvasSize: vec2f,\n layerScale: f32,\n isRenderingTerrain: f32,\n}\n@group(0) @binding($b) var<uniform> uniforms: LineUniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\nstruct VertexInput {\n#ifdef HAS_ALTITUDE\n @location($i) aPosition: POSITION_TYPE_2,\n @location($i) aAltitude: f32,\n#else\n @location($i) aPosition: POSITION_TYPE_3,\n#endif\n#if HAS_PATTERN || HAS_DASHARRAY\n @location($i) aExtrude: vec4i,\n#else\n @location($i) aExtrude: vec2i,\n#endif\n#if HAS_PATTERN || HAS_DASHARRAY || HAS_GRADIENT || HAS_TRAIL\n @location($i) aLinesofar: LINESOFAR_TYPE,\n#endif\n#ifdef HAS_STROKE_WIDTH\n @location($i) aLineStrokeWidth: u32,\n#endif\n#if HAS_LINE_DX || HAS_LINE_DY\n @location($i) aLineDxDy: vec2i,\n#endif\n#ifdef USE_LINE_OFFSET\n @location($i) aExtrudeOffset: vec2f,\n#endif\n#ifdef HAS_LINE_WIDTH\n @location($i) aLineWidth: u32,\n#endif\n#ifndef PICKING_MODE\n #ifndef HAS_GRADIENT\n #ifdef HAS_COLOR\n @location($i) aColor: vec4u,\n #endif\n #ifdef HAS_PATTERN\n #if HAS_PATTERN_ANIM || HAS_PATTERN_GAP\n @location($i) aLinePattern: vec2i,\n #endif\n @location($i) aTexInfo: vec4u,\n #endif\n #ifdef HAS_DASHARRAY\n #ifdef HAS_DASHARRAY_ATTR\n @location($i) aDasharray: vec4u,\n #endif\n #ifdef HAS_DASHARRAY_COLOR\n @location($i) aDashColor: vec4u,\n #endif\n #endif\n #endif\n #ifdef HAS_STROKE_COLOR\n @location($i) aStrokeColor: vec4u,\n #endif\n #ifdef HAS_OPACITY\n @location($i) aOpacity: u32,\n #endif\n #ifdef HAS_GRADIENT\n @location($i) aGradIndex: u32,\n #endif\n#endif\n};\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n#ifndef PICKING_MODE\n @location($o) vNormal: vec2f,\n @location($o) vWidth: vec2f,\n @location($o) vGammaScale: f32,\n#ifndef ENABLE_TILE_STENCIL\n @location($o) vPosition: vec2f,\n#endif\n @location($o) vVertex: vec3f,\n#if HAS_PATTERN || HAS_DASHARRAY || HAS_GRADIENT || HAS_TRAIL\n @location($o) vLinesofar: f32,\n#endif\n #ifndef HAS_GRADIENT\n #ifdef HAS_COLOR\n @location($o) vColor: vec4f,\n #endif\n #ifdef HAS_PATTERN\n #ifdef HAS_PATTERN_ANIM\n @location($o) vLinePatternAnimSpeed: f32,\n #endif\n #ifdef HAS_PATTERN_GAP\n @location($o) vLinePatternGap: f32,\n #endif\n @location($o) vTexInfo: vec4f,\n #endif\n #ifdef HAS_DASHARRAY\n #ifdef HAS_DASHARRAY_ATTR\n @location($o) vDasharray: vec4f,\n #endif\n #ifdef HAS_DASHARRAY_COLOR\n @location($o) vDashColor: vec4f,\n #endif\n #endif\n #endif\n #ifdef HAS_STROKE_COLOR\n @location($o) vStrokeColor: vec4f,\n #endif\n #ifdef HAS_OPACITY\n @location($o) vOpacity: f32,\n #endif\n #ifdef HAS_GRADIENT\n @location($o) vGradIndex: f32,\n #endif\n#else\n#endif\n};\n#ifndef PICKING_MODE\n #if HAS_SHADOWING && !HAS_BLOOM\n #include <vsm_shadow_vert>\n #endif\n#else\n #include <fbo_picking_vert>\n#endif\n#include <highlight_vert>\n#include <vt_position_vert>\n@vertex\nfn main(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let position = unpackVTPosition(input);\n let round = abs(f32(input.aExtrude.x)) % 2.0;\n let up = abs(f32(input.aExtrude.y)) % 2.0;\n let lineNormal = vec2f(round, up * 2.0 - 1.0);\n #ifndef PICKING_MODE\n output.vNormal = lineNormal;\n #endif\n let pos4 = vec4f(position, 1.0);\n let vertex = uniforms.projViewModelMatrix * uniforms.positionMatrix * pos4;\n #ifndef PICKING_MODE\n if (shaderUniforms.isRenderingTerrain == 1.0) {\n output.vVertex = (uniforms.positionMatrix * pos4).xyz;\n } else {\n output.vVertex = (uniforms.modelMatrix * uniforms.positionMatrix * pos4).xyz;\n }\n #endif\n let groundVertex = uniforms.projViewModelMatrix * uniforms.positionMatrix * vec4f(position.xy, 0.0, 1.0);\n let depthRatio = vertex.w / groundVertex.w;\n#ifdef HAS_STROKE_WIDTH\n let strokeWidth = f32(input.aLineStrokeWidth) / 2.0 * shaderUniforms.layerScale;\n#else\n let strokeWidth = uniforms.lineStrokeWidth;\n#endif\n#ifdef HAS_LINE_WIDTH\n let myLineWidth = f32(input.aLineWidth) / 2.0 * shaderUniforms.layerScale;\n#else\n let myLineWidth = uniforms.lineWidth * shaderUniforms.layerScale;\n#endif\n let halfwidth = myLineWidth / 2.0 + strokeWidth;\n let gapwidth = sign(strokeWidth) * myLineWidth / 2.0;\n let inset = gapwidth + sign(gapwidth) * ANTIALIASING;\n var outset = halfwidth + sign(halfwidth) * ANTIALIASING;\n let extrudeXY = vec2f(input.aExtrude.xy);\n let extrude = extrudeXY / EXTRUDE_SCALE;\n var dist = outset * extrude;\n dist *= depthRatio;\n let resScale = uniforms.tileResolution / shaderUniforms.resolution;\n var localVertex = vec4f(position + vec3f(dist, 0.0) * uniforms.tileRatio / resScale, 1.0);\n output.position = uniforms.projViewModelMatrix * uniforms.positionMatrix * localVertex;\n#ifdef HAS_LINE_DX\n let myLineDx = f32(input.aLineDxDy.x);\n#else\n let myLineDx = uniforms.lineDx;\n#endif\n#ifdef HAS_LINE_DY\n let myLineDy = f32(input.aLineDxDy.y);\n#else\n let myLineDy = uniforms.lineDy;\n#endif\n let projDistance = output.position.w;\n output.position.x += f32(myLineDx) * 2.0 / shaderUniforms.canvasSize.x * projDistance;\n output.position.y += f32(myLineDy) * 2.0 / shaderUniforms.canvasSize.y * projDistance;\n#ifndef PICKING_MODE\n output.vWidth = vec2f(outset * depthRatio, inset * depthRatio);\n if (shaderUniforms.isRenderingTerrain == 1.0) {\n output.vGammaScale = 1.0;\n } else {\n output.vGammaScale = projDistance / shaderUniforms.cameraToCenterDistance;\n }\n #ifndef ENABLE_TILE_STENCIL\n output.vPosition = position.xy;\n #ifdef USE_LINE_OFFSET\n output.vPosition += uniforms.tileRatio * offset / EXTRUDE_SCALE;\n #endif\n #endif\n #if HAS_PATTERN || HAS_DASHARRAY || HAS_GRADIENT\n let aLinesofar = f32(input.aLinesofar);\n #ifdef HAS_GRADIENT\n output.vLinesofar = aLinesofar / MAX_LINE_DISTANCE;\n output.vGradIndex = f32(input.aGradIndex);\n #else\n let linesofar = aLinesofar - halfwidth * f32(input.aExtrude.z) / EXTRUDE_SCALE / resScale * uniforms.tileRatio;\n output.vLinesofar = linesofar / uniforms.tileRatio * resScale;\n #endif\n #endif\n #ifndef HAS_GRADIENT\n #ifdef HAS_COLOR\n output.vColor = vec4f(input.aColor);\n #endif\n #ifdef HAS_DASHARRAY\n #ifdef HAS_DASHARRAY_ATTR\n output.vDasharray = vec4f(input.aDasharray);\n #endif\n #ifdef HAS_DASHARRAY_COLOR\n output.vDashColor = vec4f(input.aDashColor) / 255.0;\n #endif\n #endif\n #ifdef HAS_PATTERN\n output.vTexInfo = vec4f(vec2f(input.aTexInfo.xy), vec2f(input.aTexInfo.zw) + 1.0);\n #ifdef HAS_PATTERN_ANIM\n output.vLinePatternAnimSpeed = f32(input.aLinePattern.x) / 127.0;\n #endif\n #ifdef HAS_PATTERN_GAP\n output.vLinePatternGap = f32(input.aLinePattern.y) / 10.0;\n #endif\n #endif\n #endif\n #ifdef HAS_STROKE_COLOR\n output.vStrokeColor = vec4f(input.aStrokeColor);\n #endif\n #ifdef HAS_OPACITY\n output.vOpacity = f32(input.aOpacity) / 255.0;\n #endif\n #if HAS_SHADOWING && !HAS_BLOOM\n shadow_computeShadowPars(localVertex, &output);\n #endif\n #if HAS_HIGHLIGHT_COLOR || HAS_HIGHLIGHT_OPACITY\n highlight_setVarying(input, &output);\n #endif\n#else\n fbo_picking_setData(input, &output, projDistance, true);\n#endif\n return output;\n}";
153
157
 
154
158
  var vtMarkerFrag = "struct MarkerFragUniforms {\n alphaTest: f32,\n markerOpacity: f32\n};\nstruct ShaderUniforms {\n layerOpacity: f32\n}\n@group(0) @binding($b) var<uniform> uniforms: MarkerFragUniforms;\n@group(0) @binding($b) var<uniform> shaderUniforms: ShaderUniforms;\n@group(0) @binding($b) var iconTex: texture_2d<f32>;\n@group(0) @binding($b) var iconTexSampler: sampler;\n#include <highlight_frag>\n#include <text_render_frag>\n@fragment\nfn main(input: VertexOutput) -> @location(0) vec4f {\n var fragColor: vec4f;\n let isText = input.vIsText > 0.5;\n let textColor = renderText(input);\n let iconColor = textureSample(iconTex, iconTexSampler, input.vTexCoord) * uniforms.markerOpacity;\n if (isText) {\n fragColor = textColor;\n } else {\n fragColor = iconColor;\n }\n fragColor = fragColor * input.vOpacity * shaderUniforms.layerOpacity;\n if (fragColor.a < 0.05) {\n discard;\n }\n var color: vec4f;\n color = fragColor;\n if (color.a < uniforms.alphaTest) {\n discard;\n }\n #if HAS_HIGHLIGHT_OPACITY || HAS_HIGHLIGHT_COLOR\n return highlight_blendColor(color, input);\n #else\n return color;\n #endif\n}";
155
159
 
@@ -232,6 +236,9 @@ registerWGSLSource('gl_fog_mixFactor_vert', glFogMixFactorVert);
232
236
  registerWGSLSource('gl_fog_mixFactor_frag', glFogMixFactorFrag);
233
237
 
234
238
  registerWGSLSource('layer_3dtiles_picking_vert', layer3dtilesPickingVert);
239
+ registerWGSLSource('layer_3dtiles_pnts_vert', layer3dtilesPntsVert);
240
+ registerWGSLSource('layer_3dtiles_pnts_frag', layer3dtilesPntsFrag);
241
+
235
242
  registerWGSLSource('layer_video_video_frag', layerVideoVideoFrag);
236
243
  registerWGSLSource('layer_video_video_vert', layerVideoVideoVert);
237
244
 
@@ -259,4 +266,4 @@ registerWGSLSource('vt_tube_vert', vtTubeVert);
259
266
  registerWGSLSource('vt_flat_mask_frag', vtFlatMaskFrag);
260
267
  registerWGSLSource('vt_flat_mask_vert', vtFlatMaskVert);
261
268
 
262
- typeof console !== 'undefined' && console.log('@maptalks/gpu v0.124.4');
269
+ typeof console !== 'undefined' && console.log('@maptalks/gpu v0.125.0');