@babylonjs/lite 1.9.0 → 1.10.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.
- package/CHANGELOG.md +26 -0
- package/dist/index.js +596 -526
- package/dist/index.js.map +1 -1
- package/index.d.ts +107 -4
- package/lib/engine/engine.js +1 -1
- package/lib/engine/engine.js.map +1 -1
- package/lib/frame-graph/render-task.js +6 -4
- package/lib/frame-graph/render-task.js.map +1 -1
- package/lib/index.js +4 -1
- package/lib/index.js.map +1 -1
- package/lib/loader-gltf/gltf-ext-quantization.js +4 -1
- package/lib/loader-gltf/gltf-ext-quantization.js.map +1 -1
- package/lib/loader-gltf/gltf-feature-registry.js +11 -1
- package/lib/loader-gltf/gltf-feature-registry.js.map +1 -1
- package/lib/loader-gltf/gltf-feature-variants.js +11 -1
- package/lib/loader-gltf/gltf-feature-variants.js.map +1 -1
- package/lib/loader-gltf/gltf-json-asset.js +8 -1
- package/lib/loader-gltf/gltf-json-asset.js.map +1 -1
- package/lib/loader-gltf/gltf-material.js +4 -29
- package/lib/loader-gltf/gltf-material.js.map +1 -1
- package/lib/loader-gltf/gltf-parser.js +1 -8
- package/lib/loader-gltf/gltf-parser.js.map +1 -1
- package/lib/loader-gltf/gltf-pbr-builder.js +1 -15
- package/lib/loader-gltf/gltf-pbr-builder.js.map +1 -1
- package/lib/loader-gltf/gltf-variants.js +5 -10
- package/lib/loader-gltf/gltf-variants.js.map +1 -1
- package/lib/loader-gltf/load-gltf.js +19 -29
- package/lib/loader-gltf/load-gltf.js.map +1 -1
- package/lib/material/pbr/background-dds-skybox.js +35 -93
- package/lib/material/pbr/background-dds-skybox.js.map +1 -1
- package/lib/material/pbr/background-ground.js +13 -18
- package/lib/material/pbr/background-ground.js.map +1 -1
- package/lib/material/pbr/background-hdr-skybox.js +35 -93
- package/lib/material/pbr/background-hdr-skybox.js.map +1 -1
- package/lib/material/pbr/background-solid-skybox.js +35 -93
- package/lib/material/pbr/background-solid-skybox.js.map +1 -1
- package/lib/material/pbr/fragments/clearcoat-fragment.js +5 -1
- package/lib/material/pbr/fragments/clearcoat-fragment.js.map +1 -1
- package/lib/material/pbr/fragments/iridescence-fragment.js +4 -1
- package/lib/material/pbr/fragments/iridescence-fragment.js.map +1 -1
- package/lib/material/pbr/fragments/refraction-rtt-fragment.js +7 -2
- package/lib/material/pbr/fragments/refraction-rtt-fragment.js.map +1 -1
- package/lib/material/pbr/fragments/sheen-fragment.js +2 -1
- package/lib/material/pbr/fragments/sheen-fragment.js.map +1 -1
- package/lib/material/pbr/fragments/subsurface-fragment.js +2 -1
- package/lib/material/pbr/fragments/subsurface-fragment.js.map +1 -1
- package/lib/material/pbr/fragments/unlit-fragment.js +1 -2
- package/lib/material/pbr/fragments/unlit-fragment.js.map +1 -1
- package/lib/material/pbr/pbr-compose.js +2 -0
- package/lib/material/pbr/pbr-compose.js.map +1 -1
- package/lib/material/pbr/pbr-flag-bits.js +1 -16
- package/lib/material/pbr/pbr-flag-bits.js.map +1 -1
- package/lib/material/pbr/pbr-flags.js +1 -1
- package/lib/material/pbr/pbr-fog-wgsl.js +1 -1
- package/lib/material/pbr/pbr-fog-wgsl.js.map +1 -1
- package/lib/material/pbr/pbr-geometry-output-shader.js +2 -1
- package/lib/material/pbr/pbr-geometry-output-shader.js.map +1 -1
- package/lib/material/pbr/pbr-geometry-view.js +2 -1
- package/lib/material/pbr/pbr-geometry-view.js.map +1 -1
- package/lib/material/pbr/pbr-renderable.js +4 -0
- package/lib/material/pbr/pbr-renderable.js.map +1 -1
- package/lib/material/pbr/pbr-template-gamma.js +7 -0
- package/lib/material/pbr/pbr-template-gamma.js.map +1 -0
- package/lib/material/pbr/pbr-template.js +2 -2
- package/lib/material/pbr/pbr-template.js.map +1 -1
- package/lib/material/standard/skybox-cubemap.js +1 -1
- package/lib/material/standard/skybox-cubemap.js.map +1 -1
- package/lib/material/standard/standard-template.js +1 -1
- package/lib/material/standard/standard-template.js.map +1 -1
- package/lib/mesh/GaussianSplatting/gaussian-splatting-pipeline-sh.js +3 -5
- package/lib/mesh/GaussianSplatting/gaussian-splatting-pipeline-sh.js.map +1 -1
- package/lib/mesh/GaussianSplatting/gaussian-splatting-pipeline.js +3 -5
- package/lib/mesh/GaussianSplatting/gaussian-splatting-pipeline.js.map +1 -1
- package/lib/particle/node/blocks/particle-condition-block.js +55 -0
- package/lib/particle/node/blocks/particle-condition-block.js.map +1 -0
- package/lib/particle/node/blocks/particle-float-to-int-block.js +28 -0
- package/lib/particle/node/blocks/particle-float-to-int-block.js.map +1 -0
- package/lib/particle/node/blocks/particle-gradient-block.js +32 -0
- package/lib/particle/node/blocks/particle-gradient-block.js.map +1 -0
- package/lib/particle/node/blocks/particle-gradient-value-block.js +11 -0
- package/lib/particle/node/blocks/particle-gradient-value-block.js.map +1 -0
- package/lib/particle/node/blocks/particle-lerp-block.js +2 -24
- package/lib/particle/node/blocks/particle-lerp-block.js.map +1 -1
- package/lib/particle/node/blocks/particle-lerp.js +27 -0
- package/lib/particle/node/blocks/particle-lerp.js.map +1 -0
- package/lib/particle/node/blocks/particle-vector-length-block.js +30 -0
- package/lib/particle/node/blocks/particle-vector-length-block.js.map +1 -0
- package/lib/particle/node/blocks/system-block.js +13 -3
- package/lib/particle/node/blocks/system-block.js.map +1 -1
- package/lib/particle/node/blocks/texture-source-block.js +2 -1
- package/lib/particle/node/blocks/texture-source-block.js.map +1 -1
- package/lib/particle/node/blocks/update-size-block.js +19 -0
- package/lib/particle/node/blocks/update-size-block.js.map +1 -0
- package/lib/particle/node/npe-build-state.js +10 -0
- package/lib/particle/node/npe-build-state.js.map +1 -1
- package/lib/particle/node/npe-registry.js +12 -0
- package/lib/particle/node/npe-registry.js.map +1 -1
- package/lib/particle/particle-system.js +7 -2
- package/lib/particle/particle-system.js.map +1 -1
- package/lib/picking/billboard-pick-pipeline.js +269 -0
- package/lib/picking/billboard-pick-pipeline.js.map +1 -0
- package/lib/picking/gpu-picker.js +37 -37
- package/lib/picking/gpu-picker.js.map +1 -1
- package/lib/picking/gs-picking-pipeline.js +26 -1
- package/lib/picking/gs-picking-pipeline.js.map +1 -1
- package/lib/picking/pick-contributor.js +13 -0
- package/lib/picking/pick-contributor.js.map +1 -0
- package/lib/picking/picking-info.js.map +1 -1
- package/lib/scene/scene-core.js +2 -2
- package/lib/scene/scene-core.js.map +1 -1
- package/lib/shader/wgsl-fog.js +18 -0
- package/lib/shader/wgsl-fog.js.map +1 -0
- package/lib/shader/wgsl-helpers.js +1 -16
- package/lib/shader/wgsl-helpers.js.map +1 -1
- package/lib/sprite/billboard-scene.js +2 -0
- package/lib/sprite/billboard-scene.js.map +1 -1
- package/lib/sprite/picking/pick-billboard.js +16 -0
- package/lib/sprite/picking/pick-billboard.js.map +1 -0
- package/lib/sprite/picking/pick-sprite-2d.js +41 -0
- package/lib/sprite/picking/pick-sprite-2d.js.map +1 -0
- package/lib/sprite/shared/sprite-atlas.js +4 -1
- package/lib/sprite/shared/sprite-atlas.js.map +1 -1
- package/lib/sprite/sprite-2d.js.map +1 -1
- package/lib/sprite/sprite-pipeline.js +18 -1
- package/lib/sprite/sprite-pipeline.js.map +1 -1
- package/lib/sprite/sprite-renderer.js +12 -6
- package/lib/sprite/sprite-renderer.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"background-hdr-skybox.js","sources":["../../../../shaders/skybox-hdr.fragment.wgsl?raw","../../../../src/material/pbr/background-hdr-skybox.ts"],"sourcesContent":["export default \"// HDR Skybox Fragment Shader — samples HDR environment cubemap with image processing.\\n// Used when scene has an HDR environment rendered as the background.\\n// Matches BJS BackgroundMaterial: cubemap at LOD 0 + exposure + gamma + contrast.\\n\\nstruct MeshUniforms {\\n world: mat4x4<f32>,\\n primaryColor: vec3<f32>,\\n _pad: f32,\\n skyOutputColor: vec3<f32>,\\n _pad2: f32,\\n exposureLinear: f32,\\n contrast: f32,\\n _pad3: f32,\\n _pad4: f32,\\n};\\n\\n@group(1) @binding(0) var<uniform> mesh: MeshUniforms;\\n@group(1) @binding(1) var envCubemap: texture_cube<f32>;\\n@group(1) @binding(2) var envSampler: sampler;\\n\\nstruct FragmentInput {\\n @location(0) positionUVW: vec3<f32>,\\n @location(1) positionW: vec3<f32>,\\n};\\n\\n@fragment\\nfn main(input: FragmentInput) -> @location(0) vec4<f32> {\\n let dir = normalize(input.positionUVW);\\n var color = textureSampleLevel(envCubemap, envSampler, dir, 0.0).rgb;\\n\\n // Image processing: exposure → gamma → contrast (matches BJS applyImageProcessing)\\n color *= mesh.exposureLinear;\\n color = pow(color, vec3<f32>(1.0 / 2.2));\\n color = clamp(color, vec3<f32>(0.0), vec3<f32>(1.0));\\n\\n let highContrast = color * color * (3.0 - 2.0 * color);\\n if (mesh.contrast < 1.0) { color = mix(vec3<f32>(0.5), color, mesh.contrast); }\\n else { color = mix(color, highContrast, mesh.contrast - 1.0); }\\n color = max(color, vec3<f32>(0.0));\\n\\n return vec4<f32>(color, 1.0);\\n}\\n\"","/** HDR cubemap skybox — lazy-loaded only when useCubemapSkybox is true.\n * Contains the HDR skybox material, shader, UBO, and skybox geometry.\n * Self-contained: computes scene bounds and builds a full Renderable.\n * Tree-shaken away from scenes that use the default solid-color skybox. */\n\nimport { F32, U16 } from \"../../engine/typed-arrays.js\";\nimport { BU } from \"../../engine/gpu-flags.js\";\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { EnvironmentTextures } from \"../../loader-env/load-env.js\";\n// Mat4 import removed: local world matrices stored as Float32Array.\nimport type { Renderable } from \"../../render/renderable.js\";\nimport { createCubemapSkyboxMaterial } from \"./cubemap-skybox-material.js\";\nimport skyboxVertSrc from \"../../../shaders/skybox.vertex.wgsl?raw\";\nimport skyboxHdrFragSrc from \"../../../shaders/skybox-hdr.fragment.wgsl?raw\";\nimport { SCENE_UBO_WGSL } from \"../../shader/scene-uniforms.js\";\nimport { createMappedBuffer, createUniformBuffer } from \"../../resource/gpu-buffers.js\";\n\nconst SKY_HDR_UNIFORM_SIZE = 112; // mat4x4 + primaryColor vec3 + pad + skyOutputColor vec3 + pad + exposure + contrast + pad2\n\nfunction createSkyboxBuffers(engine: EngineContext, S: number): { posBuffer: GPUBuffer; idxBuffer: GPUBuffer; idxCount: number } {\n // prettier-ignore\n const positions = new F32([\n S,-S, S, -S,-S, S, -S, S, S, S, S, S,\n S, S,-S, -S, S,-S, -S,-S,-S, S,-S,-S,\n S, S,-S, S,-S,-S, S,-S, S, S, S, S,\n -S, S, S, -S,-S, S, -S,-S,-S, -S, S,-S,\n -S, S, S, -S, S,-S, S, S,-S, S, S, S,\n S,-S, S, S,-S,-S, -S,-S,-S, -S,-S, S,\n ]);\n // prettier-ignore\n const indices = new U16([\n 2, 1, 0, 3, 2, 0, 6, 5, 4, 7, 6, 4,\n 10, 9, 8, 11,10, 8, 14,13,12, 15,14,12,\n 18,17,16, 19,18,16, 22,21,20, 23,22,20,\n ]);\n return {\n posBuffer: createMappedBuffer(engine, positions, BU.VERTEX),\n idxBuffer: createMappedBuffer(engine, indices, BU.INDEX),\n idxCount: 36,\n };\n}\n\nfunction buildSkyboxWorldMatrix(rootPosition: [number, number, number]): Float32Array {\n const world = new F32(16);\n world[0] = 1;\n world[5] = 1;\n world[10] = 1;\n world[15] = 1;\n world[12] = rootPosition[0];\n world[13] = rootPosition[1];\n world[14] = rootPosition[2];\n return world;\n}\n\n/** Build an HDR cubemap skybox as a complete Renderable (order 0). */\nexport function buildHdrSkyboxRenderable(\n scene: SceneContext,\n envTextures: EnvironmentTextures,\n skyHalfSize: number,\n rootPosition: [number, number, number],\n primaryColor: [number, number, number]\n): Renderable {\n const engine = scene.surface.engine;\n\n const skyboxWorld = buildSkyboxWorldMatrix(rootPosition);\n\n const cc = scene.clearColor;\n\n const skyBufs = createSkyboxBuffers(engine, skyHalfSize);\n const mat = createCubemapSkyboxMaterial(\"skybox-hdr\", SCENE_UBO_WGSL + skyboxVertSrc, skyboxHdrFragSrc);\n const ubo = createSkyHdrMeshUBO(engine, skyboxWorld, primaryColor, [cc.r, cc.g, cc.b], scene.imageProcessing.exposure, scene.imageProcessing.contrast);\n\n const bindGroup = mat.createBindGroup(engine, ubo, envTextures.specularCubeView!, envTextures.cubeSampler);\n\n const r: Renderable = {\n order: 0,\n isTransparent: false,\n bind(eng, sig) {\n return {\n renderable: r,\n pipeline: mat.getPipeline(eng as EngineContext, sig),\n draw(pass) {\n pass.setBindGroup(1, bindGroup);\n pass.setVertexBuffer(0, skyBufs.posBuffer);\n pass.setIndexBuffer(skyBufs.idxBuffer, \"uint16\");\n pass.drawIndexed(skyBufs.idxCount);\n return 1;\n },\n };\n },\n };\n return r;\n}\n\n// ─── HDR Skybox UBO ─────────────────────────────────────────────────────────────\n\nfunction createSkyHdrMeshUBO(\n engine: EngineContext,\n world: Float32Array,\n primaryColor: [number, number, number],\n skyOutputColor: [number, number, number],\n exposure: number,\n contrast: number\n): GPUBuffer {\n const data = new F32(SKY_HDR_UNIFORM_SIZE / 4);\n data.set(world, 0);\n data[16] = primaryColor[0];\n data[17] = primaryColor[1];\n data[18] = primaryColor[2];\n data[20] = skyOutputColor[0];\n data[21] = skyOutputColor[1];\n data[22] = skyOutputColor[2];\n data[24] = exposure; // exposureLinear\n data[25] = contrast; // contrast\n return createUniformBuffer(engine, data);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"background-hdr-skybox.js","sources":["../../../../shaders/skybox-hdr.fragment.wgsl?raw","../../../../src/material/pbr/background-hdr-skybox.ts"],"sourcesContent":["export default \"// HDR Skybox Fragment Shader — samples HDR environment cubemap with image processing.\\n// Used when scene has an HDR environment rendered as the background.\\n// Matches BJS BackgroundMaterial: cubemap at LOD 0 + exposure + gamma + contrast.\\n\\nstruct MeshUniforms {\\n world: mat4x4<f32>,\\n primaryColor: vec3<f32>,\\n _pad: f32,\\n skyOutputColor: vec3<f32>,\\n _pad2: f32,\\n exposureLinear: f32,\\n contrast: f32,\\n _pad3: f32,\\n _pad4: f32,\\n};\\n\\n@group(1) @binding(0) var<uniform> mesh: MeshUniforms;\\n@group(1) @binding(1) var envCubemap: texture_cube<f32>;\\n@group(1) @binding(2) var envSampler: sampler;\\n\\nstruct FragmentInput {\\n @location(0) positionUVW: vec3<f32>,\\n @location(1) positionW: vec3<f32>,\\n};\\n\\n@fragment\\nfn main(input: FragmentInput) -> @location(0) vec4<f32> {\\n let dir = normalize(input.positionUVW);\\n var color = textureSampleLevel(envCubemap, envSampler, dir, 0.0).rgb;\\n\\n // Image processing: exposure → gamma → contrast (matches BJS applyImageProcessing)\\n color *= mesh.exposureLinear;\\n color = pow(color, vec3<f32>(1.0 / 2.2));\\n color = clamp(color, vec3<f32>(0.0), vec3<f32>(1.0));\\n\\n let highContrast = color * color * (3.0 - 2.0 * color);\\n if (mesh.contrast < 1.0) { color = mix(vec3<f32>(0.5), color, mesh.contrast); }\\n else { color = mix(color, highContrast, mesh.contrast - 1.0); }\\n color = max(color, vec3<f32>(0.0));\\n\\n return vec4<f32>(color, 1.0);\\n}\\n\"","/** HDR cubemap skybox — lazy-loaded only when useCubemapSkybox is true.\n * Contains the HDR skybox material, shader, UBO, and skybox geometry.\n * Self-contained: computes scene bounds and builds a full Renderable.\n * Tree-shaken away from scenes that use the default solid-color skybox. */\n\nimport { F32, U16 } from \"../../engine/typed-arrays.js\";\nimport { BU } from \"../../engine/gpu-flags.js\";\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { EnvironmentTextures } from \"../../loader-env/load-env.js\";\nimport type { Renderable } from \"../../render/renderable.js\";\nimport { createCubemapSkyboxMaterial } from \"./cubemap-skybox-material.js\";\nimport skyboxVertSrc from \"../../../shaders/skybox.vertex.wgsl?raw\";\nimport skyboxHdrFragSrc from \"../../../shaders/skybox-hdr.fragment.wgsl?raw\";\nimport { SCENE_UBO_WGSL } from \"../../shader/scene-uniforms.js\";\nimport { createMappedBuffer, createUniformBuffer } from \"../../resource/gpu-buffers.js\";\n\nconst SKY_HDR_UNIFORM_SIZE = 112; // mat4x4 + primaryColor vec3 + pad + skyOutputColor vec3 + pad + exposure + contrast + pad2\n\nfunction createSkyboxBuffers(engine: EngineContext, S: number): { posBuffer: GPUBuffer; idxBuffer: GPUBuffer } {\n // prettier-ignore\n const positions = new F32([\n -S,-S,-S, S,-S,-S, -S, S,-S, S, S,-S,\n -S,-S, S, S,-S, S, -S, S, S, S, S, S,\n ]);\n // prettier-ignore\n const indices = new U16([\n 6,4,5, 7,6,5, 0,2,3, 1,0,3,\n 5,1,3, 7,5,3, 0,4,6, 2,0,6,\n 3,2,6, 7,3,6, 0,1,5, 4,0,5,\n ]);\n return {\n posBuffer: createMappedBuffer(engine, positions, BU.VERTEX),\n idxBuffer: createMappedBuffer(engine, indices, BU.INDEX),\n };\n}\n\n/** Build an HDR cubemap skybox as a complete Renderable (order 0). */\nexport function buildHdrSkyboxRenderable(\n scene: SceneContext,\n envTextures: EnvironmentTextures,\n skyHalfSize: number,\n rootPosition: [number, number, number],\n primaryColor: [number, number, number]\n): Renderable {\n const engine = scene.surface.engine;\n\n const cc = scene.clearColor;\n\n const skyBufs = createSkyboxBuffers(engine, skyHalfSize);\n const mat = createCubemapSkyboxMaterial(\"skybox-hdr\", SCENE_UBO_WGSL + skyboxVertSrc, skyboxHdrFragSrc);\n const ubo = createSkyHdrMeshUBO(engine, rootPosition, primaryColor, [cc.r, cc.g, cc.b], scene.imageProcessing.exposure, scene.imageProcessing.contrast);\n\n const bindGroup = mat.createBindGroup(engine, ubo, envTextures.specularCubeView!, envTextures.cubeSampler);\n\n const r: Renderable = {\n order: 0,\n isTransparent: false,\n bind(eng, sig) {\n return {\n renderable: r,\n pipeline: mat.getPipeline(eng as EngineContext, sig),\n draw(pass) {\n pass.setBindGroup(1, bindGroup);\n pass.setVertexBuffer(0, skyBufs.posBuffer);\n pass.setIndexBuffer(skyBufs.idxBuffer, \"uint16\");\n pass.drawIndexed(36);\n return 1;\n },\n };\n },\n };\n return r;\n}\n\n// ─── HDR Skybox UBO ─────────────────────────────────────────────────────────────\n\nfunction createSkyHdrMeshUBO(\n engine: EngineContext,\n rootPosition: [number, number, number],\n primaryColor: [number, number, number],\n skyOutputColor: [number, number, number],\n exposure: number,\n contrast: number\n): GPUBuffer {\n const data = new F32(SKY_HDR_UNIFORM_SIZE / 4);\n data[0] = data[5] = data[10] = data[15] = 1;\n data[12] = rootPosition[0];\n data[13] = rootPosition[1];\n data[14] = rootPosition[2];\n data[16] = primaryColor[0];\n data[17] = primaryColor[1];\n data[18] = primaryColor[2];\n data[20] = skyOutputColor[0];\n data[21] = skyOutputColor[1];\n data[22] = skyOutputColor[2];\n data[24] = exposure; // exposureLinear\n data[25] = contrast; // contrast\n return createUniformBuffer(engine, data);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { U16, F32 } from '../../engine/typed-arrays.js';
|
|
2
2
|
import { BU, SS } from '../../engine/gpu-flags.js';
|
|
3
3
|
import { s as skyboxVertSrc } from '../../_chunks/skybox.vertex-Ban7q6IM.js';
|
|
4
4
|
import { createDefaultPipelineDescriptor, getSceneBindGroupLayout } from '../../render/scene-helpers.js';
|
|
@@ -13,134 +13,74 @@ const skyboxFragSrc = "struct c{world:mat4x4<f32>,primaryColor:vec3<f32>,_pad:f3
|
|
|
13
13
|
const SKY_MESH_UNIFORM_SIZE = 96;
|
|
14
14
|
function createSkyboxBuffers(engine, S) {
|
|
15
15
|
const positions = new F32([
|
|
16
|
-
S,
|
|
17
|
-
-S,
|
|
18
|
-
S,
|
|
19
|
-
-S,
|
|
20
|
-
-S,
|
|
21
|
-
S,
|
|
22
|
-
-S,
|
|
23
|
-
S,
|
|
24
|
-
S,
|
|
25
|
-
S,
|
|
26
|
-
S,
|
|
27
|
-
S,
|
|
28
|
-
S,
|
|
29
|
-
S,
|
|
30
|
-
-S,
|
|
31
|
-
-S,
|
|
32
|
-
S,
|
|
33
|
-
-S,
|
|
34
|
-
-S,
|
|
35
16
|
-S,
|
|
36
17
|
-S,
|
|
37
|
-
S,
|
|
38
|
-
-S,
|
|
39
18
|
-S,
|
|
40
19
|
S,
|
|
41
|
-
S,
|
|
42
20
|
-S,
|
|
43
|
-
S,
|
|
44
21
|
-S,
|
|
45
22
|
-S,
|
|
46
23
|
S,
|
|
47
24
|
-S,
|
|
48
25
|
S,
|
|
49
26
|
S,
|
|
50
|
-
S,
|
|
51
|
-
S,
|
|
52
27
|
-S,
|
|
53
|
-
S,
|
|
54
|
-
S,
|
|
55
28
|
-S,
|
|
56
29
|
-S,
|
|
57
30
|
S,
|
|
58
|
-
-S,
|
|
59
|
-
-S,
|
|
60
|
-
-S,
|
|
61
|
-
-S,
|
|
62
31
|
S,
|
|
63
32
|
-S,
|
|
64
|
-
-S,
|
|
65
|
-
S,
|
|
66
|
-
S,
|
|
67
|
-
-S,
|
|
68
|
-
S,
|
|
69
|
-
-S,
|
|
70
|
-
S,
|
|
71
33
|
S,
|
|
72
34
|
-S,
|
|
73
35
|
S,
|
|
74
36
|
S,
|
|
75
37
|
S,
|
|
76
38
|
S,
|
|
77
|
-
-S,
|
|
78
|
-
S,
|
|
79
|
-
S,
|
|
80
|
-
-S,
|
|
81
|
-
-S,
|
|
82
|
-
-S,
|
|
83
|
-
-S,
|
|
84
|
-
-S,
|
|
85
|
-
-S,
|
|
86
|
-
-S,
|
|
87
39
|
S
|
|
88
40
|
]);
|
|
89
41
|
const indices = new U16([
|
|
42
|
+
6,
|
|
43
|
+
4,
|
|
44
|
+
5,
|
|
45
|
+
7,
|
|
46
|
+
6,
|
|
47
|
+
5,
|
|
48
|
+
0,
|
|
90
49
|
2,
|
|
50
|
+
3,
|
|
91
51
|
1,
|
|
92
52
|
0,
|
|
93
53
|
3,
|
|
54
|
+
5,
|
|
55
|
+
1,
|
|
56
|
+
3,
|
|
57
|
+
7,
|
|
58
|
+
5,
|
|
59
|
+
3,
|
|
60
|
+
0,
|
|
61
|
+
4,
|
|
62
|
+
6,
|
|
94
63
|
2,
|
|
95
64
|
0,
|
|
96
65
|
6,
|
|
97
|
-
|
|
98
|
-
|
|
66
|
+
3,
|
|
67
|
+
2,
|
|
68
|
+
6,
|
|
99
69
|
7,
|
|
70
|
+
3,
|
|
100
71
|
6,
|
|
72
|
+
0,
|
|
73
|
+
1,
|
|
74
|
+
5,
|
|
101
75
|
4,
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
8,
|
|
105
|
-
11,
|
|
106
|
-
10,
|
|
107
|
-
8,
|
|
108
|
-
14,
|
|
109
|
-
13,
|
|
110
|
-
12,
|
|
111
|
-
15,
|
|
112
|
-
14,
|
|
113
|
-
12,
|
|
114
|
-
18,
|
|
115
|
-
17,
|
|
116
|
-
16,
|
|
117
|
-
19,
|
|
118
|
-
18,
|
|
119
|
-
16,
|
|
120
|
-
22,
|
|
121
|
-
21,
|
|
122
|
-
20,
|
|
123
|
-
23,
|
|
124
|
-
22,
|
|
125
|
-
20
|
|
76
|
+
0,
|
|
77
|
+
5
|
|
126
78
|
]);
|
|
127
79
|
return {
|
|
128
80
|
posBuffer: createMappedBuffer(engine, positions, BU.VERTEX),
|
|
129
|
-
idxBuffer: createMappedBuffer(engine, indices, BU.INDEX)
|
|
130
|
-
idxCount: 36
|
|
81
|
+
idxBuffer: createMappedBuffer(engine, indices, BU.INDEX)
|
|
131
82
|
};
|
|
132
83
|
}
|
|
133
|
-
function buildSkyboxWorldMatrix(rootPosition) {
|
|
134
|
-
const world = new F32(16);
|
|
135
|
-
world[0] = 1;
|
|
136
|
-
world[5] = 1;
|
|
137
|
-
world[10] = 1;
|
|
138
|
-
world[15] = 1;
|
|
139
|
-
world[12] = rootPosition[0];
|
|
140
|
-
world[13] = rootPosition[1];
|
|
141
|
-
world[14] = rootPosition[2];
|
|
142
|
-
return world;
|
|
143
|
-
}
|
|
144
84
|
const SKYBOX_POS_BUFFER = [{ arrayStride: 12, attributes: [{ shaderLocation: 0, offset: 0, format: "float32x3" }] }];
|
|
145
85
|
const _skyPipelines = /* @__PURE__ */ new Map();
|
|
146
86
|
let _skyLayout = null;
|
|
@@ -198,12 +138,11 @@ function createSkyboxMaterial() {
|
|
|
198
138
|
}
|
|
199
139
|
function buildSolidSkyboxRenderable(scene, envTextures, skyHalfSize, rootPosition, primaryColor) {
|
|
200
140
|
const engine = scene.surface.engine;
|
|
201
|
-
const skyboxWorld = buildSkyboxWorldMatrix(rootPosition);
|
|
202
141
|
const cc = scene.clearColor;
|
|
203
142
|
const skyBufs = createSkyboxBuffers(engine, skyHalfSize);
|
|
204
143
|
const skyMat = createSkyboxMaterial();
|
|
205
144
|
const skyOutputColor = [cc.r, cc.g, cc.b];
|
|
206
|
-
const skyUBO = createSkyMeshUBO(engine,
|
|
145
|
+
const skyUBO = createSkyMeshUBO(engine, rootPosition, primaryColor, skyOutputColor);
|
|
207
146
|
const skyBG = skyMat.createBindGroup(engine, skyUBO, envTextures);
|
|
208
147
|
const r = {
|
|
209
148
|
order: 0,
|
|
@@ -217,7 +156,7 @@ function buildSolidSkyboxRenderable(scene, envTextures, skyHalfSize, rootPositio
|
|
|
217
156
|
pass.setBindGroup(1, skyBG);
|
|
218
157
|
pass.setVertexBuffer(0, skyBufs.posBuffer);
|
|
219
158
|
pass.setIndexBuffer(skyBufs.idxBuffer, "uint16");
|
|
220
|
-
pass.drawIndexed(
|
|
159
|
+
pass.drawIndexed(36);
|
|
221
160
|
return 1;
|
|
222
161
|
}
|
|
223
162
|
};
|
|
@@ -225,9 +164,12 @@ function buildSolidSkyboxRenderable(scene, envTextures, skyHalfSize, rootPositio
|
|
|
225
164
|
};
|
|
226
165
|
return r;
|
|
227
166
|
}
|
|
228
|
-
function createSkyMeshUBO(engine,
|
|
167
|
+
function createSkyMeshUBO(engine, rootPosition, primaryColor, skyOutputColor) {
|
|
229
168
|
const data = new F32(SKY_MESH_UNIFORM_SIZE / 4);
|
|
230
|
-
data
|
|
169
|
+
data[0] = data[5] = data[10] = data[15] = 1;
|
|
170
|
+
data[12] = rootPosition[0];
|
|
171
|
+
data[13] = rootPosition[1];
|
|
172
|
+
data[14] = rootPosition[2];
|
|
231
173
|
data[16] = primaryColor[0];
|
|
232
174
|
data[17] = primaryColor[1];
|
|
233
175
|
data[18] = primaryColor[2];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"background-solid-skybox.js","sources":["../../../../shaders/skybox.fragment.wgsl?raw","../../../../src/material/pbr/background-solid-skybox.ts"],"sourcesContent":["export default \"// Skybox Fragment Shader — matches Babylon BackgroundMaterial\\n// BJS loads a separate CDN skybox texture (backgroundSkybox.dds) that produces\\n// exactly scene.clearColor when rendered through the BackgroundMaterial pipeline.\\n// We replicate this by outputting the pre-computed clearColor directly from a UBO.\\n\\nstruct MeshUniforms {\\n world: mat4x4<f32>,\\n primaryColor: vec3<f32>,\\n _pad: f32,\\n // Pre-computed sRGB output color for the sky background (= scene.clearColor).\\n skyOutputColor: vec3<f32>,\\n _pad2: f32,\\n};\\n@group(1) @binding(0) var<uniform> mesh: MeshUniforms;\\n\\nstruct FragmentInput {\\n @location(0) positionUVW: vec3<f32>,\\n @location(1) positionW: vec3<f32>,\\n};\\n\\n@fragment\\nfn main(input: FragmentInput) -> @location(0) vec4<f32> {\\n var result = vec4<f32>(mesh.skyOutputColor, 1.0);\\n\\n // Dithering (enableNoise=true, variance=0.5)\\n result = vec4<f32>(result.rgb + vec3<f32>(dither(input.positionW.xy, 0.5)), result.a);\\n result = max(result, vec4<f32>(0.0));\\n\\n return result;\\n}\\n\"","/** Solid-color skybox renderable — the clear-color background used by PBR\n * environment scenes when no HDR/DDS skybox is provided.\n *\n * Dynamically imported from `background-renderable.ts` so scenes that pass\n * `skipSkybox: true` (or use a dyn-imported HDR/DDS skybox instead) don't\n * pay for the shader module or cube geometry. */\n\nimport { F32, U16 } from \"../../engine/typed-arrays.js\";\nimport { BU, SS } from \"../../engine/gpu-flags.js\";\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { EnvironmentTextures } from \"../../loader-env/load-env.js\";\nimport type { Mat4 } from \"../../math/types.js\";\nimport type { Renderable } from \"../../render/renderable.js\";\nimport type { RenderTargetSignature } from \"../../engine/render-target.js\";\n\nimport skyboxVertSrc from \"../../../shaders/skybox.vertex.wgsl?raw\";\nimport skyboxFragSrc from \"../../../shaders/skybox.fragment.wgsl?raw\";\nimport { createDefaultPipelineDescriptor, getSceneBindGroupLayout } from \"../../render/scene-helpers.js\";\nimport { targetSignatureKey } from \"../../engine/render-target.js\";\nimport { WGSL_DITHER } from \"../../shader/wgsl-helpers.js\";\nimport { SCENE_UBO_WGSL } from \"../../shader/scene-uniforms.js\";\nimport { createMappedBuffer, createUniformBuffer } from \"../../resource/gpu-buffers.js\";\nimport { createSingleUniformBGL } from \"../../shader/bgl-helpers.js\";\n\nconst SKY_MESH_UNIFORM_SIZE = 96; // mat4x4 + primaryColor vec3 + pad + skyOutputColor vec3 + pad\n\nfunction createSkyboxBuffers(engine: EngineContext, S: number): { posBuffer: GPUBuffer; idxBuffer: GPUBuffer; idxCount: number } {\n // prettier-ignore\n const positions = new F32([\n S,-S, S, -S,-S, S, -S, S, S, S, S, S,\n S, S,-S, -S, S,-S, -S,-S,-S, S,-S,-S,\n S, S,-S, S,-S,-S, S,-S, S, S, S, S,\n -S, S, S, -S,-S, S, -S,-S,-S, -S, S,-S,\n -S, S, S, -S, S,-S, S, S,-S, S, S, S,\n S,-S, S, S,-S,-S, -S,-S,-S, -S,-S, S,\n ]);\n // prettier-ignore\n const indices = new U16([\n 2, 1, 0, 3, 2, 0, 6, 5, 4, 7, 6, 4,\n 10, 9, 8, 11,10, 8, 14,13,12, 15,14,12,\n 18,17,16, 19,18,16, 22,21,20, 23,22,20,\n ]);\n return {\n posBuffer: createMappedBuffer(engine, positions, BU.VERTEX),\n idxBuffer: createMappedBuffer(engine, indices, BU.INDEX),\n idxCount: 36,\n };\n}\n\nfunction buildSkyboxWorldMatrix(rootPosition: [number, number, number]): Float32Array {\n const world = new F32(16);\n world[0] = 1;\n world[5] = 1;\n world[10] = 1;\n world[15] = 1;\n world[12] = rootPosition[0];\n world[13] = rootPosition[1];\n world[14] = rootPosition[2];\n return world;\n}\n\ninterface SkyboxMaterial {\n getPipeline(engine: EngineContext, sig: RenderTargetSignature): GPURenderPipeline;\n createBindGroup(engine: EngineContext, meshUBO: GPUBuffer, env: EnvironmentTextures): GPUBindGroup;\n}\n\nconst SKYBOX_POS_BUFFER: GPUVertexBufferLayout[] = [{ arrayStride: 12, attributes: [{ shaderLocation: 0, offset: 0, format: \"float32x3\" as GPUVertexFormat }] }];\n\n/** Module-global pipeline cache shared by all solid-skybox renderables. */\nconst _skyPipelines = new Map<string, GPURenderPipeline>();\nlet _skyLayout: GPUBindGroupLayout | null = null;\nlet _skyCachedDevice: GPUDevice | null = null;\n\nfunction createSkyboxMaterial(): SkyboxMaterial {\n function getLayout(engine: EngineContext): GPUBindGroupLayout {\n const device = engine._device;\n if (_skyLayout && _skyCachedDevice === device) {\n return _skyLayout;\n }\n _skyLayout = createSingleUniformBGL(engine, \"skybox-material\", SS.VERTEX | SS.FRAGMENT);\n return _skyLayout;\n }\n\n return {\n getPipeline(_engine, sig) {\n const device = _engine._device;\n if (_skyCachedDevice !== device) {\n _skyPipelines.clear();\n _skyLayout = null;\n _skyCachedDevice = device;\n }\n const key = targetSignatureKey(sig);\n const cached = _skyPipelines.get(key);\n if (cached) {\n return cached;\n }\n const _vertModule = device.createShaderModule({ code: SCENE_UBO_WGSL + skyboxVertSrc, label: \"skybox-vert\" });\n const _fragModule = device.createShaderModule({ code: WGSL_DITHER + skyboxFragSrc, label: \"skybox-frag\" });\n\n const pipeline = device.createRenderPipeline(\n createDefaultPipelineDescriptor({\n _label: \"skybox-pipeline\",\n _engine,\n _bgls: [getSceneBindGroupLayout(_engine), getLayout(_engine)],\n _vertModule,\n _fragModule,\n _vertexBuffers: SKYBOX_POS_BUFFER,\n _format: sig._colorFormat!,\n _depthStencilFormat: sig._depthStencilFormat,\n _depthCompare: sig._depthCompare,\n _msaaSamples: sig._sampleCount,\n _depthWriteEnabled: false,\n })\n );\n _skyPipelines.set(key, pipeline);\n return pipeline;\n },\n\n createBindGroup(engine, meshUBO, _env) {\n const device = engine._device;\n return device.createBindGroup({\n layout: getLayout(engine),\n entries: [{ binding: 0, resource: { buffer: meshUBO } }],\n });\n },\n };\n}\n\nexport function buildSolidSkyboxRenderable(\n scene: SceneContext,\n envTextures: EnvironmentTextures,\n skyHalfSize: number,\n rootPosition: [number, number, number],\n primaryColor: [number, number, number]\n): Renderable {\n const engine = scene.surface.engine;\n const skyboxWorld = buildSkyboxWorldMatrix(rootPosition);\n const cc = scene.clearColor;\n const skyBufs = createSkyboxBuffers(engine, skyHalfSize);\n\n const skyMat = createSkyboxMaterial();\n const skyOutputColor: [number, number, number] = [cc.r, cc.g, cc.b];\n const skyUBO = createSkyMeshUBO(engine, skyboxWorld as unknown as Mat4, primaryColor, skyOutputColor);\n const skyBG = skyMat.createBindGroup(engine, skyUBO, envTextures);\n\n const r: Renderable = {\n order: 0, // skybox renders first (behind everything)\n isTransparent: false,\n bind(eng, sig) {\n return {\n renderable: r,\n pipeline: skyMat.getPipeline(eng as EngineContext, sig),\n draw(pass) {\n pass.setBindGroup(1, skyBG);\n pass.setVertexBuffer(0, skyBufs.posBuffer);\n pass.setIndexBuffer(skyBufs.idxBuffer, \"uint16\");\n pass.drawIndexed(skyBufs.idxCount);\n return 1;\n },\n };\n },\n };\n return r;\n}\n\nfunction createSkyMeshUBO(engine: EngineContext, world: Mat4, primaryColor: [number, number, number], skyOutputColor: [number, number, number]): GPUBuffer {\n const data = new F32(SKY_MESH_UNIFORM_SIZE / 4);\n data.set(world, 0);\n data[16] = primaryColor[0];\n data[17] = primaryColor[1];\n data[18] = primaryColor[2];\n data[20] = skyOutputColor[0];\n data[21] = skyOutputColor[1];\n data[22] = skyOutputColor[2];\n return createUniformBuffer(engine, data);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"background-solid-skybox.js","sources":["../../../../shaders/skybox.fragment.wgsl?raw","../../../../src/material/pbr/background-solid-skybox.ts"],"sourcesContent":["export default \"// Skybox Fragment Shader — matches Babylon BackgroundMaterial\\n// BJS loads a separate CDN skybox texture (backgroundSkybox.dds) that produces\\n// exactly scene.clearColor when rendered through the BackgroundMaterial pipeline.\\n// We replicate this by outputting the pre-computed clearColor directly from a UBO.\\n\\nstruct MeshUniforms {\\n world: mat4x4<f32>,\\n primaryColor: vec3<f32>,\\n _pad: f32,\\n // Pre-computed sRGB output color for the sky background (= scene.clearColor).\\n skyOutputColor: vec3<f32>,\\n _pad2: f32,\\n};\\n@group(1) @binding(0) var<uniform> mesh: MeshUniforms;\\n\\nstruct FragmentInput {\\n @location(0) positionUVW: vec3<f32>,\\n @location(1) positionW: vec3<f32>,\\n};\\n\\n@fragment\\nfn main(input: FragmentInput) -> @location(0) vec4<f32> {\\n var result = vec4<f32>(mesh.skyOutputColor, 1.0);\\n\\n // Dithering (enableNoise=true, variance=0.5)\\n result = vec4<f32>(result.rgb + vec3<f32>(dither(input.positionW.xy, 0.5)), result.a);\\n result = max(result, vec4<f32>(0.0));\\n\\n return result;\\n}\\n\"","/** Solid-color skybox renderable — the clear-color background used by PBR\n * environment scenes when no HDR/DDS skybox is provided.\n *\n * Dynamically imported from `background-renderable.ts` so scenes that pass\n * `skipSkybox: true` (or use a dyn-imported HDR/DDS skybox instead) don't\n * pay for the shader module or cube geometry. */\n\nimport { F32, U16 } from \"../../engine/typed-arrays.js\";\nimport { BU, SS } from \"../../engine/gpu-flags.js\";\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { EnvironmentTextures } from \"../../loader-env/load-env.js\";\nimport type { Renderable } from \"../../render/renderable.js\";\nimport type { RenderTargetSignature } from \"../../engine/render-target.js\";\n\nimport skyboxVertSrc from \"../../../shaders/skybox.vertex.wgsl?raw\";\nimport skyboxFragSrc from \"../../../shaders/skybox.fragment.wgsl?raw\";\nimport { createDefaultPipelineDescriptor, getSceneBindGroupLayout } from \"../../render/scene-helpers.js\";\nimport { targetSignatureKey } from \"../../engine/render-target.js\";\nimport { WGSL_DITHER } from \"../../shader/wgsl-helpers.js\";\nimport { SCENE_UBO_WGSL } from \"../../shader/scene-uniforms.js\";\nimport { createMappedBuffer, createUniformBuffer } from \"../../resource/gpu-buffers.js\";\nimport { createSingleUniformBGL } from \"../../shader/bgl-helpers.js\";\n\nconst SKY_MESH_UNIFORM_SIZE = 96; // mat4x4 + primaryColor vec3 + pad + skyOutputColor vec3 + pad\n\nfunction createSkyboxBuffers(engine: EngineContext, S: number): { posBuffer: GPUBuffer; idxBuffer: GPUBuffer } {\n // prettier-ignore\n const positions = new F32([\n -S,-S,-S, S,-S,-S, -S, S,-S, S, S,-S,\n -S,-S, S, S,-S, S, -S, S, S, S, S, S,\n ]);\n // prettier-ignore\n const indices = new U16([\n 6,4,5, 7,6,5, 0,2,3, 1,0,3,\n 5,1,3, 7,5,3, 0,4,6, 2,0,6,\n 3,2,6, 7,3,6, 0,1,5, 4,0,5,\n ]);\n return {\n posBuffer: createMappedBuffer(engine, positions, BU.VERTEX),\n idxBuffer: createMappedBuffer(engine, indices, BU.INDEX),\n };\n}\n\ninterface SkyboxMaterial {\n getPipeline(engine: EngineContext, sig: RenderTargetSignature): GPURenderPipeline;\n createBindGroup(engine: EngineContext, meshUBO: GPUBuffer, env: EnvironmentTextures): GPUBindGroup;\n}\n\nconst SKYBOX_POS_BUFFER: GPUVertexBufferLayout[] = [{ arrayStride: 12, attributes: [{ shaderLocation: 0, offset: 0, format: \"float32x3\" as GPUVertexFormat }] }];\n\n/** Module-global pipeline cache shared by all solid-skybox renderables. */\nconst _skyPipelines = new Map<string, GPURenderPipeline>();\nlet _skyLayout: GPUBindGroupLayout | null = null;\nlet _skyCachedDevice: GPUDevice | null = null;\n\nfunction createSkyboxMaterial(): SkyboxMaterial {\n function getLayout(engine: EngineContext): GPUBindGroupLayout {\n const device = engine._device;\n if (_skyLayout && _skyCachedDevice === device) {\n return _skyLayout;\n }\n _skyLayout = createSingleUniformBGL(engine, \"skybox-material\", SS.VERTEX | SS.FRAGMENT);\n return _skyLayout;\n }\n\n return {\n getPipeline(_engine, sig) {\n const device = _engine._device;\n if (_skyCachedDevice !== device) {\n _skyPipelines.clear();\n _skyLayout = null;\n _skyCachedDevice = device;\n }\n const key = targetSignatureKey(sig);\n const cached = _skyPipelines.get(key);\n if (cached) {\n return cached;\n }\n const _vertModule = device.createShaderModule({ code: SCENE_UBO_WGSL + skyboxVertSrc, label: \"skybox-vert\" });\n const _fragModule = device.createShaderModule({ code: WGSL_DITHER + skyboxFragSrc, label: \"skybox-frag\" });\n\n const pipeline = device.createRenderPipeline(\n createDefaultPipelineDescriptor({\n _label: \"skybox-pipeline\",\n _engine,\n _bgls: [getSceneBindGroupLayout(_engine), getLayout(_engine)],\n _vertModule,\n _fragModule,\n _vertexBuffers: SKYBOX_POS_BUFFER,\n _format: sig._colorFormat!,\n _depthStencilFormat: sig._depthStencilFormat,\n _depthCompare: sig._depthCompare,\n _msaaSamples: sig._sampleCount,\n _depthWriteEnabled: false,\n })\n );\n _skyPipelines.set(key, pipeline);\n return pipeline;\n },\n\n createBindGroup(engine, meshUBO, _env) {\n const device = engine._device;\n return device.createBindGroup({\n layout: getLayout(engine),\n entries: [{ binding: 0, resource: { buffer: meshUBO } }],\n });\n },\n };\n}\n\nexport function buildSolidSkyboxRenderable(\n scene: SceneContext,\n envTextures: EnvironmentTextures,\n skyHalfSize: number,\n rootPosition: [number, number, number],\n primaryColor: [number, number, number]\n): Renderable {\n const engine = scene.surface.engine;\n const cc = scene.clearColor;\n const skyBufs = createSkyboxBuffers(engine, skyHalfSize);\n\n const skyMat = createSkyboxMaterial();\n const skyOutputColor: [number, number, number] = [cc.r, cc.g, cc.b];\n const skyUBO = createSkyMeshUBO(engine, rootPosition, primaryColor, skyOutputColor);\n const skyBG = skyMat.createBindGroup(engine, skyUBO, envTextures);\n\n const r: Renderable = {\n order: 0, // skybox renders first (behind everything)\n isTransparent: false,\n bind(eng, sig) {\n return {\n renderable: r,\n pipeline: skyMat.getPipeline(eng as EngineContext, sig),\n draw(pass) {\n pass.setBindGroup(1, skyBG);\n pass.setVertexBuffer(0, skyBufs.posBuffer);\n pass.setIndexBuffer(skyBufs.idxBuffer, \"uint16\");\n pass.drawIndexed(36);\n return 1;\n },\n };\n },\n };\n return r;\n}\n\nfunction createSkyMeshUBO(\n engine: EngineContext,\n rootPosition: [number, number, number],\n primaryColor: [number, number, number],\n skyOutputColor: [number, number, number]\n): GPUBuffer {\n const data = new F32(SKY_MESH_UNIFORM_SIZE / 4);\n data[0] = data[5] = data[10] = data[15] = 1;\n data[12] = rootPosition[0];\n data[13] = rootPosition[1];\n data[14] = rootPosition[2];\n data[16] = primaryColor[0];\n data[17] = primaryColor[1];\n data[18] = primaryColor[2];\n data[20] = skyOutputColor[0];\n data[21] = skyOutputColor[1];\n data[22] = skyOutputColor[2];\n return createUniformBuffer(engine, data);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { PBR_HAS_CLEARCOAT,
|
|
1
|
+
import { PBR_HAS_CLEARCOAT, PBR_HAS_METALLIC_REFLECTANCE_MAP, PBR_HAS_REFLECTANCE_MAP } from '../pbr-flag-bits.js';
|
|
2
2
|
|
|
3
|
+
const PBR2_CC_INT_MAP = 1 << 0;
|
|
4
|
+
const PBR2_CC_ROUGH_MAP = 1 << 1;
|
|
5
|
+
const PBR2_CC_NORMAL_MAP = 1 << 2;
|
|
6
|
+
const PBR2_CC_F0_REMAP_OFF = 1 << 3;
|
|
3
7
|
const PBR2_CC_UV_TX = 1 << 25;
|
|
4
8
|
const STAGE_FRAGMENT = 2;
|
|
5
9
|
const CC_HELPERS = `
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clearcoat-fragment.js","sources":["../../../../../src/material/pbr/fragments/clearcoat-fragment.ts"],"sourcesContent":["/**\n * Clearcoat Fragment\n *\n * Adds a glossy transparent top layer (like car paint or lacquered surfaces).\n * Only bundled when a scene uses PbrMaterialProps.clearCoat.\n *\n * Math follows BJS PBRClearCoatConfiguration:\n * - F0 from IOR: ((1-ior)/(1+ior))^2\n * - F0 remap: base F0 adjusted for coat/base interface\n * - Direct: GGX + Kelemen visibility + Schlick fresnel\n * - IBL: Jones analytical BRDF (not BRDF LUT)\n * - Conservation: base layer attenuated by (1 - fresnel * intensity)\n *\n * Supports glTF KHR_materials_clearcoat textures:\n * - clearcoatTexture (R channel multiplies intensity)\n * - clearcoatRoughnessTexture (G channel multiplies roughness)\n * - clearcoatNormalTexture (tangent-space normal, perturbs coat normal)\n */\n\nimport type { ShaderFragment, BindingDecl, UboField } from \"../../../shader/fragment-types.js\";\nimport type { PbrMaterialProps, ClearCoatProps } from \"../pbr-material.js\";\nimport type { PbrExt } from \"../pbr-flags.js\";\nimport {\n PBR_HAS_CLEARCOAT,\n PBR_HAS_METALLIC_REFLECTANCE_MAP,\n PBR_HAS_REFLECTANCE_MAP,\n PBR2_CC_INT_MAP,\n PBR2_CC_ROUGH_MAP,\n PBR2_CC_NORMAL_MAP,\n PBR2_CC_F0_REMAP_OFF,\n} from \"../pbr-flag-bits.js\";\n\n// Clearcoat-only features2 bit (reserved in pbr-flag-bits.ts). Defined here, not\n// in the shared flag module, for zero bundle movement on scenes that never load\n// this lazy fragment.\nconst PBR2_CC_UV_TX = 1 << 25;\n\nconst STAGE_FRAGMENT = 0x2;\n\nconst CC_HELPERS = `\nfn visibility_Kelemen(VdotH_kl: f32) -> f32 {\nreturn 0.25 / (VdotH_kl * VdotH_kl + 0.0000001);\n}\nfn getR0RemappedForClearCoat(f0_rc: vec3<f32>, ccA: f32, ccB: f32) -> vec3<f32> {\nlet sf0 = sqrt(f0_rc);\nlet num = ccA + ccB * sf0;\nlet den = ccB + ccA * sf0;\nreturn saturate((num / den) * (num / den));\n}\nfn ccSchlick(f0: f32, cosTheta: f32) -> f32 {\nlet t = 1.0 - cosTheta;\nlet t2 = t * t;\nreturn f0 + (1.0 - f0) * (t2 * t2 * t);\n}\n`;\n\nconst ccUvExpr = (name: string): string => `(vec2<f32>(dot(material.${name}m.xy, input.uv), dot(material.${name}m.zw, input.uv)) + material.${name}t.xy)`;\nconst CC_INT_TEX = (uv: string): string => `material.ccParams.x * textureSample(ccIntensityTexture, ccIntensitySampler_, ${uv}).r`;\nconst CC_INT_PLAIN = `material.ccParams.x`;\nconst CC_ROUGH_TEX = (uv: string): string => `clamp(material.ccParams.y * textureSample(ccRoughnessTexture, ccRoughnessSampler_, ${uv}).g, 0.0, 1.0)`;\nconst CC_ROUGH_PLAIN = `material.ccParams.y`;\n\n// WGSL fragment: coat-layer normal. Computes ccN (coat world-space normal)\n// using a locally-derived cotangent frame from world-position and UV derivatives.\n// Emitted in /*AC*/ so ccN is in scope for direct + IBL blocks.\nconst CC_NORMAL_COMPUTE = (uv: string): string => `\nlet cc_dp1 = dpdx(input.worldPos);\nlet cc_dp2 = dpdy(input.worldPos);\nlet cc_duv1 = dpdx(input.uv);\nlet cc_duv2 = dpdy(input.uv);\nlet cc_dp2perp = cross(cc_dp2, N_geom);\nlet cc_dp1perp = cross(N_geom, cc_dp1);\nlet cc_tFrame = cc_dp2perp * cc_duv1.x + cc_dp1perp * cc_duv2.x;\nlet cc_bFrame = -(cc_dp2perp * cc_duv1.y + cc_dp1perp * cc_duv2.y);\nlet cc_det = max(dot(cc_tFrame, cc_tFrame), dot(cc_bFrame, cc_bFrame));\nlet cc_invmax = select(inverseSqrt(cc_det), 0.0, cc_det == 0.0);\nlet cc_frame = mat3x3<f32>(cc_tFrame * cc_invmax, cc_bFrame * cc_invmax, N_geom);\nlet ccNormSampleRaw = textureSample(ccNormalTexture, ccNormalSampler_, ${uv}).rgb * 2.0 - 1.0;\nlet ccNormScale = material.ccParams.z;\nvar ccN = normalize(cc_frame * normalize(ccNormSampleRaw * vec3<f32>(ccNormScale, ccNormScale, 1.0)));\n`;\n\nfunction makeF0Remap(intensityExpr: string): string {\n return `\n{\nlet ccInt_r = ${intensityExpr};\nlet remappedF0 = getR0RemappedForClearCoat(colorF0, material.ccRefractionParams.z, material.ccRefractionParams.w);\ncolorF0 = mix(colorF0, remappedF0, ccInt_r);\n}\n`;\n}\n\nfunction makeDirectMod(intensityExpr: string, roughnessExpr: string, hasNormalMap: boolean): string {\n const N = hasNormalMap ? \"ccN\" : \"N_geom\";\n return `\nvar ccDirectAttenuation = 1.0;\nvar ccDirectSpecularTerm = vec3<f32>(0.0);\n{\nlet ccInt_dl = ${intensityExpr};\nlet ccRough_dl = ${roughnessExpr};\nlet ccF0_dl = material.ccRefractionParams.x;\nlet ccAlphaG_dl = ccRough_dl * ccRough_dl + 0.0005;\nlet ccNdotL_dl = saturate(dot(${N}, L));\nlet ccH_dl = normalize(V + L);\nlet ccNdotH_dl = clamp(dot(${N}, ccH_dl), 0.0000001, 1.0);\nlet ccVdotH_dl = saturate(dot(V, ccH_dl));\nlet ccD_dl = distributionGGX(ccNdotH_dl, ccAlphaG_dl);\nlet ccVis_dl = visibility_Kelemen(ccVdotH_dl);\nlet ccFresnel_dl = ccSchlick(ccF0_dl, ccVdotH_dl);\nlet ccTerm = ccFresnel_dl * ccD_dl * ccVis_dl * ccNdotL_dl;\nccDirectSpecularTerm = vec3<f32>(ccTerm) * lightColor * lightAtten * material.directIntensity * ccInt_dl;\nccDirectAttenuation = 1.0 - ccFresnel_dl * ccInt_dl;\n}\n`;\n}\n\nfunction makeIblMod(intensityExpr: string, roughnessExpr: string, hasNormalMap: boolean, hasSpecularAA: boolean, hasBaseNormalMap: boolean): string {\n const N = hasNormalMap ? \"ccN\" : \"N_geom\";\n const alphaG = hasSpecularAA\n ? `let ccAlphaG_ibl_base = ccRough_ibl * ccRough_ibl + 0.0005;\nlet cc_nDfdx_AA = dpdx(${N});\nlet cc_nDfdy_AA = dpdy(${N});\nlet cc_slopeSquare_AA = max(dot(cc_nDfdx_AA, cc_nDfdx_AA), dot(cc_nDfdy_AA, cc_nDfdy_AA));\nlet ccAlphaG_ibl = ccAlphaG_ibl_base + sqrt(cc_slopeSquare_AA) * 0.75;`\n : `let ccAlphaG_ibl = ccRough_ibl * ccRough_ibl + 0.0005;`;\n const ehoLine = hasBaseNormalMap ? `let ccEho_ibl = environmentHorizonOcclusion(-V, ${N}, N_geom);` : `let ccEho_ibl = 1.0;`;\n return `\n{\nlet ccInt_ibl = ${intensityExpr};\nlet ccRough_ibl = ${roughnessExpr};\nlet ccF0_ibl = material.ccRefractionParams.x;\nlet ccR_raw = reflect(-V, ${N});\nlet ccR_ibl = rotateY(ccR_raw, scene.envRotationY);\nlet ccNdotV_ibl = abs(dot(${N}, V)) + 0.0000001;\n${alphaG}\nvar ccSpecLod_ibl = log2(cubemapDim * ccAlphaG_ibl) * scene.vImageInfos.z;\nlet ccEnvRadiance_ibl = textureSampleLevel(iblTexture, iblSampler, ccR_ibl, clamp(ccSpecLod_ibl, 0.0, maxLod)).rgb * material.environmentIntensity;\nlet ccBrdf_ibl = textureSample(brdfLUT, brdfSampler_, vec2<f32>(ccNdotV_ibl, ccRough_ibl)).rgb;\n${ehoLine}\nlet ccSpecEnvRefl = (vec3<f32>(ccF0_ibl) * ccBrdf_ibl.y + (vec3<f32>(1.0) - vec3<f32>(ccF0_ibl)) * ccBrdf_ibl.x) * ccInt_ibl * ccEho_ibl;\nlet ccFresnelIBL = ccSchlick(ccF0_ibl, ccNdotV_ibl);\nlet ccConservation_ibl = 1.0 - ccFresnelIBL * ccInt_ibl;\nlet ccFinalRadiance_ibl = ccEnvRadiance_ibl * ccSpecEnvRefl;\ncolor = finalIrradiance * ccConservation_ibl\n + finalRadianceScaled * ccConservation_ibl\n + finalSpecularScaled * ccDirectAttenuation\n + directDiffuse * ccDirectAttenuation\n + ccDirectSpecularTerm\n + ccFinalRadiance_ibl\n + emissive;\n}\n`;\n}\n\nfunction makeNonIblMod(intensityExpr: string): string {\n return `\n{\nlet ccF0_noIbl = material.ccRefractionParams.x;\nlet ccInt_noIbl = ${intensityExpr};\nlet ccFresnelNoIbl = ccSchlick(ccF0_noIbl, NdotV);\nlet ccCons_noIbl = 1.0 - ccFresnelNoIbl * ccInt_noIbl;\ncolor = (color - emissive) * ccCons_noIbl + emissive + ccDirectSpecularTerm;\n}\n`;\n}\n\nexport function createClearcoatFragment(features: number, features2: number, hasIbl: boolean, hasBaseNormalMap: boolean, hasSpecularAA: boolean): ShaderFragment | null {\n if ((features & PBR_HAS_CLEARCOAT) === 0) {\n return null;\n }\n const hasReflectance = (features & (PBR_HAS_METALLIC_REFLECTANCE_MAP | PBR_HAS_REFLECTANCE_MAP)) !== 0;\n const hasIntensityMap = (features2 & PBR2_CC_INT_MAP) !== 0;\n const hasRoughnessMap = (features2 & PBR2_CC_ROUGH_MAP) !== 0;\n const hasNormalMap = (features2 & PBR2_CC_NORMAL_MAP) !== 0;\n const disableF0Remap = (features2 & PBR2_CC_F0_REMAP_OFF) !== 0;\n const hasUvTx = (features2 & PBR2_CC_UV_TX) !== 0;\n const intUv = hasUvTx ? ccUvExpr(\"ccIntUV\") : \"input.uv\";\n const roughUv = hasUvTx ? ccUvExpr(\"ccRoughUV\") : \"input.uv\";\n const normUv = hasUvTx ? ccUvExpr(\"ccNormUV\") : \"input.uv\";\n const intensityExpr = hasIntensityMap ? CC_INT_TEX(intUv) : CC_INT_PLAIN;\n const roughnessExpr = hasRoughnessMap ? CC_ROUGH_TEX(roughUv) : CC_ROUGH_PLAIN;\n const slots: Partial<Record<string, string>> = {\n MF: disableF0Remap ? \"\" : makeF0Remap(intensityExpr),\n AD: makeDirectMod(intensityExpr, roughnessExpr, hasNormalMap),\n BL: `var ccDirectAttenuation = 1.0;\\nvar ccDirectSpecularTerm = vec3<f32>(0.0);`,\n };\n if (hasNormalMap) {\n slots.AC = CC_NORMAL_COMPUTE(normUv);\n }\n // AI and NI are mutually exclusive — only one path runs\n if (hasIbl) {\n slots.AI = makeIblMod(intensityExpr, roughnessExpr, hasNormalMap, hasSpecularAA, hasBaseNormalMap);\n } else {\n slots.NI = makeNonIblMod(intensityExpr);\n }\n const deps: string[] = [];\n if (hasIbl) {\n deps.push(\"ibl\");\n }\n if (hasReflectance) {\n deps.push(\"reflectance\");\n }\n // Fragment id varies with texture config so shader-composer's fragmentKey\n // (and downstream pipeline cache) distinguishes variants.\n const suffix =\n (hasIntensityMap ? \"I\" : \"\") +\n (hasRoughnessMap ? \"R\" : \"\") +\n (hasNormalMap ? \"N\" : \"\") +\n (disableF0Remap ? \"X\" : \"\") +\n (hasSpecularAA ? \"A\" : \"\") +\n (hasBaseNormalMap ? \"B\" : \"\") +\n (hasUvTx ? \"U\" : \"\");\n const bindings: BindingDecl[] = [];\n if (hasIntensityMap) {\n bindings.push(\n { _name: \"ccIntensityTexture\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"ccIntensitySampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n }\n if (hasRoughnessMap) {\n bindings.push(\n { _name: \"ccRoughnessTexture\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"ccRoughnessSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n }\n if (hasNormalMap) {\n bindings.push(\n { _name: \"ccNormalTexture\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"ccNormalSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n }\n\n const uboFields: UboField[] = [\n { _name: \"ccParams\", _type: \"vec4<f32>\" },\n { _name: \"ccRefractionParams\", _type: \"vec4<f32>\" },\n ];\n if (hasUvTx) {\n if (hasIntensityMap) {\n uboFields.push({ _name: \"ccIntUVm\", _type: \"vec4<f32>\" }, { _name: \"ccIntUVt\", _type: \"vec4<f32>\" });\n }\n if (hasRoughnessMap) {\n uboFields.push({ _name: \"ccRoughUVm\", _type: \"vec4<f32>\" }, { _name: \"ccRoughUVt\", _type: \"vec4<f32>\" });\n }\n if (hasNormalMap) {\n uboFields.push({ _name: \"ccNormUVm\", _type: \"vec4<f32>\" }, { _name: \"ccNormUVt\", _type: \"vec4<f32>\" });\n }\n }\n\n return {\n _id: suffix ? `clearcoat-${suffix}` : \"clearcoat\",\n _dependencies: deps.length > 0 ? deps : undefined,\n\n _uboFields: uboFields,\n\n _bindings: bindings,\n\n _helperFunctions: CC_HELPERS,\n\n _fragmentSlots: slots,\n };\n}\n\n/** Write the clearcoat material-UBO slice (ccParams + ccParams2). */\nexport function writeClearcoatUBO(data: Float32Array, material: PbrMaterialProps, offsets: ReadonlyMap<string, number>): void {\n const cc = material.clearCoat as ClearCoatProps | undefined;\n if (!cc?.isEnabled || !offsets.has(\"ccParams\")) {\n return;\n }\n const off = offsets.get(\"ccParams\")! / 4;\n const ior = cc.indexOfRefraction ?? 1.5;\n const a = 1 - ior;\n const b = 1 + ior;\n data[off] = cc.intensity ?? 1.0;\n data[off + 1] = cc.roughness ?? 0.0;\n data[off + 2] = cc.bumpTextureScale ?? 1.0;\n data[off + 4] = Math.pow(-a / b, 2);\n data[off + 5] = 1 / ior;\n data[off + 6] = a;\n data[off + 7] = b;\n\n writeCcUvTransform(data, offsets, \"ccIntUV\", cc.texture);\n writeCcUvTransform(data, offsets, \"ccRoughUV\", cc.roughnessTexture);\n writeCcUvTransform(data, offsets, \"ccNormUV\", cc.bumpTexture);\n}\n\n/** Write a 2x2 UV matrix (vec4) + translate (vec4) for a clearcoat texture. */\nfunction writeCcUvTransform(\n data: Float32Array,\n offsets: ReadonlyMap<string, number>,\n name: string,\n tex: { uScale?: number; vScale?: number; uAng?: number; uOffset?: number; vOffset?: number } | undefined\n): void {\n const mOff = offsets.get(`${name}m`);\n const tOff = offsets.get(`${name}t`);\n if (mOff === undefined || tOff === undefined) {\n return;\n }\n const sx = tex?.uScale ?? 1;\n const sy = tex?.vScale ?? 1;\n const ang = tex?.uAng ?? 0;\n const mi = mOff / 4;\n if (ang === 0) {\n data[mi] = sx;\n data[mi + 1] = 0;\n data[mi + 2] = 0;\n data[mi + 3] = sy;\n } else {\n const c = Math.cos(ang);\n const s = Math.sin(ang);\n data[mi] = c * sx;\n data[mi + 1] = s * sy;\n data[mi + 2] = -s * sx;\n data[mi + 3] = c * sy;\n }\n const ti = tOff / 4;\n data[ti] = tex?.uOffset ?? 0;\n data[ti + 1] = tex?.vOffset ?? 0;\n}\n\nconst CC_TEX: ReadonlyArray<readonly [number, \"texture\" | \"roughnessTexture\" | \"bumpTexture\"]> = [\n [PBR2_CC_INT_MAP, \"texture\"],\n [PBR2_CC_ROUGH_MAP, \"roughnessTexture\"],\n [PBR2_CC_NORMAL_MAP, \"bumpTexture\"],\n];\n\n/** Clearcoat PBR extension (group 1, base-tex phase). */\nexport const pbrExt: PbrExt = {\n id: \"clearcoat\",\n phase: \"base-tex\",\n detect(mat) {\n const cc = (mat as PbrMaterialProps).clearCoat as ClearCoatProps | undefined;\n if (!cc?.isEnabled) {\n return { f: 0, f2: 0 };\n }\n let f2 = 0;\n for (const [flag, key] of CC_TEX) {\n if (cc[key]) {\n f2 |= flag;\n }\n }\n const ccHasTx = (t: { _hasTx?: boolean } | undefined): boolean => !!t?._hasTx;\n if (\n ccHasTx(cc.texture as { _hasTx?: boolean } | undefined) ||\n ccHasTx(cc.roughnessTexture as { _hasTx?: boolean } | undefined) ||\n ccHasTx(cc.bumpTexture as { _hasTx?: boolean } | undefined)\n ) {\n f2 |= PBR2_CC_UV_TX;\n }\n if (cc.useF0Remap === false) {\n f2 |= PBR2_CC_F0_REMAP_OFF;\n }\n return { f: PBR_HAS_CLEARCOAT, f2 };\n },\n frag: (ctx) => createClearcoatFragment(ctx._features, ctx._features2, ctx._hasIbl, ctx._hasAnyNormal, ctx._hasSpecularAA),\n writeUbo: writeClearcoatUBO as PbrExt[\"writeUbo\"],\n bind(ctx, entries, b) {\n const cc = (ctx._material as PbrMaterialProps).clearCoat as ClearCoatProps | undefined;\n if (!cc) {\n return b;\n }\n for (const [flag, key] of CC_TEX) {\n const tex = cc[key];\n if ((ctx._features2 & flag) !== 0 && tex) {\n entries.push({ binding: b++, resource: tex.view });\n entries.push({ binding: b++, resource: tex.sampler });\n }\n }\n return b;\n },\n textures(mat, t) {\n const cc = (mat as PbrMaterialProps).clearCoat;\n if (!cc) {\n return;\n }\n for (const [, key] of CC_TEX) {\n const tex = cc[key];\n if (tex) {\n t.push(tex);\n }\n }\n },\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"clearcoat-fragment.js","sources":["../../../../../src/material/pbr/fragments/clearcoat-fragment.ts"],"sourcesContent":["/**\n * Clearcoat Fragment\n *\n * Adds a glossy transparent top layer (like car paint or lacquered surfaces).\n * Only bundled when a scene uses PbrMaterialProps.clearCoat.\n *\n * Math follows BJS PBRClearCoatConfiguration:\n * - F0 from IOR: ((1-ior)/(1+ior))^2\n * - F0 remap: base F0 adjusted for coat/base interface\n * - Direct: GGX + Kelemen visibility + Schlick fresnel\n * - IBL: Jones analytical BRDF (not BRDF LUT)\n * - Conservation: base layer attenuated by (1 - fresnel * intensity)\n *\n * Supports glTF KHR_materials_clearcoat textures:\n * - clearcoatTexture (R channel multiplies intensity)\n * - clearcoatRoughnessTexture (G channel multiplies roughness)\n * - clearcoatNormalTexture (tangent-space normal, perturbs coat normal)\n */\n\nimport type { ShaderFragment, BindingDecl, UboField } from \"../../../shader/fragment-types.js\";\nimport type { PbrMaterialProps, ClearCoatProps } from \"../pbr-material.js\";\nimport type { PbrExt } from \"../pbr-flags.js\";\nimport { PBR_HAS_CLEARCOAT, PBR_HAS_METALLIC_REFLECTANCE_MAP, PBR_HAS_REFLECTANCE_MAP } from \"../pbr-flag-bits.js\";\n\n// Clearcoat-only features2 bits, kept out of the shared flag module.\nconst PBR2_CC_INT_MAP = 1 << 0;\nconst PBR2_CC_ROUGH_MAP = 1 << 1;\nconst PBR2_CC_NORMAL_MAP = 1 << 2;\nconst PBR2_CC_F0_REMAP_OFF = 1 << 3;\nconst PBR2_CC_UV_TX = 1 << 25;\n\nconst STAGE_FRAGMENT = 0x2;\n\nconst CC_HELPERS = `\nfn visibility_Kelemen(VdotH_kl: f32) -> f32 {\nreturn 0.25 / (VdotH_kl * VdotH_kl + 0.0000001);\n}\nfn getR0RemappedForClearCoat(f0_rc: vec3<f32>, ccA: f32, ccB: f32) -> vec3<f32> {\nlet sf0 = sqrt(f0_rc);\nlet num = ccA + ccB * sf0;\nlet den = ccB + ccA * sf0;\nreturn saturate((num / den) * (num / den));\n}\nfn ccSchlick(f0: f32, cosTheta: f32) -> f32 {\nlet t = 1.0 - cosTheta;\nlet t2 = t * t;\nreturn f0 + (1.0 - f0) * (t2 * t2 * t);\n}\n`;\n\nconst ccUvExpr = (name: string): string => `(vec2<f32>(dot(material.${name}m.xy, input.uv), dot(material.${name}m.zw, input.uv)) + material.${name}t.xy)`;\nconst CC_INT_TEX = (uv: string): string => `material.ccParams.x * textureSample(ccIntensityTexture, ccIntensitySampler_, ${uv}).r`;\nconst CC_INT_PLAIN = `material.ccParams.x`;\nconst CC_ROUGH_TEX = (uv: string): string => `clamp(material.ccParams.y * textureSample(ccRoughnessTexture, ccRoughnessSampler_, ${uv}).g, 0.0, 1.0)`;\nconst CC_ROUGH_PLAIN = `material.ccParams.y`;\n\n// WGSL fragment: coat-layer normal. Computes ccN (coat world-space normal)\n// using a locally-derived cotangent frame from world-position and UV derivatives.\n// Emitted in /*AC*/ so ccN is in scope for direct + IBL blocks.\nconst CC_NORMAL_COMPUTE = (uv: string): string => `\nlet cc_dp1 = dpdx(input.worldPos);\nlet cc_dp2 = dpdy(input.worldPos);\nlet cc_duv1 = dpdx(input.uv);\nlet cc_duv2 = dpdy(input.uv);\nlet cc_dp2perp = cross(cc_dp2, N_geom);\nlet cc_dp1perp = cross(N_geom, cc_dp1);\nlet cc_tFrame = cc_dp2perp * cc_duv1.x + cc_dp1perp * cc_duv2.x;\nlet cc_bFrame = -(cc_dp2perp * cc_duv1.y + cc_dp1perp * cc_duv2.y);\nlet cc_det = max(dot(cc_tFrame, cc_tFrame), dot(cc_bFrame, cc_bFrame));\nlet cc_invmax = select(inverseSqrt(cc_det), 0.0, cc_det == 0.0);\nlet cc_frame = mat3x3<f32>(cc_tFrame * cc_invmax, cc_bFrame * cc_invmax, N_geom);\nlet ccNormSampleRaw = textureSample(ccNormalTexture, ccNormalSampler_, ${uv}).rgb * 2.0 - 1.0;\nlet ccNormScale = material.ccParams.z;\nvar ccN = normalize(cc_frame * normalize(ccNormSampleRaw * vec3<f32>(ccNormScale, ccNormScale, 1.0)));\n`;\n\nfunction makeF0Remap(intensityExpr: string): string {\n return `\n{\nlet ccInt_r = ${intensityExpr};\nlet remappedF0 = getR0RemappedForClearCoat(colorF0, material.ccRefractionParams.z, material.ccRefractionParams.w);\ncolorF0 = mix(colorF0, remappedF0, ccInt_r);\n}\n`;\n}\n\nfunction makeDirectMod(intensityExpr: string, roughnessExpr: string, hasNormalMap: boolean): string {\n const N = hasNormalMap ? \"ccN\" : \"N_geom\";\n return `\nvar ccDirectAttenuation = 1.0;\nvar ccDirectSpecularTerm = vec3<f32>(0.0);\n{\nlet ccInt_dl = ${intensityExpr};\nlet ccRough_dl = ${roughnessExpr};\nlet ccF0_dl = material.ccRefractionParams.x;\nlet ccAlphaG_dl = ccRough_dl * ccRough_dl + 0.0005;\nlet ccNdotL_dl = saturate(dot(${N}, L));\nlet ccH_dl = normalize(V + L);\nlet ccNdotH_dl = clamp(dot(${N}, ccH_dl), 0.0000001, 1.0);\nlet ccVdotH_dl = saturate(dot(V, ccH_dl));\nlet ccD_dl = distributionGGX(ccNdotH_dl, ccAlphaG_dl);\nlet ccVis_dl = visibility_Kelemen(ccVdotH_dl);\nlet ccFresnel_dl = ccSchlick(ccF0_dl, ccVdotH_dl);\nlet ccTerm = ccFresnel_dl * ccD_dl * ccVis_dl * ccNdotL_dl;\nccDirectSpecularTerm = vec3<f32>(ccTerm) * lightColor * lightAtten * material.directIntensity * ccInt_dl;\nccDirectAttenuation = 1.0 - ccFresnel_dl * ccInt_dl;\n}\n`;\n}\n\nfunction makeIblMod(intensityExpr: string, roughnessExpr: string, hasNormalMap: boolean, hasSpecularAA: boolean, hasBaseNormalMap: boolean): string {\n const N = hasNormalMap ? \"ccN\" : \"N_geom\";\n const alphaG = hasSpecularAA\n ? `let ccAlphaG_ibl_base = ccRough_ibl * ccRough_ibl + 0.0005;\nlet cc_nDfdx_AA = dpdx(${N});\nlet cc_nDfdy_AA = dpdy(${N});\nlet cc_slopeSquare_AA = max(dot(cc_nDfdx_AA, cc_nDfdx_AA), dot(cc_nDfdy_AA, cc_nDfdy_AA));\nlet ccAlphaG_ibl = ccAlphaG_ibl_base + sqrt(cc_slopeSquare_AA) * 0.75;`\n : `let ccAlphaG_ibl = ccRough_ibl * ccRough_ibl + 0.0005;`;\n const ehoLine = hasBaseNormalMap ? `let ccEho_ibl = environmentHorizonOcclusion(-V, ${N}, N_geom);` : `let ccEho_ibl = 1.0;`;\n return `\n{\nlet ccInt_ibl = ${intensityExpr};\nlet ccRough_ibl = ${roughnessExpr};\nlet ccF0_ibl = material.ccRefractionParams.x;\nlet ccR_raw = reflect(-V, ${N});\nlet ccR_ibl = rotateY(ccR_raw, scene.envRotationY);\nlet ccNdotV_ibl = abs(dot(${N}, V)) + 0.0000001;\n${alphaG}\nvar ccSpecLod_ibl = log2(cubemapDim * ccAlphaG_ibl) * scene.vImageInfos.z;\nlet ccEnvRadiance_ibl = textureSampleLevel(iblTexture, iblSampler, ccR_ibl, clamp(ccSpecLod_ibl, 0.0, maxLod)).rgb * material.environmentIntensity;\nlet ccBrdf_ibl = textureSample(brdfLUT, brdfSampler_, vec2<f32>(ccNdotV_ibl, ccRough_ibl)).rgb;\n${ehoLine}\nlet ccSpecEnvRefl = (vec3<f32>(ccF0_ibl) * ccBrdf_ibl.y + (vec3<f32>(1.0) - vec3<f32>(ccF0_ibl)) * ccBrdf_ibl.x) * ccInt_ibl * ccEho_ibl;\nlet ccFresnelIBL = ccSchlick(ccF0_ibl, ccNdotV_ibl);\nlet ccConservation_ibl = 1.0 - ccFresnelIBL * ccInt_ibl;\nlet ccFinalRadiance_ibl = ccEnvRadiance_ibl * ccSpecEnvRefl;\ncolor = finalIrradiance * ccConservation_ibl\n + finalRadianceScaled * ccConservation_ibl\n + finalSpecularScaled * ccDirectAttenuation\n + directDiffuse * ccDirectAttenuation\n + ccDirectSpecularTerm\n + ccFinalRadiance_ibl\n + emissive;\n}\n`;\n}\n\nfunction makeNonIblMod(intensityExpr: string): string {\n return `\n{\nlet ccF0_noIbl = material.ccRefractionParams.x;\nlet ccInt_noIbl = ${intensityExpr};\nlet ccFresnelNoIbl = ccSchlick(ccF0_noIbl, NdotV);\nlet ccCons_noIbl = 1.0 - ccFresnelNoIbl * ccInt_noIbl;\ncolor = (color - emissive) * ccCons_noIbl + emissive + ccDirectSpecularTerm;\n}\n`;\n}\n\nexport function createClearcoatFragment(features: number, features2: number, hasIbl: boolean, hasBaseNormalMap: boolean, hasSpecularAA: boolean): ShaderFragment | null {\n if ((features & PBR_HAS_CLEARCOAT) === 0) {\n return null;\n }\n const hasReflectance = (features & (PBR_HAS_METALLIC_REFLECTANCE_MAP | PBR_HAS_REFLECTANCE_MAP)) !== 0;\n const hasIntensityMap = (features2 & PBR2_CC_INT_MAP) !== 0;\n const hasRoughnessMap = (features2 & PBR2_CC_ROUGH_MAP) !== 0;\n const hasNormalMap = (features2 & PBR2_CC_NORMAL_MAP) !== 0;\n const disableF0Remap = (features2 & PBR2_CC_F0_REMAP_OFF) !== 0;\n const hasUvTx = (features2 & PBR2_CC_UV_TX) !== 0;\n const intUv = hasUvTx ? ccUvExpr(\"ccIntUV\") : \"input.uv\";\n const roughUv = hasUvTx ? ccUvExpr(\"ccRoughUV\") : \"input.uv\";\n const normUv = hasUvTx ? ccUvExpr(\"ccNormUV\") : \"input.uv\";\n const intensityExpr = hasIntensityMap ? CC_INT_TEX(intUv) : CC_INT_PLAIN;\n const roughnessExpr = hasRoughnessMap ? CC_ROUGH_TEX(roughUv) : CC_ROUGH_PLAIN;\n const slots: Partial<Record<string, string>> = {\n MF: disableF0Remap ? \"\" : makeF0Remap(intensityExpr),\n AD: makeDirectMod(intensityExpr, roughnessExpr, hasNormalMap),\n BL: `var ccDirectAttenuation = 1.0;\\nvar ccDirectSpecularTerm = vec3<f32>(0.0);`,\n };\n if (hasNormalMap) {\n slots.AC = CC_NORMAL_COMPUTE(normUv);\n }\n // AI and NI are mutually exclusive — only one path runs\n if (hasIbl) {\n slots.AI = makeIblMod(intensityExpr, roughnessExpr, hasNormalMap, hasSpecularAA, hasBaseNormalMap);\n } else {\n slots.NI = makeNonIblMod(intensityExpr);\n }\n const deps: string[] = [];\n if (hasIbl) {\n deps.push(\"ibl\");\n }\n if (hasReflectance) {\n deps.push(\"reflectance\");\n }\n // Fragment id varies with texture config so shader-composer's fragmentKey\n // (and downstream pipeline cache) distinguishes variants.\n const suffix =\n (hasIntensityMap ? \"I\" : \"\") +\n (hasRoughnessMap ? \"R\" : \"\") +\n (hasNormalMap ? \"N\" : \"\") +\n (disableF0Remap ? \"X\" : \"\") +\n (hasSpecularAA ? \"A\" : \"\") +\n (hasBaseNormalMap ? \"B\" : \"\") +\n (hasUvTx ? \"U\" : \"\");\n const bindings: BindingDecl[] = [];\n if (hasIntensityMap) {\n bindings.push(\n { _name: \"ccIntensityTexture\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"ccIntensitySampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n }\n if (hasRoughnessMap) {\n bindings.push(\n { _name: \"ccRoughnessTexture\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"ccRoughnessSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n }\n if (hasNormalMap) {\n bindings.push(\n { _name: \"ccNormalTexture\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"ccNormalSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n }\n\n const uboFields: UboField[] = [\n { _name: \"ccParams\", _type: \"vec4<f32>\" },\n { _name: \"ccRefractionParams\", _type: \"vec4<f32>\" },\n ];\n if (hasUvTx) {\n if (hasIntensityMap) {\n uboFields.push({ _name: \"ccIntUVm\", _type: \"vec4<f32>\" }, { _name: \"ccIntUVt\", _type: \"vec4<f32>\" });\n }\n if (hasRoughnessMap) {\n uboFields.push({ _name: \"ccRoughUVm\", _type: \"vec4<f32>\" }, { _name: \"ccRoughUVt\", _type: \"vec4<f32>\" });\n }\n if (hasNormalMap) {\n uboFields.push({ _name: \"ccNormUVm\", _type: \"vec4<f32>\" }, { _name: \"ccNormUVt\", _type: \"vec4<f32>\" });\n }\n }\n\n return {\n _id: suffix ? `clearcoat-${suffix}` : \"clearcoat\",\n _dependencies: deps.length > 0 ? deps : undefined,\n\n _uboFields: uboFields,\n\n _bindings: bindings,\n\n _helperFunctions: CC_HELPERS,\n\n _fragmentSlots: slots,\n };\n}\n\n/** Write the clearcoat material-UBO slice (ccParams + ccParams2). */\nexport function writeClearcoatUBO(data: Float32Array, material: PbrMaterialProps, offsets: ReadonlyMap<string, number>): void {\n const cc = material.clearCoat as ClearCoatProps | undefined;\n if (!cc?.isEnabled || !offsets.has(\"ccParams\")) {\n return;\n }\n const off = offsets.get(\"ccParams\")! / 4;\n const ior = cc.indexOfRefraction ?? 1.5;\n const a = 1 - ior;\n const b = 1 + ior;\n data[off] = cc.intensity ?? 1.0;\n data[off + 1] = cc.roughness ?? 0.0;\n data[off + 2] = cc.bumpTextureScale ?? 1.0;\n data[off + 4] = Math.pow(-a / b, 2);\n data[off + 5] = 1 / ior;\n data[off + 6] = a;\n data[off + 7] = b;\n\n writeCcUvTransform(data, offsets, \"ccIntUV\", cc.texture);\n writeCcUvTransform(data, offsets, \"ccRoughUV\", cc.roughnessTexture);\n writeCcUvTransform(data, offsets, \"ccNormUV\", cc.bumpTexture);\n}\n\n/** Write a 2x2 UV matrix (vec4) + translate (vec4) for a clearcoat texture. */\nfunction writeCcUvTransform(\n data: Float32Array,\n offsets: ReadonlyMap<string, number>,\n name: string,\n tex: { uScale?: number; vScale?: number; uAng?: number; uOffset?: number; vOffset?: number } | undefined\n): void {\n const mOff = offsets.get(`${name}m`);\n const tOff = offsets.get(`${name}t`);\n if (mOff === undefined || tOff === undefined) {\n return;\n }\n const sx = tex?.uScale ?? 1;\n const sy = tex?.vScale ?? 1;\n const ang = tex?.uAng ?? 0;\n const mi = mOff / 4;\n if (ang === 0) {\n data[mi] = sx;\n data[mi + 1] = 0;\n data[mi + 2] = 0;\n data[mi + 3] = sy;\n } else {\n const c = Math.cos(ang);\n const s = Math.sin(ang);\n data[mi] = c * sx;\n data[mi + 1] = s * sy;\n data[mi + 2] = -s * sx;\n data[mi + 3] = c * sy;\n }\n const ti = tOff / 4;\n data[ti] = tex?.uOffset ?? 0;\n data[ti + 1] = tex?.vOffset ?? 0;\n}\n\nconst CC_TEX: ReadonlyArray<readonly [number, \"texture\" | \"roughnessTexture\" | \"bumpTexture\"]> = [\n [PBR2_CC_INT_MAP, \"texture\"],\n [PBR2_CC_ROUGH_MAP, \"roughnessTexture\"],\n [PBR2_CC_NORMAL_MAP, \"bumpTexture\"],\n];\n\n/** Clearcoat PBR extension (group 1, base-tex phase). */\nexport const pbrExt: PbrExt = {\n id: \"clearcoat\",\n phase: \"base-tex\",\n detect(mat) {\n const cc = (mat as PbrMaterialProps).clearCoat as ClearCoatProps | undefined;\n if (!cc?.isEnabled) {\n return { f: 0, f2: 0 };\n }\n let f2 = 0;\n for (const [flag, key] of CC_TEX) {\n if (cc[key]) {\n f2 |= flag;\n }\n }\n const ccHasTx = (t: { _hasTx?: boolean } | undefined): boolean => !!t?._hasTx;\n if (\n ccHasTx(cc.texture as { _hasTx?: boolean } | undefined) ||\n ccHasTx(cc.roughnessTexture as { _hasTx?: boolean } | undefined) ||\n ccHasTx(cc.bumpTexture as { _hasTx?: boolean } | undefined)\n ) {\n f2 |= PBR2_CC_UV_TX;\n }\n if (cc.useF0Remap === false) {\n f2 |= PBR2_CC_F0_REMAP_OFF;\n }\n return { f: PBR_HAS_CLEARCOAT, f2 };\n },\n frag: (ctx) => createClearcoatFragment(ctx._features, ctx._features2, ctx._hasIbl, ctx._hasAnyNormal, ctx._hasSpecularAA),\n writeUbo: writeClearcoatUBO as PbrExt[\"writeUbo\"],\n bind(ctx, entries, b) {\n const cc = (ctx._material as PbrMaterialProps).clearCoat as ClearCoatProps | undefined;\n if (!cc) {\n return b;\n }\n for (const [flag, key] of CC_TEX) {\n const tex = cc[key];\n if ((ctx._features2 & flag) !== 0 && tex) {\n entries.push({ binding: b++, resource: tex.view });\n entries.push({ binding: b++, resource: tex.sampler });\n }\n }\n return b;\n },\n textures(mat, t) {\n const cc = (mat as PbrMaterialProps).clearCoat;\n if (!cc) {\n return;\n }\n for (const [, key] of CC_TEX) {\n const tex = cc[key];\n if (tex) {\n t.push(tex);\n }\n }\n },\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PBR_HAS_METALLIC_REFLECTANCE_MAP, PBR_HAS_REFLECTANCE_MAP, PBR2_HAS_REFLECTANCE_FACTORS } from '../pbr-flag-bits.js';
|
|
2
2
|
|
|
3
3
|
const STAGE_FRAGMENT = 2;
|
|
4
|
+
const PBR2_HAS_IRIDESCENCE = 1 << 17;
|
|
5
|
+
const PBR2_HAS_IRIDESCENCE_MAP = 1 << 18;
|
|
6
|
+
const PBR2_HAS_IRIDESCENCE_THICKNESS_MAP = 1 << 19;
|
|
4
7
|
const PBR2_HAS_IRIDESCENCE_UV_TX = 1 << 20;
|
|
5
8
|
const PBR2_HAS_IRIDESCENCE_THICKNESS_UV_TX = 1 << 21;
|
|
6
9
|
const PBR2_HAS_IRIDESCENCE_UV2 = 1 << 22;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iridescence-fragment.js","sources":["../../../../../src/material/pbr/fragments/iridescence-fragment.ts"],"sourcesContent":["/**\n * Iridescence Fragment\n *\n * Native PBR thin-film iridescence (BJS PBRMaterial.iridescence and\n * KHR_materials_iridescence). Modifies the already-computed base-layer colorF0\n * before direct and IBL lighting consume it.\n */\n\nimport type { BindingDecl, ShaderFragment, UboField } from \"../../../shader/fragment-types.js\";\nimport type { Texture2D } from \"../../../texture/texture-2d.js\";\nimport type { PbrExt } from \"../pbr-flags.js\";\nimport type { IridescenceProps, PbrMaterialProps } from \"../pbr-material.js\";\nimport {\n PBR_HAS_METALLIC_REFLECTANCE_MAP,\n PBR_HAS_REFLECTANCE_MAP,\n PBR2_HAS_IRIDESCENCE,\n PBR2_HAS_IRIDESCENCE_MAP,\n PBR2_HAS_IRIDESCENCE_THICKNESS_MAP,\n PBR2_HAS_REFLECTANCE_FACTORS,\n} from \"../pbr-flag-bits.js\";\n\nconst STAGE_FRAGMENT = 0x2;\nconst PBR2_HAS_IRIDESCENCE_UV_TX = 1 << 20;\nconst PBR2_HAS_IRIDESCENCE_THICKNESS_UV_TX = 1 << 21;\nconst PBR2_HAS_IRIDESCENCE_UV2 = 1 << 22;\nconst PBR2_HAS_IRIDESCENCE_THICKNESS_UV2 = 1 << 23;\nconst IRI_MSH_HAS_UV2 = 1 << 7;\n\nconst IRIDESCENCE_HELPERS = `const IRI_XYZ_TO_REC709:mat3x3<f32>=mat3x3<f32>(\n3.2404542,-0.9692660,0.0556434,\n-1.5371385,1.8760108,-0.2040259,\n-0.4985314,0.0415560,1.0572252);\nfn iri_square3(x:vec3<f32>)->vec3<f32>{return x*x;}\nfn iri_iorFromAirF0(f0:vec3<f32>)->vec3<f32>{\nlet s=sqrt(clamp(f0,vec3<f32>(0.0),vec3<f32>(0.9999)));\nreturn (vec3<f32>(1.0)+s)/(vec3<f32>(1.0)-s);\n}\nfn iri_r0FromIor3(iorT:vec3<f32>,iorI:f32)->vec3<f32>{return iri_square3((iorT-vec3<f32>(iorI))/(iorT+vec3<f32>(iorI)));}\nfn iri_r0FromIor(iorT:f32,iorI:f32)->f32{let r=(iorT-iorI)/(iorT+iorI);return r*r;}\nfn iri_fresSchlick(c:f32,F0:vec3<f32>,F90:vec3<f32>)->vec3<f32>{\nlet t=1.0-c;\nlet t2=t*t;\nreturn F0+(F90-F0)*(t2*t2*t);\n}\nfn iri_evalSensitivity(opd:f32,shift:vec3<f32>)->vec3<f32>{\nlet phase=6.283185307179586*opd*1.0e-9;\nlet val=vec3<f32>(5.4856e-13,4.4201e-13,5.2481e-13);\nlet pos=vec3<f32>(1.6810e+06,1.7953e+06,2.2084e+06);\nlet vr=vec3<f32>(4.3278e+09,9.3046e+09,6.6121e+09);\nvar xyz=val*sqrt(6.283185307179586*vr)*cos(pos*phase+shift)*exp(-(phase*phase)*vr);\nxyz.x=xyz.x+9.7470e-14*sqrt(6.283185307179586*4.5282e+09)*cos(2.2399e+06*phase+shift.x)*exp(-4.5282e+09*phase*phase);\nxyz=xyz/1.0685e-7;\nreturn IRI_XYZ_TO_REC709*xyz;\n}\nfn iri_eval(outsideIor:f32,eta2:f32,cosTheta1:f32,thickness:f32,baseF0:vec3<f32>)->vec3<f32>{\nlet iridescenceIor=mix(outsideIor,eta2,smoothstep(0.0,0.03,thickness));\nlet eta=outsideIor/iridescenceIor;\nlet sinTheta2Sq=eta*eta*(1.0-cosTheta1*cosTheta1);\nlet cosTheta2Sq=1.0-sinTheta2Sq;\nif(cosTheta2Sq<0.0){return vec3<f32>(1.0);}\nlet cosTheta2=sqrt(cosTheta2Sq);\nlet r0=iri_r0FromIor(iridescenceIor,outsideIor);\nlet r12=iri_fresSchlick(cosTheta1,vec3<f32>(r0),vec3<f32>(1.0)).x;\nlet t121=1.0-r12;\nvar phi12=0.0;\nif(iridescenceIor<outsideIor){phi12=3.141592653589793;}\nlet phi21=3.141592653589793-phi12;\nlet baseIor=iri_iorFromAirF0(baseF0);\nlet r1=iri_r0FromIor3(baseIor,iridescenceIor);\nlet r23=iri_fresSchlick(cosTheta2,r1,vec3<f32>(1.0));\nvar phi23=vec3<f32>(0.0);\nif(baseIor.x<iridescenceIor){phi23.x=3.141592653589793;}\nif(baseIor.y<iridescenceIor){phi23.y=3.141592653589793;}\nif(baseIor.z<iridescenceIor){phi23.z=3.141592653589793;}\nlet opd=2.0*iridescenceIor*thickness*cosTheta2;\nlet phi=vec3<f32>(phi21)+phi23;\nlet r123=clamp(vec3<f32>(r12)*r23,vec3<f32>(1e-5),vec3<f32>(0.9999));\nlet smallR123=sqrt(r123);\nlet rs=(t121*t121)*r23/(vec3<f32>(1.0)-r123);\nvar outI=vec3<f32>(r12)+rs;\nvar cm=rs-vec3<f32>(t121);\nfor(var m:i32=1;m<=2;m=m+1){\ncm=cm*smallR123;\noutI=outI+cm*(2.0*iri_evalSensitivity(f32(m)*opd,f32(m)*phi));\n}\nreturn max(outI,vec3<f32>(0.0));\n}`;\n\nconst IRI_TEX: ReadonlyArray<readonly [number, \"texture\" | \"thicknessTexture\"]> = [\n [PBR2_HAS_IRIDESCENCE_MAP, \"texture\"],\n [PBR2_HAS_IRIDESCENCE_THICKNESS_MAP, \"thicknessTexture\"],\n];\n\nfunction uvBaseExpr(features2: number, meshFeatures: number, uv2Flag: number): string {\n return (features2 & uv2Flag) !== 0 && (meshFeatures & IRI_MSH_HAS_UV2) !== 0 ? \"input.uv2\" : \"input.uv\";\n}\n\nfunction uvDecl(name: string, baseUv: string, hasTx: boolean): string {\n return hasTx ? `let ${name}=vec2<f32>(dot(material.${name}m.xy,${baseUv}),dot(material.${name}m.zw,${baseUv}))+material.${name}t.xy;` : `let ${name}=${baseUv};`;\n}\n\nfunction uvTransformUboFields(name: string): UboField[] {\n return [\n { _name: `${name}m`, _type: \"vec4<f32>\" },\n { _name: `${name}t`, _type: \"vec4<f32>\" },\n ];\n}\n\nfunction writeUvTransform(data: Float32Array, offsets: ReadonlyMap<string, number>, name: string, tex: Texture2D | undefined): void {\n const mOff = offsets.get(`${name}m`);\n const tOff = offsets.get(`${name}t`);\n if (mOff === undefined || tOff === undefined) {\n return;\n }\n const mi = mOff / 4;\n const ti = tOff / 4;\n const sx = tex?.uScale ?? 1;\n const sy = tex?.vScale ?? 1;\n const ang = tex?.uAng ?? 0;\n const ox = tex?.uOffset ?? 0;\n const oy = tex?.vOffset ?? 0;\n if (ang === 0) {\n data[mi] = sx;\n data[mi + 1] = 0;\n data[mi + 2] = 0;\n data[mi + 3] = sy;\n } else {\n const c = Math.cos(ang);\n const s = Math.sin(ang);\n data[mi] = c * sx;\n data[mi + 1] = s * sy;\n data[mi + 2] = -s * sx;\n data[mi + 3] = c * sy;\n }\n data[ti] = ox;\n data[ti + 1] = oy;\n data[ti + 2] = 0;\n data[ti + 3] = 0;\n}\n\nfunction createIridescenceFragment(features: number, features2: number, meshFeatures: number): ShaderFragment | null {\n if ((features2 & PBR2_HAS_IRIDESCENCE) === 0) {\n return null;\n }\n const hasIntensityMap = (features2 & PBR2_HAS_IRIDESCENCE_MAP) !== 0;\n const hasThicknessMap = (features2 & PBR2_HAS_IRIDESCENCE_THICKNESS_MAP) !== 0;\n const hasIntensityUvTx = (features2 & PBR2_HAS_IRIDESCENCE_UV_TX) !== 0;\n const hasThicknessUvTx = (features2 & PBR2_HAS_IRIDESCENCE_THICKNESS_UV_TX) !== 0;\n const bindings: BindingDecl[] = [];\n const uboFields: UboField[] = [{ _name: \"iridescenceParams\", _type: \"vec4<f32>\" }];\n if (hasIntensityMap) {\n bindings.push(\n { _name: \"iridescenceTexture\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"iridescenceSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n if (hasIntensityUvTx) {\n uboFields.push(...uvTransformUboFields(\"iridescenceUV\"));\n }\n }\n if (hasThicknessMap) {\n bindings.push(\n { _name: \"iridescenceThicknessTexture\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"iridescenceThicknessSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n if (hasThicknessUvTx) {\n uboFields.push(...uvTransformUboFields(\"iridescenceThicknessUV\"));\n }\n }\n\n const scopeVars: string[] = [];\n if (hasIntensityMap) {\n scopeVars.push(uvDecl(\"iridescenceUV\", uvBaseExpr(features2, meshFeatures, PBR2_HAS_IRIDESCENCE_UV2), hasIntensityUvTx));\n }\n if (hasThicknessMap) {\n scopeVars.push(uvDecl(\"iridescenceThicknessUV\", uvBaseExpr(features2, meshFeatures, PBR2_HAS_IRIDESCENCE_THICKNESS_UV2), hasThicknessUvTx));\n }\n\n const intensity = hasIntensityMap ? \"material.iridescenceParams.x*textureSample(iridescenceTexture,iridescenceSampler_,iridescenceUV).r\" : \"material.iridescenceParams.x\";\n const thickness = hasThicknessMap\n ? \"mix(material.iridescenceParams.z,material.iridescenceParams.w,textureSample(iridescenceThicknessTexture,iridescenceThicknessSampler_,iridescenceThicknessUV).g)\"\n : \"material.iridescenceParams.w\";\n return {\n _id: \"iridescence\",\n _dependencies:\n (features & (PBR_HAS_METALLIC_REFLECTANCE_MAP | PBR_HAS_REFLECTANCE_MAP)) !== 0 || (features2 & PBR2_HAS_REFLECTANCE_FACTORS) !== 0 ? [\"reflectance\"] : undefined,\n _uboFields: uboFields,\n _bindings: bindings,\n _helperFunctions: IRIDESCENCE_HELPERS,\n _fragmentSlots: {\n ...(scopeVars.length ? { SV: scopeVars.join(\"\\n\") } : undefined),\n MF: `{\nlet iriIntensity=clamp(${intensity},0.0,1.0);\nlet iriThickness=max(${thickness},0.0);\nlet iriF0=iri_eval(1.0,max(material.iridescenceParams.y,1.0001),NdotV,iriThickness,colorF0);\ncolorF0=mix(colorF0,iriF0,iriIntensity);\n}`,\n },\n };\n}\n\nexport function writeIridescenceUBO(data: Float32Array, material: PbrMaterialProps, offsets: ReadonlyMap<string, number>): void {\n const iri = material.iridescence as IridescenceProps | undefined;\n if (!iri?.isEnabled || !offsets.has(\"iridescenceParams\")) {\n return;\n }\n const off = offsets.get(\"iridescenceParams\")! / 4;\n data[off] = iri.intensity ?? 1.0;\n data[off + 1] = iri.indexOfRefraction ?? 1.3;\n data[off + 2] = iri.minimumThickness ?? 100;\n data[off + 3] = iri.maximumThickness ?? 400;\n writeUvTransform(data, offsets, \"iridescenceUV\", iri.texture);\n writeUvTransform(data, offsets, \"iridescenceThicknessUV\", iri.thicknessTexture);\n}\n\nexport const pbrExt: PbrExt = {\n id: \"iridescence\",\n phase: \"base-tex\",\n detect(mat) {\n const iri = (mat as PbrMaterialProps).iridescence;\n if (!iri?.isEnabled) {\n return { f: 0, f2: 0 };\n }\n let f2 = PBR2_HAS_IRIDESCENCE;\n if (iri.texture) {\n f2 |= PBR2_HAS_IRIDESCENCE_MAP;\n if ((iri.texture as { _hasTx?: boolean })._hasTx) {\n f2 |= PBR2_HAS_IRIDESCENCE_UV_TX;\n }\n if ((iri.texture as { _texCoord?: number })._texCoord === 1) {\n f2 |= PBR2_HAS_IRIDESCENCE_UV2;\n }\n }\n if (iri.thicknessTexture) {\n f2 |= PBR2_HAS_IRIDESCENCE_THICKNESS_MAP;\n if ((iri.thicknessTexture as { _hasTx?: boolean })._hasTx) {\n f2 |= PBR2_HAS_IRIDESCENCE_THICKNESS_UV_TX;\n }\n if ((iri.thicknessTexture as { _texCoord?: number })._texCoord === 1) {\n f2 |= PBR2_HAS_IRIDESCENCE_THICKNESS_UV2;\n }\n }\n return { f: 0, f2 };\n },\n frag: (ctx) => createIridescenceFragment(ctx._features, ctx._features2, ctx._meshFeatures),\n writeUbo: writeIridescenceUBO as PbrExt[\"writeUbo\"],\n bind(ctx, entries, b) {\n const iri = (ctx._material as PbrMaterialProps).iridescence;\n if (!iri) {\n return b;\n }\n for (const [flag, key] of IRI_TEX) {\n const tex = iri[key];\n if ((ctx._features2 & flag) !== 0 && tex) {\n entries.push({ binding: b++, resource: tex.view });\n entries.push({ binding: b++, resource: tex.sampler });\n }\n }\n return b;\n },\n textures(mat, t) {\n const iri = (mat as PbrMaterialProps).iridescence;\n if (!iri) {\n return;\n }\n for (const [, key] of IRI_TEX) {\n const tex = iri[key];\n if (tex) {\n t.push(tex);\n }\n }\n },\n};\n"],"names":[],"mappings":";;AAqBA,MAAM,cAAA,GAAiB,CAAA;AACvB,MAAM,6BAA6B,CAAA,IAAK,EAAA;AACxC,MAAM,uCAAuC,CAAA,IAAK,EAAA;AAClD,MAAM,2BAA2B,CAAA,IAAK,EAAA;AACtC,MAAM,qCAAqC,CAAA,IAAK,EAAA;AAChD,MAAM,kBAAkB,CAAA,IAAK,CAAA;AAE7B,MAAM,mBAAA,GAAsB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA;AA4D5B,MAAM,OAAA,GAA4E;AAAA,EAC9E,CAAC,0BAA0B,SAAS,CAAA;AAAA,EACpC,CAAC,oCAAoC,kBAAkB;AAC3D,CAAA;AAEA,SAAS,UAAA,CAAW,SAAA,EAAmB,YAAA,EAAsB,OAAA,EAAyB;AAClF,EAAA,OAAA,CAAQ,YAAY,OAAA,MAAa,CAAA,IAAA,CAAM,YAAA,GAAe,eAAA,MAAqB,IAAI,WAAA,GAAc,UAAA;AACjG;AAEA,SAAS,MAAA,CAAO,IAAA,EAAc,MAAA,EAAgB,KAAA,EAAwB;AAClE,EAAA,OAAO,QAAQ,CAAA,IAAA,EAAO,IAAI,CAAA,wBAAA,EAA2B,IAAI,QAAQ,MAAM,CAAA,eAAA,EAAkB,IAAI,CAAA,KAAA,EAAQ,MAAM,CAAA,YAAA,EAAe,IAAI,UAAU,CAAA,IAAA,EAAO,IAAI,IAAI,MAAM,CAAA,CAAA,CAAA;AACjK;AAEA,SAAS,qBAAqB,IAAA,EAA0B;AACpD,EAAA,OAAO;AAAA,IACH,EAAE,KAAA,EAAO,CAAA,EAAG,IAAI,CAAA,CAAA,CAAA,EAAK,OAAO,WAAA,EAAY;AAAA,IACxC,EAAE,KAAA,EAAO,CAAA,EAAG,IAAI,CAAA,CAAA,CAAA,EAAK,OAAO,WAAA;AAAY,GAC5C;AACJ;AAEA,SAAS,gBAAA,CAAiB,IAAA,EAAoB,OAAA,EAAsC,IAAA,EAAc,GAAA,EAAkC;AAChI,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,CAAA,EAAG,IAAI,CAAA,CAAA,CAAG,CAAA;AACnC,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,CAAA,EAAG,IAAI,CAAA,CAAA,CAAG,CAAA;AACnC,EAAA,IAAI,IAAA,KAAS,MAAA,IAAa,IAAA,KAAS,MAAA,EAAW;AAC1C,IAAA;AAAA,EACJ;AACA,EAAA,MAAM,KAAK,IAAA,GAAO,CAAA;AAClB,EAAA,MAAM,KAAK,IAAA,GAAO,CAAA;AAClB,EAAA,MAAM,EAAA,GAAK,KAAK,MAAA,IAAU,CAAA;AAC1B,EAAA,MAAM,EAAA,GAAK,KAAK,MAAA,IAAU,CAAA;AAC1B,EAAA,MAAM,GAAA,GAAM,KAAK,IAAA,IAAQ,CAAA;AACzB,EAAA,MAAM,EAAA,GAAK,KAAK,OAAA,IAAW,CAAA;AAC3B,EAAA,MAAM,EAAA,GAAK,KAAK,OAAA,IAAW,CAAA;AAC3B,EAAA,IAAI,QAAQ,CAAA,EAAG;AACX,IAAA,IAAA,CAAK,EAAE,CAAA,GAAI,EAAA;AACX,IAAA,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA,GAAI,CAAA;AACf,IAAA,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA,GAAI,CAAA;AACf,IAAA,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA,GAAI,EAAA;AAAA,EACnB,CAAA,MAAO;AACH,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA;AACtB,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA;AACtB,IAAA,IAAA,CAAK,EAAE,IAAI,CAAA,GAAI,EAAA;AACf,IAAA,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA,GAAI,CAAA,GAAI,EAAA;AACnB,IAAA,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA,GAAI,CAAC,CAAA,GAAI,EAAA;AACpB,IAAA,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA,GAAI,CAAA,GAAI,EAAA;AAAA,EACvB;AACA,EAAA,IAAA,CAAK,EAAE,CAAA,GAAI,EAAA;AACX,EAAA,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA,GAAI,EAAA;AACf,EAAA,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA,GAAI,CAAA;AACf,EAAA,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA,GAAI,CAAA;AACnB;AAEA,SAAS,yBAAA,CAA0B,QAAA,EAAkB,SAAA,EAAmB,YAAA,EAA6C;AACjH,EAAA,IAAA,CAAK,SAAA,GAAY,0BAA0B,CAAA,EAAG;AAC1C,IAAA,OAAO,IAAA;AAAA,EACX;AACA,EAAA,MAAM,eAAA,GAAA,CAAmB,YAAY,wBAAA,MAA8B,CAAA;AACnE,EAAA,MAAM,eAAA,GAAA,CAAmB,YAAY,kCAAA,MAAwC,CAAA;AAC7E,EAAA,MAAM,gBAAA,GAAA,CAAoB,YAAY,0BAAA,MAAgC,CAAA;AACtE,EAAA,MAAM,gBAAA,GAAA,CAAoB,YAAY,oCAAA,MAA0C,CAAA;AAChF,EAAA,MAAM,WAA0B,EAAC;AACjC,EAAA,MAAM,YAAwB,CAAC,EAAE,OAAO,mBAAA,EAAqB,KAAA,EAAO,aAAa,CAAA;AACjF,EAAA,IAAI,eAAA,EAAiB;AACjB,IAAA,QAAA,CAAS,IAAA;AAAA,MACL,EAAE,KAAA,EAAO,oBAAA,EAAsB,KAAA,EAAO,EAAE,KAAA,EAAO,SAAA,EAAW,YAAA,EAAc,iBAAA,EAAkB,EAAG,WAAA,EAAa,cAAA,EAAe;AAAA,MACzH,EAAE,KAAA,EAAO,qBAAA,EAAuB,KAAA,EAAO,EAAE,KAAA,EAAO,SAAA,EAAW,YAAA,EAAc,SAAA,EAAU,EAAG,WAAA,EAAa,cAAA;AAAe,KACtH;AACA,IAAA,IAAI,gBAAA,EAAkB;AAClB,MAAA,SAAA,CAAU,IAAA,CAAK,GAAG,oBAAA,CAAqB,eAAe,CAAC,CAAA;AAAA,IAC3D;AAAA,EACJ;AACA,EAAA,IAAI,eAAA,EAAiB;AACjB,IAAA,QAAA,CAAS,IAAA;AAAA,MACL,EAAE,KAAA,EAAO,6BAAA,EAA+B,KAAA,EAAO,EAAE,KAAA,EAAO,SAAA,EAAW,YAAA,EAAc,iBAAA,EAAkB,EAAG,WAAA,EAAa,cAAA,EAAe;AAAA,MAClI,EAAE,KAAA,EAAO,8BAAA,EAAgC,KAAA,EAAO,EAAE,KAAA,EAAO,SAAA,EAAW,YAAA,EAAc,SAAA,EAAU,EAAG,WAAA,EAAa,cAAA;AAAe,KAC/H;AACA,IAAA,IAAI,gBAAA,EAAkB;AAClB,MAAA,SAAA,CAAU,IAAA,CAAK,GAAG,oBAAA,CAAqB,wBAAwB,CAAC,CAAA;AAAA,IACpE;AAAA,EACJ;AAEA,EAAA,MAAM,YAAsB,EAAC;AAC7B,EAAA,IAAI,eAAA,EAAiB;AACjB,IAAA,SAAA,CAAU,IAAA,CAAK,OAAO,eAAA,EAAiB,UAAA,CAAW,WAAW,YAAA,EAAc,wBAAwB,CAAA,EAAG,gBAAgB,CAAC,CAAA;AAAA,EAC3H;AACA,EAAA,IAAI,eAAA,EAAiB;AACjB,IAAA,SAAA,CAAU,IAAA,CAAK,OAAO,wBAAA,EAA0B,UAAA,CAAW,WAAW,YAAA,EAAc,kCAAkC,CAAA,EAAG,gBAAgB,CAAC,CAAA;AAAA,EAC9I;AAEA,EAAA,MAAM,SAAA,GAAY,kBAAkB,oGAAA,GAAuG,8BAAA;AAC3I,EAAA,MAAM,SAAA,GAAY,kBACZ,iKAAA,GACA,8BAAA;AACN,EAAA,OAAO;AAAA,IACH,GAAA,EAAK,aAAA;AAAA,IACL,aAAA,EAAA,CACK,QAAA,IAAY,gCAAA,GAAmC,uBAAA,CAAA,MAA8B,CAAA,IAAA,CAAM,YAAY,4BAAA,MAAkC,CAAA,GAAI,CAAC,aAAa,CAAA,GAAI,MAAA;AAAA,IAC5J,UAAA,EAAY,SAAA;AAAA,IACZ,SAAA,EAAW,QAAA;AAAA,IACX,gBAAA,EAAkB,mBAAA;AAAA,IAClB,cAAA,EAAgB;AAAA,MACZ,GAAI,UAAU,MAAA,GAAS,EAAE,IAAI,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA,EAAE,GAAI,MAAA;AAAA,MACtD,EAAA,EAAI,CAAA;AAAA,uBAAA,EACS,SAAS,CAAA;AAAA,qBAAA,EACX,SAAS,CAAA;AAAA;AAAA;AAAA,CAAA;AAAA;AAIxB,GACJ;AACJ;AAEO,SAAS,mBAAA,CAAoB,IAAA,EAAoB,QAAA,EAA4B,OAAA,EAA4C;AAC5H,EAAA,MAAM,MAAM,QAAA,CAAS,WAAA;AACrB,EAAA,IAAI,CAAC,GAAA,EAAK,SAAA,IAAa,CAAC,OAAA,CAAQ,GAAA,CAAI,mBAAmB,CAAA,EAAG;AACtD,IAAA;AAAA,EACJ;AACA,EAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,CAAI,mBAAmB,CAAA,GAAK,CAAA;AAChD,EAAA,IAAA,CAAK,GAAG,CAAA,GAAI,GAAA,CAAI,SAAA,IAAa,CAAA;AAC7B,EAAA,IAAA,CAAK,GAAA,GAAM,CAAC,CAAA,GAAI,GAAA,CAAI,iBAAA,IAAqB,GAAA;AACzC,EAAA,IAAA,CAAK,GAAA,GAAM,CAAC,CAAA,GAAI,GAAA,CAAI,gBAAA,IAAoB,GAAA;AACxC,EAAA,IAAA,CAAK,GAAA,GAAM,CAAC,CAAA,GAAI,GAAA,CAAI,gBAAA,IAAoB,GAAA;AACxC,EAAA,gBAAA,CAAiB,IAAA,EAAM,OAAA,EAAS,eAAA,EAAiB,GAAA,CAAI,OAAO,CAAA;AAC5D,EAAA,gBAAA,CAAiB,IAAA,EAAM,OAAA,EAAS,wBAAA,EAA0B,GAAA,CAAI,gBAAgB,CAAA;AAClF;AAEO,MAAM,MAAA,GAAiB;AAAA,EAC1B,EAAA,EAAI,aAAA;AAAA,EACJ,KAAA,EAAO,UAAA;AAAA,EACP,OAAO,GAAA,EAAK;AACR,IAAA,MAAM,MAAO,GAAA,CAAyB,WAAA;AACtC,IAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACjB,MAAA,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,CAAA,EAAE;AAAA,IACzB;AACA,IAAA,IAAI,EAAA,GAAK,oBAAA;AACT,IAAA,IAAI,IAAI,OAAA,EAAS;AACb,MAAA,EAAA,IAAM,wBAAA;AACN,MAAA,IAAK,GAAA,CAAI,QAAiC,MAAA,EAAQ;AAC9C,QAAA,EAAA,IAAM,0BAAA;AAAA,MACV;AACA,MAAA,IAAK,GAAA,CAAI,OAAA,CAAmC,SAAA,KAAc,CAAA,EAAG;AACzD,QAAA,EAAA,IAAM,wBAAA;AAAA,MACV;AAAA,IACJ;AACA,IAAA,IAAI,IAAI,gBAAA,EAAkB;AACtB,MAAA,EAAA,IAAM,kCAAA;AACN,MAAA,IAAK,GAAA,CAAI,iBAA0C,MAAA,EAAQ;AACvD,QAAA,EAAA,IAAM,oCAAA;AAAA,MACV;AACA,MAAA,IAAK,GAAA,CAAI,gBAAA,CAA4C,SAAA,KAAc,CAAA,EAAG;AAClE,QAAA,EAAA,IAAM,kCAAA;AAAA,MACV;AAAA,IACJ;AACA,IAAA,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,EAAA,EAAG;AAAA,EACtB,CAAA;AAAA,EACA,IAAA,EAAM,CAAC,GAAA,KAAQ,yBAAA,CAA0B,IAAI,SAAA,EAAW,GAAA,CAAI,UAAA,EAAY,GAAA,CAAI,aAAa,CAAA;AAAA,EACzF,QAAA,EAAU,mBAAA;AAAA,EACV,IAAA,CAAK,GAAA,EAAK,OAAA,EAAS,CAAA,EAAG;AAClB,IAAA,MAAM,GAAA,GAAO,IAAI,SAAA,CAA+B,WAAA;AAChD,IAAA,IAAI,CAAC,GAAA,EAAK;AACN,MAAA,OAAO,CAAA;AAAA,IACX;AACA,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,GAAG,CAAA,IAAK,OAAA,EAAS;AAC/B,MAAA,MAAM,GAAA,GAAM,IAAI,GAAG,CAAA;AACnB,MAAA,IAAA,CAAK,GAAA,CAAI,UAAA,GAAa,IAAA,MAAU,CAAA,IAAK,GAAA,EAAK;AACtC,QAAA,OAAA,CAAQ,KAAK,EAAE,OAAA,EAAS,KAAK,QAAA,EAAU,GAAA,CAAI,MAAM,CAAA;AACjD,QAAA,OAAA,CAAQ,KAAK,EAAE,OAAA,EAAS,KAAK,QAAA,EAAU,GAAA,CAAI,SAAS,CAAA;AAAA,MACxD;AAAA,IACJ;AACA,IAAA,OAAO,CAAA;AAAA,EACX,CAAA;AAAA,EACA,QAAA,CAAS,KAAK,CAAA,EAAG;AACb,IAAA,MAAM,MAAO,GAAA,CAAyB,WAAA;AACtC,IAAA,IAAI,CAAC,GAAA,EAAK;AACN,MAAA;AAAA,IACJ;AACA,IAAA,KAAA,MAAW,GAAG,GAAG,CAAA,IAAK,OAAA,EAAS;AAC3B,MAAA,MAAM,GAAA,GAAM,IAAI,GAAG,CAAA;AACnB,MAAA,IAAI,GAAA,EAAK;AACL,QAAA,CAAA,CAAE,KAAK,GAAG,CAAA;AAAA,MACd;AAAA,IACJ;AAAA,EACJ;AACJ;;;;"}
|
|
1
|
+
{"version":3,"file":"iridescence-fragment.js","sources":["../../../../../src/material/pbr/fragments/iridescence-fragment.ts"],"sourcesContent":["/**\n * Iridescence Fragment\n *\n * Native PBR thin-film iridescence (BJS PBRMaterial.iridescence and\n * KHR_materials_iridescence). Modifies the already-computed base-layer colorF0\n * before direct and IBL lighting consume it.\n */\n\nimport type { BindingDecl, ShaderFragment, UboField } from \"../../../shader/fragment-types.js\";\nimport type { Texture2D } from \"../../../texture/texture-2d.js\";\nimport type { PbrExt } from \"../pbr-flags.js\";\nimport type { IridescenceProps, PbrMaterialProps } from \"../pbr-material.js\";\nimport { PBR_HAS_METALLIC_REFLECTANCE_MAP, PBR_HAS_REFLECTANCE_MAP, PBR2_HAS_REFLECTANCE_FACTORS } from \"../pbr-flag-bits.js\";\n\nconst STAGE_FRAGMENT = 0x2;\nconst PBR2_HAS_IRIDESCENCE = 1 << 17;\nconst PBR2_HAS_IRIDESCENCE_MAP = 1 << 18;\nconst PBR2_HAS_IRIDESCENCE_THICKNESS_MAP = 1 << 19;\nconst PBR2_HAS_IRIDESCENCE_UV_TX = 1 << 20;\nconst PBR2_HAS_IRIDESCENCE_THICKNESS_UV_TX = 1 << 21;\nconst PBR2_HAS_IRIDESCENCE_UV2 = 1 << 22;\nconst PBR2_HAS_IRIDESCENCE_THICKNESS_UV2 = 1 << 23;\nconst IRI_MSH_HAS_UV2 = 1 << 7;\n\nconst IRIDESCENCE_HELPERS = `const IRI_XYZ_TO_REC709:mat3x3<f32>=mat3x3<f32>(\n3.2404542,-0.9692660,0.0556434,\n-1.5371385,1.8760108,-0.2040259,\n-0.4985314,0.0415560,1.0572252);\nfn iri_square3(x:vec3<f32>)->vec3<f32>{return x*x;}\nfn iri_iorFromAirF0(f0:vec3<f32>)->vec3<f32>{\nlet s=sqrt(clamp(f0,vec3<f32>(0.0),vec3<f32>(0.9999)));\nreturn (vec3<f32>(1.0)+s)/(vec3<f32>(1.0)-s);\n}\nfn iri_r0FromIor3(iorT:vec3<f32>,iorI:f32)->vec3<f32>{return iri_square3((iorT-vec3<f32>(iorI))/(iorT+vec3<f32>(iorI)));}\nfn iri_r0FromIor(iorT:f32,iorI:f32)->f32{let r=(iorT-iorI)/(iorT+iorI);return r*r;}\nfn iri_fresSchlick(c:f32,F0:vec3<f32>,F90:vec3<f32>)->vec3<f32>{\nlet t=1.0-c;\nlet t2=t*t;\nreturn F0+(F90-F0)*(t2*t2*t);\n}\nfn iri_evalSensitivity(opd:f32,shift:vec3<f32>)->vec3<f32>{\nlet phase=6.283185307179586*opd*1.0e-9;\nlet val=vec3<f32>(5.4856e-13,4.4201e-13,5.2481e-13);\nlet pos=vec3<f32>(1.6810e+06,1.7953e+06,2.2084e+06);\nlet vr=vec3<f32>(4.3278e+09,9.3046e+09,6.6121e+09);\nvar xyz=val*sqrt(6.283185307179586*vr)*cos(pos*phase+shift)*exp(-(phase*phase)*vr);\nxyz.x=xyz.x+9.7470e-14*sqrt(6.283185307179586*4.5282e+09)*cos(2.2399e+06*phase+shift.x)*exp(-4.5282e+09*phase*phase);\nxyz=xyz/1.0685e-7;\nreturn IRI_XYZ_TO_REC709*xyz;\n}\nfn iri_eval(outsideIor:f32,eta2:f32,cosTheta1:f32,thickness:f32,baseF0:vec3<f32>)->vec3<f32>{\nlet iridescenceIor=mix(outsideIor,eta2,smoothstep(0.0,0.03,thickness));\nlet eta=outsideIor/iridescenceIor;\nlet sinTheta2Sq=eta*eta*(1.0-cosTheta1*cosTheta1);\nlet cosTheta2Sq=1.0-sinTheta2Sq;\nif(cosTheta2Sq<0.0){return vec3<f32>(1.0);}\nlet cosTheta2=sqrt(cosTheta2Sq);\nlet r0=iri_r0FromIor(iridescenceIor,outsideIor);\nlet r12=iri_fresSchlick(cosTheta1,vec3<f32>(r0),vec3<f32>(1.0)).x;\nlet t121=1.0-r12;\nvar phi12=0.0;\nif(iridescenceIor<outsideIor){phi12=3.141592653589793;}\nlet phi21=3.141592653589793-phi12;\nlet baseIor=iri_iorFromAirF0(baseF0);\nlet r1=iri_r0FromIor3(baseIor,iridescenceIor);\nlet r23=iri_fresSchlick(cosTheta2,r1,vec3<f32>(1.0));\nvar phi23=vec3<f32>(0.0);\nif(baseIor.x<iridescenceIor){phi23.x=3.141592653589793;}\nif(baseIor.y<iridescenceIor){phi23.y=3.141592653589793;}\nif(baseIor.z<iridescenceIor){phi23.z=3.141592653589793;}\nlet opd=2.0*iridescenceIor*thickness*cosTheta2;\nlet phi=vec3<f32>(phi21)+phi23;\nlet r123=clamp(vec3<f32>(r12)*r23,vec3<f32>(1e-5),vec3<f32>(0.9999));\nlet smallR123=sqrt(r123);\nlet rs=(t121*t121)*r23/(vec3<f32>(1.0)-r123);\nvar outI=vec3<f32>(r12)+rs;\nvar cm=rs-vec3<f32>(t121);\nfor(var m:i32=1;m<=2;m=m+1){\ncm=cm*smallR123;\noutI=outI+cm*(2.0*iri_evalSensitivity(f32(m)*opd,f32(m)*phi));\n}\nreturn max(outI,vec3<f32>(0.0));\n}`;\n\nconst IRI_TEX: ReadonlyArray<readonly [number, \"texture\" | \"thicknessTexture\"]> = [\n [PBR2_HAS_IRIDESCENCE_MAP, \"texture\"],\n [PBR2_HAS_IRIDESCENCE_THICKNESS_MAP, \"thicknessTexture\"],\n];\n\nfunction uvBaseExpr(features2: number, meshFeatures: number, uv2Flag: number): string {\n return (features2 & uv2Flag) !== 0 && (meshFeatures & IRI_MSH_HAS_UV2) !== 0 ? \"input.uv2\" : \"input.uv\";\n}\n\nfunction uvDecl(name: string, baseUv: string, hasTx: boolean): string {\n return hasTx ? `let ${name}=vec2<f32>(dot(material.${name}m.xy,${baseUv}),dot(material.${name}m.zw,${baseUv}))+material.${name}t.xy;` : `let ${name}=${baseUv};`;\n}\n\nfunction uvTransformUboFields(name: string): UboField[] {\n return [\n { _name: `${name}m`, _type: \"vec4<f32>\" },\n { _name: `${name}t`, _type: \"vec4<f32>\" },\n ];\n}\n\nfunction writeUvTransform(data: Float32Array, offsets: ReadonlyMap<string, number>, name: string, tex: Texture2D | undefined): void {\n const mOff = offsets.get(`${name}m`);\n const tOff = offsets.get(`${name}t`);\n if (mOff === undefined || tOff === undefined) {\n return;\n }\n const mi = mOff / 4;\n const ti = tOff / 4;\n const sx = tex?.uScale ?? 1;\n const sy = tex?.vScale ?? 1;\n const ang = tex?.uAng ?? 0;\n const ox = tex?.uOffset ?? 0;\n const oy = tex?.vOffset ?? 0;\n if (ang === 0) {\n data[mi] = sx;\n data[mi + 1] = 0;\n data[mi + 2] = 0;\n data[mi + 3] = sy;\n } else {\n const c = Math.cos(ang);\n const s = Math.sin(ang);\n data[mi] = c * sx;\n data[mi + 1] = s * sy;\n data[mi + 2] = -s * sx;\n data[mi + 3] = c * sy;\n }\n data[ti] = ox;\n data[ti + 1] = oy;\n data[ti + 2] = 0;\n data[ti + 3] = 0;\n}\n\nfunction createIridescenceFragment(features: number, features2: number, meshFeatures: number): ShaderFragment | null {\n if ((features2 & PBR2_HAS_IRIDESCENCE) === 0) {\n return null;\n }\n const hasIntensityMap = (features2 & PBR2_HAS_IRIDESCENCE_MAP) !== 0;\n const hasThicknessMap = (features2 & PBR2_HAS_IRIDESCENCE_THICKNESS_MAP) !== 0;\n const hasIntensityUvTx = (features2 & PBR2_HAS_IRIDESCENCE_UV_TX) !== 0;\n const hasThicknessUvTx = (features2 & PBR2_HAS_IRIDESCENCE_THICKNESS_UV_TX) !== 0;\n const bindings: BindingDecl[] = [];\n const uboFields: UboField[] = [{ _name: \"iridescenceParams\", _type: \"vec4<f32>\" }];\n if (hasIntensityMap) {\n bindings.push(\n { _name: \"iridescenceTexture\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"iridescenceSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n if (hasIntensityUvTx) {\n uboFields.push(...uvTransformUboFields(\"iridescenceUV\"));\n }\n }\n if (hasThicknessMap) {\n bindings.push(\n { _name: \"iridescenceThicknessTexture\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"iridescenceThicknessSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n if (hasThicknessUvTx) {\n uboFields.push(...uvTransformUboFields(\"iridescenceThicknessUV\"));\n }\n }\n\n const scopeVars: string[] = [];\n if (hasIntensityMap) {\n scopeVars.push(uvDecl(\"iridescenceUV\", uvBaseExpr(features2, meshFeatures, PBR2_HAS_IRIDESCENCE_UV2), hasIntensityUvTx));\n }\n if (hasThicknessMap) {\n scopeVars.push(uvDecl(\"iridescenceThicknessUV\", uvBaseExpr(features2, meshFeatures, PBR2_HAS_IRIDESCENCE_THICKNESS_UV2), hasThicknessUvTx));\n }\n\n const intensity = hasIntensityMap ? \"material.iridescenceParams.x*textureSample(iridescenceTexture,iridescenceSampler_,iridescenceUV).r\" : \"material.iridescenceParams.x\";\n const thickness = hasThicknessMap\n ? \"mix(material.iridescenceParams.z,material.iridescenceParams.w,textureSample(iridescenceThicknessTexture,iridescenceThicknessSampler_,iridescenceThicknessUV).g)\"\n : \"material.iridescenceParams.w\";\n return {\n _id: \"iridescence\",\n _dependencies:\n (features & (PBR_HAS_METALLIC_REFLECTANCE_MAP | PBR_HAS_REFLECTANCE_MAP)) !== 0 || (features2 & PBR2_HAS_REFLECTANCE_FACTORS) !== 0 ? [\"reflectance\"] : undefined,\n _uboFields: uboFields,\n _bindings: bindings,\n _helperFunctions: IRIDESCENCE_HELPERS,\n _fragmentSlots: {\n ...(scopeVars.length ? { SV: scopeVars.join(\"\\n\") } : undefined),\n MF: `{\nlet iriIntensity=clamp(${intensity},0.0,1.0);\nlet iriThickness=max(${thickness},0.0);\nlet iriF0=iri_eval(1.0,max(material.iridescenceParams.y,1.0001),NdotV,iriThickness,colorF0);\ncolorF0=mix(colorF0,iriF0,iriIntensity);\n}`,\n },\n };\n}\n\nexport function writeIridescenceUBO(data: Float32Array, material: PbrMaterialProps, offsets: ReadonlyMap<string, number>): void {\n const iri = material.iridescence as IridescenceProps | undefined;\n if (!iri?.isEnabled || !offsets.has(\"iridescenceParams\")) {\n return;\n }\n const off = offsets.get(\"iridescenceParams\")! / 4;\n data[off] = iri.intensity ?? 1.0;\n data[off + 1] = iri.indexOfRefraction ?? 1.3;\n data[off + 2] = iri.minimumThickness ?? 100;\n data[off + 3] = iri.maximumThickness ?? 400;\n writeUvTransform(data, offsets, \"iridescenceUV\", iri.texture);\n writeUvTransform(data, offsets, \"iridescenceThicknessUV\", iri.thicknessTexture);\n}\n\nexport const pbrExt: PbrExt = {\n id: \"iridescence\",\n phase: \"base-tex\",\n detect(mat) {\n const iri = (mat as PbrMaterialProps).iridescence;\n if (!iri?.isEnabled) {\n return { f: 0, f2: 0 };\n }\n let f2 = PBR2_HAS_IRIDESCENCE;\n if (iri.texture) {\n f2 |= PBR2_HAS_IRIDESCENCE_MAP;\n if ((iri.texture as { _hasTx?: boolean })._hasTx) {\n f2 |= PBR2_HAS_IRIDESCENCE_UV_TX;\n }\n if ((iri.texture as { _texCoord?: number })._texCoord === 1) {\n f2 |= PBR2_HAS_IRIDESCENCE_UV2;\n }\n }\n if (iri.thicknessTexture) {\n f2 |= PBR2_HAS_IRIDESCENCE_THICKNESS_MAP;\n if ((iri.thicknessTexture as { _hasTx?: boolean })._hasTx) {\n f2 |= PBR2_HAS_IRIDESCENCE_THICKNESS_UV_TX;\n }\n if ((iri.thicknessTexture as { _texCoord?: number })._texCoord === 1) {\n f2 |= PBR2_HAS_IRIDESCENCE_THICKNESS_UV2;\n }\n }\n return { f: 0, f2 };\n },\n frag: (ctx) => createIridescenceFragment(ctx._features, ctx._features2, ctx._meshFeatures),\n writeUbo: writeIridescenceUBO as PbrExt[\"writeUbo\"],\n bind(ctx, entries, b) {\n const iri = (ctx._material as PbrMaterialProps).iridescence;\n if (!iri) {\n return b;\n }\n for (const [flag, key] of IRI_TEX) {\n const tex = iri[key];\n if ((ctx._features2 & flag) !== 0 && tex) {\n entries.push({ binding: b++, resource: tex.view });\n entries.push({ binding: b++, resource: tex.sampler });\n }\n }\n return b;\n },\n textures(mat, t) {\n const iri = (mat as PbrMaterialProps).iridescence;\n if (!iri) {\n return;\n }\n for (const [, key] of IRI_TEX) {\n const tex = iri[key];\n if (tex) {\n t.push(tex);\n }\n }\n },\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { getTrilinearAnisotropicSampler } from '../../../resource/trilinear-anisotropic-sampler.js';
|
|
2
|
-
import { PBR2_HAS_REFRACTION,
|
|
2
|
+
import { PBR2_HAS_REFRACTION, PBR_HAS_THICKNESS_MAP } from '../pbr-flag-bits.js';
|
|
3
3
|
|
|
4
|
+
const PBR2_HAS_VOLUME = 1 << 5;
|
|
5
|
+
const PBR2_HAS_REFRACTION_MAP = 1 << 6;
|
|
6
|
+
const PBR2_HAS_THICKNESS_GLTF_CHANNEL = 1 << 7;
|
|
7
|
+
const PBR2_LINEAR_IMAGE_PROCESSING = 1 << 14;
|
|
8
|
+
const PBR2_HAS_DISPERSION = 1 << 20;
|
|
4
9
|
const LINEAR_IMAGE_PROCESSING_SLOTS = { NI: `if(scene.vImageInfos.w>=0.0){`, BC: `}` };
|
|
5
10
|
function makeRefractionMod(hasVolume, hasMap, hasThicknessMap, useGltfThicknessChannel, hasDispersion, dispersionSampleWgsl) {
|
|
6
11
|
const thicknessScaleLine = hasVolume || hasThicknessMap ? `let ts=max(length(mesh.world[0].xyz),max(length(mesh.world[1].xyz),length(mesh.world[2].xyz)));` : ``;
|
|
@@ -220,5 +225,5 @@ function makeRefractionRttExt(dispersionSampleWgsl) {
|
|
|
220
225
|
};
|
|
221
226
|
}
|
|
222
227
|
|
|
223
|
-
export { makeRefractionRttExt };
|
|
228
|
+
export { PBR2_HAS_REFRACTION_MAP, PBR2_HAS_VOLUME, makeRefractionRttExt };
|
|
224
229
|
//# sourceMappingURL=refraction-rtt-fragment.js.map
|