@meimu/mutracer 0.3.0 → 0.3.1
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 +222 -0
- package/LICENSES/FidelityFX-FSR.txt +19 -0
- package/LICENSES/pbrt-v4-Apache-2.0.txt +202 -0
- package/THIRD_PARTY_NOTICES.md +18 -4
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +6260 -5580
- package/docs/api.md +45 -18
- package/docs/materials.md +4 -2
- package/docs/performance.md +7 -0
- package/docs/post-processing.md +62 -9
- package/docs/progressive-rendering.md +3 -0
- package/docs/sampling.md +4 -0
- package/docs/technical/acceleration.md +52 -0
- package/docs/technical/aovs.md +79 -0
- package/docs/technical/caustics.md +109 -0
- package/docs/technical/continuous-spectrum.md +29 -0
- package/docs/technical/display-upscale.md +82 -0
- package/docs/technical/openpbr.md +99 -0
- package/docs/technical/pbrt-import.md +168 -0
- package/docs/technical/tiling.md +74 -0
- package/docs/technical/webgl.md +53 -0
- package/docs/viewer.md +11 -1
- package/lib/Display.d.ts +19 -5
- package/lib/Display.js +10 -7
- package/lib/Display.js.map +1 -1
- package/lib/Engine.d.ts +2 -1
- package/lib/Engine.js +30 -2
- package/lib/Engine.js.map +1 -1
- package/lib/Render.d.ts +20 -11
- package/lib/Render.js +32 -7
- package/lib/Render.js.map +1 -1
- package/lib/main.d.ts +3 -1
- package/lib/main.js +1 -0
- package/lib/main.js.map +1 -1
- package/lib/oidn.d.ts +1 -1
- package/lib/renderer/AovPrimitiveCache.js +39 -8
- package/lib/renderer/AovPrimitiveCache.js.map +1 -1
- package/lib/renderer/DisplayPostProcess.d.ts +8 -3
- package/lib/renderer/DisplayPostProcess.js +51 -18
- package/lib/renderer/DisplayPostProcess.js.map +1 -1
- package/lib/renderer/MaterialData.js +7 -2
- package/lib/renderer/MaterialData.js.map +1 -1
- package/lib/renderer/RenderingPipeline.d.ts +7 -1
- package/lib/renderer/RenderingPipeline.js.map +1 -1
- package/lib/renderer/TileRender.d.ts +2 -2
- package/lib/renderer/TileRender.js +128 -7
- package/lib/renderer/TileRender.js.map +1 -1
- package/lib/renderer/WGPUAov.d.ts +6 -1
- package/lib/renderer/WGPUAov.js +108 -14
- package/lib/renderer/WGPUAov.js.map +1 -1
- package/lib/renderer/WGPUCanvasSurface.js +12 -1
- package/lib/renderer/WGPUCanvasSurface.js.map +1 -1
- package/lib/renderer/WGPUEnvMapDistribution.js +19 -19
- package/lib/renderer/WGPUFullQuadPass.js +3 -3
- package/lib/renderer/WGPURayTraceOutput.js +12 -12
- package/lib/renderer/WGPURayTracePass.d.ts +17 -4
- package/lib/renderer/WGPURayTracePass.js +194 -71
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.js +46 -40
- package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLAov.js +3 -3
- package/lib/renderer/WebGLAov.js.map +1 -1
- package/lib/renderer/WebGLFullQuadPass.d.ts +1 -1
- package/lib/renderer/WebGLFullQuadPass.js +8 -2
- package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
- package/lib/renderer/WebGLJNLMDenoiser.js +66 -66
- package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -1
- package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
- package/lib/renderer/WebGLRayTracePass.d.ts +14 -10
- package/lib/renderer/WebGLRayTracePass.js +115 -111
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/WebGLRenderingPipeline.js +10 -3
- package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLSkyBaker.js +57 -57
- package/lib/renderer/aov.d.ts +13 -1
- package/lib/renderer/aov.js +21 -2
- package/lib/renderer/aov.js.map +1 -1
- package/lib/renderer/aovDisplay.js +2 -2
- package/lib/renderer/aovDisplay.js.map +1 -1
- package/lib/renderer/binnedSahBvh.d.ts +2 -1
- package/lib/renderer/binnedSahBvh.js +24 -17
- package/lib/renderer/binnedSahBvh.js.map +1 -1
- package/lib/renderer/bvhAccel.d.ts +3 -1
- package/lib/renderer/bvhAccel.js +36 -6
- package/lib/renderer/bvhAccel.js.map +1 -1
- package/lib/renderer/cameraUniform.d.ts +1 -1
- package/lib/renderer/cameraUniform.js +6 -2
- package/lib/renderer/cameraUniform.js.map +1 -1
- package/lib/renderer/compactVertices.d.ts +14 -0
- package/lib/renderer/compactVertices.js +124 -0
- package/lib/renderer/compactVertices.js.map +1 -0
- package/lib/renderer/easu.d.ts +11 -0
- package/lib/renderer/easu.js +156 -0
- package/lib/renderer/easu.js.map +1 -0
- package/lib/renderer/geometryUpdateState.d.ts +1 -0
- package/lib/renderer/geometryUpdateState.js.map +1 -1
- package/lib/renderer/geometryUpdates.js +3 -2
- package/lib/renderer/geometryUpdates.js.map +1 -1
- package/lib/renderer/glsl/aovDisplay.frag.js +5 -5
- package/lib/renderer/glsl/aovReflectance.glsl.js +35 -35
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
- package/lib/renderer/glsl/aovTrace.frag.js +44 -36
- package/lib/renderer/glsl/aovTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.js +16 -0
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/cameraRay.glsl.d.ts +1 -1
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -16
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +8 -8
- package/lib/renderer/glsl/chunks/envMap.glsl.js +67 -67
- package/lib/renderer/glsl/chunks/intersect.glsl.js +390 -375
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +120 -120
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +562 -562
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +4 -4
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +37 -35
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +70 -74
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +107 -88
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +11 -11
- package/lib/renderer/glsl/chunks/sampling.glsl.js +77 -77
- package/lib/renderer/glsl/chunks/sobol.glsl.js +70 -70
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.d.ts +6 -0
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js +47 -0
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
- package/lib/renderer/glsl/depthQuery.frag.js +12 -6
- package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +10 -10
- package/lib/renderer/glsl/rayTrace.frag.js +233 -170
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +10 -9
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +58 -58
- package/lib/renderer/gpuMemory.js +1 -1
- package/lib/renderer/gpuMemory.js.map +1 -1
- package/lib/renderer/openPbrEnergyLut.d.ts +2 -1
- package/lib/renderer/openPbrEnergyLut.js +18 -1
- package/lib/renderer/openPbrEnergyLut.js.map +1 -1
- package/lib/renderer/pathLimits.d.ts +5 -4
- package/lib/renderer/pathLimits.js +6 -5
- package/lib/renderer/pathLimits.js.map +1 -1
- package/lib/renderer/prepareMeshBVH.d.ts +2 -0
- package/lib/renderer/prepareMeshBVH.js +5 -3
- package/lib/renderer/prepareMeshBVH.js.map +1 -1
- package/lib/renderer/progressiveScheduler.js +1 -1
- package/lib/renderer/progressiveScheduler.js.map +1 -1
- package/lib/renderer/renderPipeline.d.ts +4 -0
- package/lib/renderer/renderPipeline.js +1 -0
- package/lib/renderer/renderPipeline.js.map +1 -1
- package/lib/renderer/researchTransport.d.ts +1 -1
- package/lib/renderer/researchTransport.js.map +1 -1
- package/lib/renderer/sceneAssembly.d.ts +1 -1
- package/lib/renderer/sceneAssembly.js +4 -3
- package/lib/renderer/sceneAssembly.js.map +1 -1
- package/lib/renderer/sceneChangeDetector.d.ts +1 -1
- package/lib/renderer/sceneChangeDetector.js +3 -1
- package/lib/renderer/sceneChangeDetector.js.map +1 -1
- package/lib/renderer/sceneLayoutSchema.d.ts +1 -0
- package/lib/renderer/sceneLayoutSchema.js +2 -2
- package/lib/renderer/sceneLayoutSchema.js.map +1 -1
- package/lib/renderer/scenePreparation.d.ts +3 -2
- package/lib/renderer/scenePreparation.js +18 -2
- package/lib/renderer/scenePreparation.js.map +1 -1
- package/lib/renderer/scratchSampling.js +6 -6
- package/lib/renderer/spectrum.js +2 -2
- package/lib/renderer/staticBvhPreparation.d.ts +9 -0
- package/lib/renderer/staticBvhPreparation.js +8 -2
- package/lib/renderer/staticBvhPreparation.js.map +1 -1
- package/lib/renderer/surfaceHit.d.ts +10 -0
- package/lib/renderer/surfaceHit.js +22 -0
- package/lib/renderer/surfaceHit.js.map +1 -0
- package/lib/renderer/tangentRequirements.d.ts +2 -0
- package/lib/renderer/tangentRequirements.js +7 -0
- package/lib/renderer/tangentRequirements.js.map +1 -0
- package/lib/renderer/textureAtlas.d.ts +4 -0
- package/lib/renderer/textureAtlas.js +48 -2
- package/lib/renderer/textureAtlas.js.map +1 -1
- package/lib/renderer/webgl.js +4 -0
- package/lib/renderer/webgl.js.map +1 -1
- package/lib/renderer/webglVertexAttributes.d.ts +17 -0
- package/lib/renderer/webglVertexAttributes.js +44 -0
- package/lib/renderer/webglVertexAttributes.js.map +1 -0
- package/lib/renderer/wgpuBindlessSource.js +2 -2
- package/lib/renderer/wgpuMaterialConstants.js +4 -3
- package/lib/renderer/wgpuMaterialConstants.js.map +1 -1
- package/lib/renderer/wgpuSceneUniform.js +2 -2
- package/lib/renderer/wgpuSceneUniform.js.map +1 -1
- package/lib/renderer/wgpuShaderSource.d.ts +15 -0
- package/lib/renderer/wgpuShaderSource.js +1 -1
- package/lib/renderer/wgpuShaderSource.js.map +1 -1
- package/lib/renderer/wgsl/aovCompact.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/aovCompact.wgsl.js +26 -0
- package/lib/renderer/wgsl/aovCompact.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovDisplay.wgsl.js +9 -9
- package/lib/renderer/wgsl/aovReflectance.wgsl.js +39 -39
- package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +1 -1
- package/lib/renderer/wgsl/aovResolve.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/aovResolve.wgsl.js +21 -2
- package/lib/renderer/wgsl/aovResolve.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js +2 -2
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/aovTrace.wgsl.js +31 -31
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js +56 -0
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/bloom.wgsl.js +18 -18
- package/lib/renderer/wgsl/causticLight.compute.d.ts +1 -1
- package/lib/renderer/wgsl/causticLight.compute.js +121 -119
- package/lib/renderer/wgsl/causticLight.compute.js.map +1 -1
- package/lib/renderer/wgsl/chunks/background.wgsl.js +46 -46
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +30 -30
- package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +6 -2
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +550 -542
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +18 -16
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +2 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +70 -69
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +593 -593
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +118 -118
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +4 -1
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +32 -26
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +114 -114
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +159 -137
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +8 -8
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +74 -74
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +74 -74
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.d.ts +6 -0
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js +66 -0
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js +61 -0
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.js +99 -97
- package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
- package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/depthQuery.wgsl.js +11 -2
- package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/easu.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/easu.wgsl.js +80 -0
- package/lib/renderer/wgsl/easu.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.d.ts +21 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.js +230 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/jnlm.compute.js +74 -74
- package/lib/renderer/wgsl/jnlm.compute.js.map +1 -1
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +26 -26
- package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +3 -3
- package/lib/renderer/wgsl/photonMap.compute.js +89 -89
- package/lib/renderer/wgsl/proceduralSky.compute.js +61 -61
- package/lib/renderer/wgsl/rayTrace.compute.d.ts +14 -0
- package/lib/renderer/wgsl/rayTrace.compute.js +395 -333
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/Scene.js.map +1 -1
- package/lib/settings/render.d.ts +11 -0
- package/lib/settings/render.js +1 -0
- package/lib/settings/render.js.map +1 -1
- package/lib/util/fromTHREE.js +21 -14
- package/lib/util/fromTHREE.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +5 -2
- package/lib/oidnBundledWeights.cdn.d.ts +0 -2
- package/lib/oidnBundledWeights.cdn.js +0 -5
- package/lib/oidnBundledWeights.cdn.js.map +0 -1
- package/lib/renderer/bvh.worker.d.ts +0 -1
- package/lib/renderer/bvh.worker.js +0 -16
- package/lib/renderer/bvh.worker.js.map +0 -1
- package/lib/renderer/bvhWorkerBuild.d.ts +0 -13
- package/lib/renderer/bvhWorkerBuild.js +0 -17
- package/lib/renderer/bvhWorkerBuild.js.map +0 -1
- package/lib/renderer/lightCore.d.ts +0 -12
- package/lib/renderer/lightCore.js +0 -13
- package/lib/renderer/lightCore.js.map +0 -1
- package/lib/renderer/materialCore.d.ts +0 -8
- package/lib/renderer/materialCore.js +0 -9
- package/lib/renderer/materialCore.js.map +0 -1
- package/lib/scene/PixelTexture.d.ts +0 -6
- package/lib/scene/PixelTexture.js +0 -10
- package/lib/scene/PixelTexture.js.map +0 -1
- package/lib/util/studioLighting.d.ts +0 -18
- package/lib/util/studioLighting.js +0 -36
- package/lib/util/studioLighting.js.map +0 -1
|
@@ -5,7 +5,7 @@ import { mapAlphaUsageConstants } from '../../materialConstants.js';
|
|
|
5
5
|
// (https://github.com/hoverinc/ray-tracing-renderer).
|
|
6
6
|
// Copyright (c) 2019 HOVER, MIT license; see LICENSES/RayTracingRenderer-MIT.txt.
|
|
7
7
|
import { materialAlphaModeConstants } from '../../materialConstants.js';
|
|
8
|
-
export function createMaterialBufferWgsl({ hasAnisotropyDirections = true, hasCoatNormals = false, hasSceneAlpha = true, hasTransmission = true, caustics = false, hasMetalness = true } = {}) {
|
|
8
|
+
export function createMaterialBufferWgsl({ independentTextures = false, hasAnisotropyDirections = true, hasCoatNormals = false, hasSceneAlpha = true, hasTransmission = true, caustics = false, hasMetalness = true } = {}) {
|
|
9
9
|
const alphaModeAssignment = hasSceneAlpha
|
|
10
10
|
? '(*ma).alphaMode = i32(matData.alphaMode);'
|
|
11
11
|
: '';
|
|
@@ -20,7 +20,7 @@ else if ((*ma).alphaMode == ${materialAlphaModeConstants.mask}) {
|
|
|
20
20
|
: '(*ma).alpha = 1.0;';
|
|
21
21
|
return /* wgsl */ `
|
|
22
22
|
|
|
23
|
-
${hasAnisotropyDirections ? /* wgsl */ `fn
|
|
23
|
+
${hasAnisotropyDirections ? /* wgsl */ `fn fl(roughness: f32, strength: f32) -> vec2f {
|
|
24
24
|
if (strength == 0.0) { return vec2f(roughness, 0.0); }
|
|
25
25
|
let u = roughness * roughness;
|
|
26
26
|
let a = u + (1.0 - u) * strength * strength;
|
|
@@ -29,56 +29,57 @@ return vec2f(pow((a*a + u*u) * 0.5, 0.25), clamp(1.0 - u/a, 0.0, 1.0));
|
|
|
29
29
|
}
|
|
30
30
|
` : /* wgsl */ ``}
|
|
31
31
|
|
|
32
|
-
fn
|
|
32
|
+
fn np(c: vec3f) -> vec3f {
|
|
33
33
|
return mix(pow(c * 0.9478672986 + 0.0521327014, vec3f(2.4)), c * 0.0773993808, vec3f(c < vec3f(0.04045)));
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
fn decodeMapColor(idx: i32, c: vec3f) -> vec3f {
|
|
37
37
|
if (mapInfo[idx + NUM_MAPS * 2].y > 0.5) { return c; }
|
|
38
|
-
return
|
|
38
|
+
return np(c);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
fn af(val: i32) -> vec2f {
|
|
42
42
|
return vec2f(f32(val >> 8), f32(val & 0xff) / 255.0);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
fn
|
|
45
|
+
fn getMapSize(idx: i32) -> vec2f {
|
|
46
46
|
return mapInfo[idx].xy;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
fn
|
|
49
|
+
fn getMapLayer(idx: i32) -> i32 {
|
|
50
50
|
return i32(floor(mapInfo[idx].z));
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
fn
|
|
53
|
+
fn getMapOffset(idx: i32) -> vec2f {
|
|
54
54
|
return vec2f(fract(mapInfo[idx].z), mapInfo[idx].w);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
fn
|
|
57
|
+
fn gi(value: f32, mode: f32) -> f32 {
|
|
58
58
|
if (mode < 0.5) { return fract(value); }
|
|
59
59
|
if (mode < 1.5) { return clamp(value, 0.0, 1.0); }
|
|
60
60
|
return 1.0 - abs(1.0 - (value - 2.0 * floor(value * 0.5)));
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
fn
|
|
63
|
+
fn jj(idx: i32, uv: vec2f) -> vec2f {
|
|
64
64
|
let transform = mapInfo[idx + NUM_MAPS];
|
|
65
65
|
let modes = mapInfo[idx + NUM_MAPS * 2].zw;
|
|
66
66
|
let value = uv * transform.xy + transform.zw;
|
|
67
|
-
return vec2f(
|
|
67
|
+
return vec2f(gi(value.x, modes.x), gi(value.y, modes.y));
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
fn
|
|
71
|
-
let
|
|
72
|
-
|
|
73
|
-
let
|
|
74
|
-
let
|
|
75
|
-
let
|
|
76
|
-
let
|
|
70
|
+
fn getMapUV(idx: i32, uv: vec2f) -> vec2f {
|
|
71
|
+
${independentTextures ? ` let wq = 0.5 / getMapSize(idx);
|
|
72
|
+
return clamp(jj(idx, uv), wq, 1.0 - wq);` : ` let sZ = jj(idx, uv);
|
|
73
|
+
let jT = 1.0 / vec2f(textureDimensions(map).xy);
|
|
74
|
+
let eg = getMapOffset(idx);
|
|
75
|
+
let lf = getMapSize(idx) + jT;
|
|
76
|
+
let qy = eg - 0.5 * jT;
|
|
77
|
+
let mM = eg + lf - jT;
|
|
77
78
|
return clamp(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
)
|
|
79
|
+
qy + sZ * lf,
|
|
80
|
+
eg,
|
|
81
|
+
mM
|
|
82
|
+
);`}
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
fn getMapUvSet(idx: i32, uv: vec2f, uv1: vec2f) -> vec2f {
|
|
@@ -86,28 +87,28 @@ return select(uv, uv1, mapInfo[idx + NUM_MAPS * 2].x > 0.5);
|
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
fn sampleMap(idx: i32, uv: vec2f) -> vec4f {
|
|
89
|
-
let size = vec2i(round(
|
|
90
|
-
let
|
|
90
|
+
let size = ${independentTextures ? 'vec2i(getMapSize(idx))' : 'vec2i(round(getMapSize(idx) * vec2f(textureDimensions(map).xy) + vec2f(1.0)))'};
|
|
91
|
+
let texel = jj(idx, uv) * vec2f(size) - vec2f(0.5);
|
|
91
92
|
let modes = mapInfo[idx + NUM_MAPS * 2].zw;
|
|
92
93
|
|
|
93
94
|
|
|
94
|
-
if ((size.x > 1 && modes.x < 0.5 && (
|
|
95
|
-
(size.y > 1 && modes.y < 0.5 && (
|
|
96
|
-
let base = vec2i(floor(
|
|
97
|
-
let weight = fract(
|
|
98
|
-
let origin = vec2i(round(
|
|
95
|
+
if ((size.x > 1 && modes.x < 0.5 && (texel.x < 0.0 || texel.x > f32(size.x - 1))) ||
|
|
96
|
+
(size.y > 1 && modes.y < 0.5 && (texel.y < 0.0 || texel.y > f32(size.y - 1)))) {
|
|
97
|
+
let base = vec2i(floor(texel));
|
|
98
|
+
let weight = fract(texel);
|
|
99
|
+
let origin = ${independentTextures ? 'vec2i(0)' : 'vec2i(round(getMapOffset(idx) * vec2f(textureDimensions(map).xy) - vec2f(0.5)))'};
|
|
99
100
|
return mix(
|
|
100
|
-
mix(
|
|
101
|
-
mix(
|
|
101
|
+
mix(eX(idx, base, size, origin, modes), eX(idx, base + vec2i(1, 0), size, origin, modes), weight.x),
|
|
102
|
+
mix(eX(idx, base + vec2i(0, 1), size, origin, modes), eX(idx, base + vec2i(1, 1), size, origin, modes), weight.x), weight.y);
|
|
102
103
|
}
|
|
103
|
-
return textureSampleLevel(map, mapSampler,
|
|
104
|
+
return ${independentTextures ? 'textureSampleLevel(map[getMapLayer(idx)], mapSampler, getMapUV(idx, uv), 0.0)' : 'textureSampleLevel(map, mapSampler, getMapUV(idx, uv), getMapLayer(idx), 0.0)'};
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
fn
|
|
107
|
-
var p = clamp(
|
|
108
|
-
if (modes.x < 0.5) { p.x = ((
|
|
109
|
-
if (modes.y < 0.5) { p.y = ((
|
|
110
|
-
return textureLoad(map, origin + p,
|
|
107
|
+
fn eX(idx: i32, jV: vec2i, size: vec2i, origin: vec2i, modes: vec2f) -> vec4f {
|
|
108
|
+
var p = clamp(jV, vec2i(0), size - vec2i(1));
|
|
109
|
+
if (modes.x < 0.5) { p.x = ((jV.x % size.x) + size.x) % size.x; }
|
|
110
|
+
if (modes.y < 0.5) { p.y = ((jV.y % size.y) + size.y) % size.y; }
|
|
111
|
+
return ${independentTextures ? 'textureLoad(map[getMapLayer(idx)], p, 0)' : 'textureLoad(map, origin + p, getMapLayer(idx), 0)'};
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
|
|
@@ -137,14 +138,14 @@ return emission;
|
|
|
137
138
|
|
|
138
139
|
fn aL(roughness: f32, anisotropy: f32) -> vec2f {
|
|
139
140
|
let alpha = roughness * roughness;
|
|
140
|
-
let
|
|
141
|
-
if (anisotropy == 0.0) { return vec2f(max(
|
|
142
|
-
let
|
|
143
|
-
let
|
|
144
|
-
return max(vec2f(
|
|
141
|
+
let rf = ROUGHNESS_MIN * ROUGHNESS_MIN;
|
|
142
|
+
if (anisotropy == 0.0) { return vec2f(max(rf, alpha)); }
|
|
143
|
+
let da = 1.0 - anisotropy;
|
|
144
|
+
let uU = alpha * sqrt(2.0 / (1.0 + da * da));
|
|
145
|
+
return max(vec2f(rf), vec2f(uU, da * uU));
|
|
145
146
|
}
|
|
146
147
|
|
|
147
|
-
fn
|
|
148
|
+
fn lO(instanceIndex: i32) -> vec3f {
|
|
148
149
|
if (instanceIndex < 0) { return vec3f(1.0); }
|
|
149
150
|
return instancesBuffer[instanceIndex * ${INSTANCE_VEC4_STRIDE} + 9].xyz;
|
|
150
151
|
}
|
|
@@ -230,11 +231,11 @@ if (USE_METALLIC_ROUGHNESS_MAPS) {
|
|
|
230
231
|
|
|
231
232
|
let mrtMapIndex = i32(matData.mrtMapIndex);
|
|
232
233
|
if (mrtMapIndex >= 0) {
|
|
233
|
-
let
|
|
234
|
+
let ga = sampleMap(
|
|
234
235
|
mrtMapIndex, getMapUvSet(mrtMapIndex, uv, uv1)
|
|
235
236
|
);
|
|
236
|
-
(*ma).baseMetalness *=
|
|
237
|
-
(*ma).specularRoughness *=
|
|
237
|
+
(*ma).baseMetalness *= ga.b;
|
|
238
|
+
(*ma).specularRoughness *= ga.g;
|
|
238
239
|
}
|
|
239
240
|
}
|
|
240
241
|
|
|
@@ -267,16 +268,16 @@ ${hasAnisotropyDirections ? /* wgsl */ `
|
|
|
267
268
|
(*ma).coatAnisotropyRotation = matData.coatAnisotropyRotation;
|
|
268
269
|
if (USE_ANISOTROPY_MAPS && matData.anisotropyMapIndex >= 0.0) {
|
|
269
270
|
let index = i32(matData.anisotropyMapIndex);
|
|
270
|
-
let
|
|
271
|
-
(*ma).specularAnisotropy *=
|
|
272
|
-
let direction =
|
|
271
|
+
let texel = sampleMap(index, getMapUvSet(index, uv, uv1));
|
|
272
|
+
(*ma).specularAnisotropy *= texel.b;
|
|
273
|
+
let direction = texel.rg * 2.0 - 1.0;
|
|
273
274
|
if (dot(direction, direction) > 1e-4) { (*ma).anisotropyDirection = normalize(direction); }
|
|
274
275
|
(*ma).anisotropyDirectionEnabled = true;
|
|
275
276
|
}
|
|
276
277
|
if (matData.specularAnisotropyModel > 0.5 && (*ma).specularAnisotropy > 0.0) {
|
|
277
|
-
let
|
|
278
|
-
(*ma).specularRoughness =
|
|
279
|
-
(*ma).specularAnisotropy =
|
|
278
|
+
let vG = fl(clamp((*ma).specularRoughness, 0.0, 1.0), (*ma).specularAnisotropy);
|
|
279
|
+
(*ma).specularRoughness = vG.x;
|
|
280
|
+
(*ma).specularAnisotropy = vG.y;
|
|
280
281
|
}
|
|
281
282
|
if ((*ma).anisotropyDirectionEnabled) {
|
|
282
283
|
let theta = matData.specularAnisotropyRotation;
|
|
@@ -288,14 +289,14 @@ let d = (*ma).anisotropyDirection;
|
|
|
288
289
|
|
|
289
290
|
|
|
290
291
|
if ((*ma).coatWeight > 0.0 && (*ma).coatRoughness > 0.0) {
|
|
291
|
-
let
|
|
292
|
-
let
|
|
292
|
+
let im = (*ma).specularRoughness * (*ma).specularRoughness;
|
|
293
|
+
let iq = (*ma).coatRoughness * (*ma).coatRoughness;
|
|
293
294
|
(*ma).specularRoughness = mix((*ma).specularRoughness,
|
|
294
|
-
pow(min(1.0,
|
|
295
|
+
pow(min(1.0, im * im + 2.0 * iq * iq), 0.25), (*ma).coatWeight);
|
|
295
296
|
}
|
|
296
297
|
${hasTransmission ? '' : /* wgsl */ `(*ma).transmissionWeight = 0.0;`}
|
|
297
298
|
${hasMetalness ? '' : /* wgsl */ `(*ma).baseMetalness = 0.0;`}
|
|
298
|
-
let color =
|
|
299
|
+
let color = lO(instanceIndex) * vertexColor;
|
|
299
300
|
(*ma).baseColor *= color;
|
|
300
301
|
if ((*ma).materialType == UNLIT) { (*ma).emission *= color; }
|
|
301
302
|
|
|
@@ -308,39 +309,39 @@ let specularAlpha = aL((*ma).specularRoughness, (*ma).specularAnisotropy);
|
|
|
308
309
|
(*ma).alphaY = specularAlpha.y;
|
|
309
310
|
}
|
|
310
311
|
|
|
311
|
-
fn
|
|
312
|
+
fn qa(materialIndex: i32, uv: vec2f, normal: vec3f, dp1: vec3f, dp2: vec3f, pU: vec2f, pV: vec2f) -> vec3f {
|
|
312
313
|
let matData = materialsBuffer[materialIndex];
|
|
313
314
|
let normalMapIndex = i32(matData.normalMapIndex);
|
|
314
315
|
if (normalMapIndex >= 0) {
|
|
315
316
|
|
|
316
317
|
|
|
317
318
|
|
|
318
|
-
let
|
|
319
|
-
let
|
|
320
|
-
var dpdu =
|
|
321
|
-
var
|
|
322
|
-
let
|
|
323
|
-
if (
|
|
324
|
-
let
|
|
325
|
-
dpdu *=
|
|
326
|
-
|
|
319
|
+
let tu = cross(dp2, normal);
|
|
320
|
+
let tq = cross(normal, dp1);
|
|
321
|
+
var dpdu = tu * pU.x + tq * pV.x;
|
|
322
|
+
var vl = tu * pU.y + tq * pV.y;
|
|
323
|
+
let dZ = max(dot(dpdu, dpdu), dot(vl, vl));
|
|
324
|
+
if (dZ > 1e-12) {
|
|
325
|
+
let vw = inverseSqrt(dZ);
|
|
326
|
+
dpdu *= vw;
|
|
327
|
+
vl *= vw;
|
|
327
328
|
}
|
|
328
329
|
else {
|
|
329
330
|
|
|
330
331
|
|
|
331
|
-
let
|
|
332
|
+
let pa = select(
|
|
332
333
|
vec3f(0.0, 1.0, 0.0),
|
|
333
334
|
vec3f(0.0, 0.0, 1.0),
|
|
334
335
|
abs(normal.z) < 0.999
|
|
335
336
|
);
|
|
336
|
-
dpdu = normalize(cross(
|
|
337
|
-
|
|
337
|
+
dpdu = normalize(cross(pa, normal));
|
|
338
|
+
vl = cross(normal, dpdu);
|
|
338
339
|
}
|
|
339
340
|
|
|
340
341
|
var n = 2.0 * sampleMap(normalMapIndex, uv).rgb - 1.0;
|
|
341
342
|
n = normalize(vec3(n.xy * matData.normalMapScale, n.z));
|
|
342
343
|
|
|
343
|
-
let tbn = mat3x3(dpdu,
|
|
344
|
+
let tbn = mat3x3(dpdu, vl, normal);
|
|
344
345
|
|
|
345
346
|
return normalize(tbn * n);
|
|
346
347
|
} else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"materialBuffer.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/materialBuffer.wgsl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,OAAO,EACL,0BAA0B,EAC3B,MAAM,4BAA4B,CAAC;AAEpC,MAAM,UAAU,wBAAwB,CAAC,EACvC,uBAAuB,GAAG,IAAI,EAC9B,cAAc,GAAG,KAAK,EACtB,aAAa,GAAG,IAAI,EACpB,eAAe,GAAG,IAAI,EAAE,QAAQ,GAAG,KAAK,EACxC,YAAY,GAAG,IAAI,KAOjB,EAAE;IACJ,MAAM,mBAAmB,GAAG,aAAa;QACvC,CAAC,CAAC,2CAA2C;QAC7C,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,mBAAmB,GAAG,aAAa;QACvC,CAAC,CAAC,UAAU,CAAC;yBACU,0BAA0B,CAAC,MAAM;;;8BAG5B,0BAA0B,CAAC,IAAI;;EAE3D;QACA,CAAC,CAAC,oBAAoB,CAAC;IAEzB,OAAO,UAAU,CAAC;;EAElB,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;;;CAOtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAuH0B,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+B3D,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAkCc,sBAAsB,CAAC,YAAY;;;oCAG9B,sBAAsB,CAAC,KAAK;;;;;;EAMlE,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC;;EAEvC,mBAAmB;;EAEnB,mBAAmB,CAAC,iBAAiB,EAAE,MAAM,CAAC;;;;;;;;;;;;;;EAc9C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,qBAAqB,CAAC,MAAM,CAAC;;EAE7B,mBAAmB,CAAC,eAAe,EAAE,MAAM,CAAC;;EAE9C,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;;CAG7B,CAAC,CAAC,CAAC,EAAE;;EAEF,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,CAAC;;EAE/C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,CAAC;;EAE/C,mBAAmB,CAAC,mBAAmB,EAAE,MAAM,CAAC;;EAEhD,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,CAAC;;EAEjD,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;CAuBtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;;;;;;;;;EASb,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,iCAAiC;EACnE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,4BAA4B;;;;;EAK7D,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;;CAEvB,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CL,CAAC;AACF,CAAC;AAED,MAAM,kBAAkB,GAAG,wBAAwB,EAAE,CAAC;AAEtD,eAAe,kBAAkB,CAAC","sourcesContent":["import { simpleTextureSample, thinFilmTextureSample } from '../../materialTextureSlots.js';\nimport { INSTANCE_VEC4_STRIDE } from '../../bvhAccel.js';\nimport { mapAlphaUsageConstants } from '../../materialConstants.js';\n// Portions adapted from ray-tracing-renderer@0.10.15\n// (https://github.com/hoverinc/ray-tracing-renderer).\n// Copyright (c) 2019 HOVER, MIT license; see LICENSES/RayTracingRenderer-MIT.txt.\n\nimport {\n materialAlphaModeConstants\n} from '../../materialConstants.js';\n\nexport function createMaterialBufferWgsl({\n hasAnisotropyDirections = true,\n hasCoatNormals = false,\n hasSceneAlpha = true,\n hasTransmission = true, caustics = false,\n hasMetalness = true\n}: {\n hasSceneAlpha?: boolean;\n hasAnisotropyDirections?: boolean;\n hasCoatNormals?: boolean;\n hasTransmission?: boolean; caustics?: boolean;\n hasMetalness?: boolean;\n} = {}) {\n const alphaModeAssignment = hasSceneAlpha\n ? '(*ma).alphaMode = i32(matData.alphaMode);'\n : '';\n const alphaModeResolution = hasSceneAlpha\n ? /* wgsl */ `\n if ((*ma).alphaMode == ${materialAlphaModeConstants.opaque}) {\n (*ma).alpha = 1.0;\n }\n else if ((*ma).alphaMode == ${materialAlphaModeConstants.mask}) {\n (*ma).alpha = select(0.0, 1.0, (*ma).alpha >= matData.alphaCutoff);\n }`\n : '(*ma).alpha = 1.0;';\n\n return /* wgsl */ `\n\n${hasAnisotropyDirections ? /* wgsl */ `fn gltf_anisotropy_to_openpbr(roughness: f32, strength: f32) -> vec2f {\n if (strength == 0.0) { return vec2f(roughness, 0.0); }\n let u = roughness * roughness;\n let a = u + (1.0 - u) * strength * strength;\n if (a == 0.0) { return vec2f(0.0); }\n return vec2f(pow((a*a + u*u) * 0.5, 0.25), clamp(1.0 - u/a, 0.0, 1.0));\n}\n` : /* wgsl */ ``}\n\nfn sRGBToLinear(c: vec3f) -> vec3f {\n return mix(pow(c * 0.9478672986 + 0.0521327014, vec3f(2.4)), c * 0.0773993808, vec3f(c < vec3f(0.04045)));\n}\n\nfn decodeMapColor(idx: i32, c: vec3f) -> vec3f {\n if (mapInfo[idx + NUM_MAPS * 2].y > 0.5) { return c; }\n return sRGBToLinear(c);\n}\n\nfn unpackMaterialIndex(val: i32) -> vec2f {\n return vec2f(f32(val >> 8), f32(val & 0xff) / 255.0);\n}\n\nfn getMapSize(idx: i32) -> vec2f {\n return mapInfo[idx].xy;\n}\n\nfn getMapLayer(idx: i32) -> i32 {\n return i32(floor(mapInfo[idx].z));\n}\n\nfn getMapOffset(idx: i32) -> vec2f {\n return vec2f(fract(mapInfo[idx].z), mapInfo[idx].w);\n}\n\nfn wrapMapCoordinate(value: f32, mode: f32) -> f32 {\n if (mode < 0.5) { return fract(value); }\n if (mode < 1.5) { return clamp(value, 0.0, 1.0); }\n return 1.0 - abs(1.0 - (value - 2.0 * floor(value * 0.5)));\n}\n\nfn wrappedMapUv(idx: i32, uv: vec2f) -> vec2f {\n let transform = mapInfo[idx + NUM_MAPS];\n let modes = mapInfo[idx + NUM_MAPS * 2].zw;\n let value = uv * transform.xy + transform.zw;\n return vec2f(wrapMapCoordinate(value.x, modes.x), wrapMapCoordinate(value.y, modes.y));\n}\n\nfn getMapUV(idx: i32, uv: vec2f) -> vec2f {\n let repeatedUv = wrappedMapUv(idx, uv);\n let atlasTexel = 1.0 / vec2f(textureDimensions(map).xy);\n let firstTexelCenter = getMapOffset(idx);\n let sourceExtent = getMapSize(idx) + atlasTexel;\n let sourceOrigin = firstTexelCenter - 0.5 * atlasTexel;\n let lastTexelCenter = firstTexelCenter + sourceExtent - atlasTexel;\n return clamp(\n sourceOrigin + repeatedUv * sourceExtent,\n firstTexelCenter,\n lastTexelCenter\n );\n}\n\nfn getMapUvSet(idx: i32, uv: vec2f, uv1: vec2f) -> vec2f {\n return select(uv, uv1, mapInfo[idx + NUM_MAPS * 2].x > 0.5);\n}\n\nfn sampleMap(idx: i32, uv: vec2f) -> vec4f {\n let size = vec2i(round(getMapSize(idx) * vec2f(textureDimensions(map).xy) + vec2f(1.0)));\n let texel = wrappedMapUv(idx, uv) * vec2f(size) - vec2f(0.5);\n let modes = mapInfo[idx + NUM_MAPS * 2].zw;\n // Repeat filtering must cross the logical image boundary, never another\n // atlas placement. Interior/clamped/mirrored footprints use hardware filtering.\n if ((size.x > 1 && modes.x < 0.5 && (texel.x < 0.0 || texel.x > f32(size.x - 1))) ||\n (size.y > 1 && modes.y < 0.5 && (texel.y < 0.0 || texel.y > f32(size.y - 1)))) {\n let base = vec2i(floor(texel));\n let weight = fract(texel);\n let origin = vec2i(round(getMapOffset(idx) * vec2f(textureDimensions(map).xy) - vec2f(0.5)));\n return mix(\n mix(loadMapTexel(idx, base, size, origin, modes), loadMapTexel(idx, base + vec2i(1, 0), size, origin, modes), weight.x),\n mix(loadMapTexel(idx, base + vec2i(0, 1), size, origin, modes), loadMapTexel(idx, base + vec2i(1, 1), size, origin, modes), weight.x), weight.y);\n }\n return textureSampleLevel(map, mapSampler, getMapUV(idx, uv), getMapLayer(idx), 0.0);\n}\n\nfn loadMapTexel(idx: i32, coordinate: vec2i, size: vec2i, origin: vec2i, modes: vec2f) -> vec4f {\n var p = clamp(coordinate, vec2i(0), size - vec2i(1));\n if (modes.x < 0.5) { p.x = ((coordinate.x % size.x) + size.x) % size.x; }\n if (modes.y < 0.5) { p.y = ((coordinate.y % size.y) + size.y) % size.y; }\n return textureLoad(map, origin + p, getMapLayer(idx), 0);\n}\n\n\nfn getMaterialEmission(materialIndex: i32, uv: vec2f, uv1: vec2f) -> vec3f {\n let matData = materialsBuffer[materialIndex];\n var emission = matData.emission;\n if (USE_EMISSIVE_MAPS) {\n let emissiveMapIndex = i32(matData.emissiveMapIndex);\n if (emissiveMapIndex >= 0) {\n emission *= decodeMapColor(emissiveMapIndex, sampleMap(\n emissiveMapIndex, getMapUvSet(emissiveMapIndex, uv, uv1)\n ).rgb);\n }\n }\n if (USE_COAT_WEIGHT_MAPS && matData.matType == 0.0) {\n let coatWeightMapIndex = i32(matData.coatWeightMapIndex);\n if (coatWeightMapIndex >= 0) {\n let coatWeight = clamp(matData.coatWeight, 0.0, 1.0) * sampleMap(\n coatWeightMapIndex, getMapUvSet(coatWeightMapIndex, uv, uv1)\n ).r;\n emission *= mix(vec3f(1.0), sqrt(max(matData.coatColor, vec3f(0.0))), coatWeight);\n }\n }\n return emission;\n}\n\n// OpenPBR 1.1.1: RMS-preserving GGX anisotropy, shared by base and coat.\nfn openpbr_roughness_to_alpha(roughness: f32, anisotropy: f32) -> vec2f {\n let alpha = roughness * roughness;\n let alphaMin = ROUGHNESS_MIN * ROUGHNESS_MIN;\n if (anisotropy == 0.0) { return vec2f(max(alphaMin, alpha)); }\n let complement = 1.0 - anisotropy;\n let alphaT = alpha * sqrt(2.0 / (1.0 + complement * complement));\n return max(vec2f(alphaMin), vec2f(alphaT, complement * alphaT));\n}\n\nfn getInstanceColor(instanceIndex: i32) -> vec3f {\n if (instanceIndex < 0) { return vec3f(1.0); }\n return instancesBuffer[instanceIndex * ${INSTANCE_VEC4_STRIDE} + 9].xyz;\n}\n\nfn getMaterial(\n ma: ptr<function, OpenPbrResolvedMaterial>,\n materialIndex: i32,\n uv: vec2f,\n uv1: vec2f,\n instanceIndex: i32,\n vertexColor: vec3f\n) {\n let matData = materialsBuffer[materialIndex];\n\n (*ma).baseColor = matData.color;\n (*ma).materialType = i32(matData.matType);\n (*ma).specularRoughness = matData.roughness;\n (*ma).baseMetalness = matData.metallic;\n (*ma).specularAnisotropy = clamp(matData.anisotropy, 0.0, 1.0);\n (*ma).emission = getMaterialEmission(materialIndex, uv, uv1);\n (*ma).inside = false;\n (*ma).specularIor = matData.ior;\n (*ma).transmissionWeight = matData.transmission;\n (*ma).thinWalled = matData.thin > 0.5;\n (*ma).bevel = matData.bevel;\n (*ma).transmissionDispersionScale = matData.dispersion;\n (*ma).dispersionAbbeNumber = max(matData.dispersionAbbeNumber, 1e-6);\n (*ma).mediumExtinction = max(matData.mediumExtinction, vec3f(0.0));\n (*ma).mediumScattering = max(matData.mediumScattering, vec3f(0.0));\n (*ma).mediumAnisotropy = clamp(matData.mediumAnisotropy, -1.0, 1.0);\n (*ma).mediumType = select(0, 1, max(max((*ma).mediumExtinction.x, (*ma).mediumExtinction.y), (*ma).mediumExtinction.z) > 0.0);\n (*ma).alpha = matData.alpha;\n ${alphaModeAssignment}\n\n (*ma).thinFilmThickness = matData.thinFilmThickness * 1000.0;\n (*ma).thinFilmIor = matData.thinFilmIor;\n (*ma).thinFilmWeight = select(0.0, clamp(matData.thinFilmWeight, 0.0, 1.0), HAS_THIN_FILM);\n (*ma).baseWeight = clamp(matData.baseWeight, 0.0, 1.0);\n (*ma).diffuseRoughness = clamp(matData.baseDiffuseRoughness, 0.0, 1.0);\n (*ma).specularWeight = max(matData.specularWeight, 0.0);\n (*ma).specularColor = max(matData.specularColor, vec3f(0.0));\n (*ma).subsurfaceWeight = select(0.0, clamp(matData.subsurfaceWeight, 0.0, 1.0), HAS_SUBSURFACE);\n (*ma).subsurfaceColor = max(matData.subsurfaceColor, vec3f(0.0));\n (*ma).transmissionColor = max(matData.transmissionColor, vec3f(0.0));\n (*ma).fuzzWeight = select(0.0, clamp(matData.fuzzWeight, 0.0, 1.0), HAS_FUZZ);\n (*ma).fuzzColor = max(matData.fuzzColor, vec3f(0.0));\n (*ma).fuzzRoughness = clamp(matData.fuzzRoughness, 0.0, 1.0);\n (*ma).coatWeight = select(0.0, clamp(matData.coatWeight, 0.0, 1.0), HAS_COAT);\n (*ma).coatColor = max(matData.coatColor, vec3f(0.0));\n (*ma).coatRoughness = clamp(matData.coatRoughness, ROUGHNESS_MIN, 1.0);\n (*ma).coatAnisotropy = clamp(matData.coatAnisotropy, 0.0, 1.0);\n (*ma).coatIor = max(matData.coatIor, 1.0);\n (*ma).coatDarkening = clamp(matData.coatDarkening, 0.0, 1.0);\n\n if (USE_DIFFUSE_MAPS) {\n let diffuseMapIndex = i32(matData.diffuseMapIndex);\n if (diffuseMapIndex >= 0) {\n // TODO textureSample is not supported in compute shader.\n let diffuse = sampleMap(\n diffuseMapIndex, getMapUvSet(diffuseMapIndex, uv, uv1)\n );\n // Material factors from THREE / glTF are already linear. Only color\n // textures need decoding from their stored sRGB values.\n (*ma).baseColor *= decodeMapColor(diffuseMapIndex, diffuse.rgb);\n\n // Map alpha to transmission\n if (matData.mapAlphaUsage == ${mapAlphaUsageConstants.transmission}) {\n (*ma).transmissionWeight = 1.0 - diffuse.a;\n }\n else if (matData.mapAlphaUsage == ${mapAlphaUsageConstants.alpha}) {\n (*ma).alpha *= diffuse.a;\n }\n }\n }\n\n ${simpleTextureSample('alphaMap', 'wgsl')}\n\n ${alphaModeResolution}\n\n ${simpleTextureSample('transmissionMap', 'wgsl')}\n\n if (USE_METALLIC_ROUGHNESS_MAPS) {\n // Metallic roughness transmission map index\n let mrtMapIndex = i32(matData.mrtMapIndex);\n if (mrtMapIndex >= 0) {\n let metallicRoughness = sampleMap(\n mrtMapIndex, getMapUvSet(mrtMapIndex, uv, uv1)\n );\n (*ma).baseMetalness *= metallicRoughness.b;\n (*ma).specularRoughness *= metallicRoughness.g;\n }\n }\n\n ${simpleTextureSample('roughnessMap', 'wgsl')}\n\n ${simpleTextureSample('metalnessMap', 'wgsl')}\n\n ${thinFilmTextureSample('wgsl')}\n\n ${simpleTextureSample('coatWeightMap', 'wgsl')}\n\n${hasCoatNormals ? /* wgsl */ `\n // Independent coat shading also applies when the coat has no normal map.\n (*ma).coatNormalEnabled = (*ma).coatWeight > 0.0 && (matData.normalMapIndex >= 0.0 || matData.coatNormalMapIndex >= 0.0);\n` : ''}\n\n ${simpleTextureSample('coatRoughnessMap', 'wgsl')}\n\n ${simpleTextureSample('fuzzColorMap', 'wgsl')}\n\n ${simpleTextureSample('fuzzRoughnessMap', 'wgsl')}\n\n ${simpleTextureSample('specularWeightMap', 'wgsl')}\n\n ${simpleTextureSample('specularColorMap', 'wgsl')}\n\n${hasAnisotropyDirections ? /* wgsl */ `\n (*ma).anisotropyDirection = vec2f(1.0, 0.0);\n (*ma).anisotropyDirectionEnabled = matData.specularAnisotropyRotation != 0.0;\n (*ma).coatAnisotropyRotation = matData.coatAnisotropyRotation;\n if (USE_ANISOTROPY_MAPS && matData.anisotropyMapIndex >= 0.0) {\n let index = i32(matData.anisotropyMapIndex);\n let texel = sampleMap(index, getMapUvSet(index, uv, uv1));\n (*ma).specularAnisotropy *= texel.b;\n let direction = texel.rg * 2.0 - 1.0;\n if (dot(direction, direction) > 1e-4) { (*ma).anisotropyDirection = normalize(direction); }\n (*ma).anisotropyDirectionEnabled = true;\n }\n if (matData.specularAnisotropyModel > 0.5 && (*ma).specularAnisotropy > 0.0) {\n let native = gltf_anisotropy_to_openpbr(clamp((*ma).specularRoughness, 0.0, 1.0), (*ma).specularAnisotropy);\n (*ma).specularRoughness = native.x;\n (*ma).specularAnisotropy = native.y;\n }\n if ((*ma).anisotropyDirectionEnabled) {\n let theta = matData.specularAnisotropyRotation;\n let d = (*ma).anisotropyDirection;\n (*ma).anisotropyDirection = vec2f(cos(theta)*d.x - sin(theta)*d.y, sin(theta)*d.x + cos(theta)*d.y);\n }\n\n` : /* wgsl */ ``}\n // OpenPBR 1.1.1: coat refraction broadens all base microfacet lobes.\n // Keep the zero-coat / smooth-coat paths byte-identical.\n if ((*ma).coatWeight > 0.0 && (*ma).coatRoughness > 0.0) {\n let baseRoughness2 = (*ma).specularRoughness * (*ma).specularRoughness;\n let coatRoughness2 = (*ma).coatRoughness * (*ma).coatRoughness;\n (*ma).specularRoughness = mix((*ma).specularRoughness,\n pow(min(1.0, baseRoughness2 * baseRoughness2 + 2.0 * coatRoughness2 * coatRoughness2), 0.25), (*ma).coatWeight);\n }\n ${hasTransmission ? '' : /* wgsl */ `(*ma).transmissionWeight = 0.0;`}\n ${hasMetalness ? '' : /* wgsl */ `(*ma).baseMetalness = 0.0;`}\n let color = getInstanceColor(instanceIndex) * vertexColor;\n (*ma).baseColor *= color;\n if ((*ma).materialType == UNLIT) { (*ma).emission *= color; }\n\n${caustics ? /* wgsl */ ` (*ma).causticRoughness = (*ma).specularRoughness;\n (*ma).causticNormalMapped = matData.normalMapIndex >= 0.0;\n` : ''} (*ma).specularRoughness = clamp((*ma).specularRoughness, ROUGHNESS_MIN, 1.0);\n (*ma).baseMetalness = clamp((*ma).baseMetalness, 0.0, 1.0);\n let specularAlpha = openpbr_roughness_to_alpha((*ma).specularRoughness, (*ma).specularAnisotropy);\n (*ma).alphaX = specularAlpha.x;\n (*ma).alphaY = specularAlpha.y;\n}\n\nfn getMatNormal(materialIndex: i32, uv: vec2f, normal: vec3f, dp1: vec3f, dp2: vec3f, duv1: vec2f, duv2: vec2f) -> vec3f {\n let matData = materialsBuffer[materialIndex];\n let normalMapIndex = i32(matData.normalMapIndex);\n if (normalMapIndex >= 0) {\n // http://www.thetenthplanet.de/archives/1180\n // TODO use tangent attribute\n // Compute co-tangent and co-bitangent vectors\n let dp2perp = cross(dp2, normal);\n let dp1perp = cross(normal, dp1);\n var dpdu = dp2perp * duv1.x + dp1perp * duv2.x;\n var dpdv = dp2perp * duv1.y + dp1perp * duv2.y;\n let gradientLengthSquared = max(dot(dpdu, dpdu), dot(dpdv, dpdv));\n if (gradientLengthSquared > 1e-12) {\n let invmax = inverseSqrt(gradientLengthSquared);\n dpdu *= invmax;\n dpdv *= invmax;\n }\n else {\n // Generated/triplanar UVs have no per-vertex UV derivatives. Build a\n // stable fallback basis instead of normalizing two zero vectors.\n let referenceAxis = select(\n vec3f(0.0, 1.0, 0.0),\n vec3f(0.0, 0.0, 1.0),\n abs(normal.z) < 0.999\n );\n dpdu = normalize(cross(referenceAxis, normal));\n dpdv = cross(normal, dpdu);\n }\n\n var n = 2.0 * sampleMap(normalMapIndex, uv).rgb - 1.0;\n n = normalize(vec3(n.xy * matData.normalMapScale, n.z));\n\n let tbn = mat3x3(dpdu, dpdv, normal);\n\n return normalize(tbn * n);\n } else {\n return normal;\n }\n}\n`;\n}\n\nconst materialBufferWgsl = createMaterialBufferWgsl();\n\nexport default materialBufferWgsl;\n"]}
|
|
1
|
+
{"version":3,"file":"materialBuffer.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/materialBuffer.wgsl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,OAAO,EACL,0BAA0B,EAC3B,MAAM,4BAA4B,CAAC;AAEpC,MAAM,UAAU,wBAAwB,CAAC,EACvC,mBAAmB,GAAG,KAAK,EAC3B,uBAAuB,GAAG,IAAI,EAC9B,cAAc,GAAG,KAAK,EACtB,aAAa,GAAG,IAAI,EACpB,eAAe,GAAG,IAAI,EAAE,QAAQ,GAAG,KAAK,EACxC,YAAY,GAAG,IAAI,KAQjB,EAAE;IACJ,MAAM,mBAAmB,GAAG,aAAa;QACvC,CAAC,CAAC,2CAA2C;QAC7C,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,mBAAmB,GAAG,aAAa;QACvC,CAAC,CAAC,UAAU,CAAC;yBACU,0BAA0B,CAAC,MAAM;;;8BAG5B,0BAA0B,CAAC,IAAI;;EAE3D;QACA,CAAC,CAAC,oBAAoB,CAAC;IAEzB,OAAO,UAAU,CAAC;;EAElB,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;;;CAOtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCf,mBAAmB,CAAC,CAAC,CAAC;yCAC2C,CAAC,CAAC,CAAC;;;;;;;;;;GAUjE;;;;;;;;aAQU,mBAAmB,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,+EAA+E;;;;;;;;;eAS5H,mBAAmB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,iFAAiF;;;;;SAK5H,mBAAmB,CAAC,CAAC,CAAC,+EAA+E,CAAC,CAAC,CAAC,+EAA+E;;;;;;;SAOvL,mBAAmB,CAAC,CAAC,CAAC,0CAA0C,CAAC,CAAC,CAAC,mDAAmD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAuCtF,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+B3D,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAkCc,sBAAsB,CAAC,YAAY;;;oCAG9B,sBAAsB,CAAC,KAAK;;;;;;EAMlE,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC;;EAEvC,mBAAmB;;EAEnB,mBAAmB,CAAC,iBAAiB,EAAE,MAAM,CAAC;;;;;;;;;;;;;;EAc9C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,qBAAqB,CAAC,MAAM,CAAC;;EAE7B,mBAAmB,CAAC,eAAe,EAAE,MAAM,CAAC;;EAE9C,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;;CAG7B,CAAC,CAAC,CAAC,EAAE;;EAEF,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,CAAC;;EAE/C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,CAAC;;EAE/C,mBAAmB,CAAC,mBAAmB,EAAE,MAAM,CAAC;;EAEhD,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,CAAC;;EAEjD,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;CAuBtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;;;;;;;;;EASb,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,iCAAiC;EACnE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,4BAA4B;;;;;EAK7D,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;;CAEvB,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CL,CAAC;AACF,CAAC;AAED,MAAM,kBAAkB,GAAG,wBAAwB,EAAE,CAAC;AAEtD,eAAe,kBAAkB,CAAC","sourcesContent":["import { simpleTextureSample, thinFilmTextureSample } from '../../materialTextureSlots.js';\nimport { INSTANCE_VEC4_STRIDE } from '../../bvhAccel.js';\nimport { mapAlphaUsageConstants } from '../../materialConstants.js';\n// Portions adapted from ray-tracing-renderer@0.10.15\n// (https://github.com/hoverinc/ray-tracing-renderer).\n// Copyright (c) 2019 HOVER, MIT license; see LICENSES/RayTracingRenderer-MIT.txt.\n\nimport {\n materialAlphaModeConstants\n} from '../../materialConstants.js';\n\nexport function createMaterialBufferWgsl({\n independentTextures = false,\n hasAnisotropyDirections = true,\n hasCoatNormals = false,\n hasSceneAlpha = true,\n hasTransmission = true, caustics = false,\n hasMetalness = true\n}: {\n independentTextures?: boolean;\n hasSceneAlpha?: boolean;\n hasAnisotropyDirections?: boolean;\n hasCoatNormals?: boolean;\n hasTransmission?: boolean; caustics?: boolean;\n hasMetalness?: boolean;\n} = {}) {\n const alphaModeAssignment = hasSceneAlpha\n ? '(*ma).alphaMode = i32(matData.alphaMode);'\n : '';\n const alphaModeResolution = hasSceneAlpha\n ? /* wgsl */ `\n if ((*ma).alphaMode == ${materialAlphaModeConstants.opaque}) {\n (*ma).alpha = 1.0;\n }\n else if ((*ma).alphaMode == ${materialAlphaModeConstants.mask}) {\n (*ma).alpha = select(0.0, 1.0, (*ma).alpha >= matData.alphaCutoff);\n }`\n : '(*ma).alpha = 1.0;';\n\n return /* wgsl */ `\n\n${hasAnisotropyDirections ? /* wgsl */ `fn gltf_anisotropy_to_openpbr(roughness: f32, strength: f32) -> vec2f {\n if (strength == 0.0) { return vec2f(roughness, 0.0); }\n let u = roughness * roughness;\n let a = u + (1.0 - u) * strength * strength;\n if (a == 0.0) { return vec2f(0.0); }\n return vec2f(pow((a*a + u*u) * 0.5, 0.25), clamp(1.0 - u/a, 0.0, 1.0));\n}\n` : /* wgsl */ ``}\n\nfn sRGBToLinear(c: vec3f) -> vec3f {\n return mix(pow(c * 0.9478672986 + 0.0521327014, vec3f(2.4)), c * 0.0773993808, vec3f(c < vec3f(0.04045)));\n}\n\nfn decodeMapColor(idx: i32, c: vec3f) -> vec3f {\n if (mapInfo[idx + NUM_MAPS * 2].y > 0.5) { return c; }\n return sRGBToLinear(c);\n}\n\nfn unpackMaterialIndex(val: i32) -> vec2f {\n return vec2f(f32(val >> 8), f32(val & 0xff) / 255.0);\n}\n\nfn getMapSize(idx: i32) -> vec2f {\n return mapInfo[idx].xy;\n}\n\nfn getMapLayer(idx: i32) -> i32 {\n return i32(floor(mapInfo[idx].z));\n}\n\nfn getMapOffset(idx: i32) -> vec2f {\n return vec2f(fract(mapInfo[idx].z), mapInfo[idx].w);\n}\n\nfn wrapMapCoordinate(value: f32, mode: f32) -> f32 {\n if (mode < 0.5) { return fract(value); }\n if (mode < 1.5) { return clamp(value, 0.0, 1.0); }\n return 1.0 - abs(1.0 - (value - 2.0 * floor(value * 0.5)));\n}\n\nfn wrappedMapUv(idx: i32, uv: vec2f) -> vec2f {\n let transform = mapInfo[idx + NUM_MAPS];\n let modes = mapInfo[idx + NUM_MAPS * 2].zw;\n let value = uv * transform.xy + transform.zw;\n return vec2f(wrapMapCoordinate(value.x, modes.x), wrapMapCoordinate(value.y, modes.y));\n}\n\nfn getMapUV(idx: i32, uv: vec2f) -> vec2f {\n${independentTextures ? ` let halfTexel = 0.5 / getMapSize(idx);\n return clamp(wrappedMapUv(idx, uv), halfTexel, 1.0 - halfTexel);` : ` let repeatedUv = wrappedMapUv(idx, uv);\n let atlasTexel = 1.0 / vec2f(textureDimensions(map).xy);\n let firstTexelCenter = getMapOffset(idx);\n let sourceExtent = getMapSize(idx) + atlasTexel;\n let sourceOrigin = firstTexelCenter - 0.5 * atlasTexel;\n let lastTexelCenter = firstTexelCenter + sourceExtent - atlasTexel;\n return clamp(\n sourceOrigin + repeatedUv * sourceExtent,\n firstTexelCenter,\n lastTexelCenter\n );`}\n}\n\nfn getMapUvSet(idx: i32, uv: vec2f, uv1: vec2f) -> vec2f {\n return select(uv, uv1, mapInfo[idx + NUM_MAPS * 2].x > 0.5);\n}\n\nfn sampleMap(idx: i32, uv: vec2f) -> vec4f {\n let size = ${independentTextures ? 'vec2i(getMapSize(idx))' : 'vec2i(round(getMapSize(idx) * vec2f(textureDimensions(map).xy) + vec2f(1.0)))'};\n let texel = wrappedMapUv(idx, uv) * vec2f(size) - vec2f(0.5);\n let modes = mapInfo[idx + NUM_MAPS * 2].zw;\n // Repeat filtering must cross the logical image boundary, never another\n // atlas placement. Interior/clamped/mirrored footprints use hardware filtering.\n if ((size.x > 1 && modes.x < 0.5 && (texel.x < 0.0 || texel.x > f32(size.x - 1))) ||\n (size.y > 1 && modes.y < 0.5 && (texel.y < 0.0 || texel.y > f32(size.y - 1)))) {\n let base = vec2i(floor(texel));\n let weight = fract(texel);\n let origin = ${independentTextures ? 'vec2i(0)' : 'vec2i(round(getMapOffset(idx) * vec2f(textureDimensions(map).xy) - vec2f(0.5)))'};\n return mix(\n mix(loadMapTexel(idx, base, size, origin, modes), loadMapTexel(idx, base + vec2i(1, 0), size, origin, modes), weight.x),\n mix(loadMapTexel(idx, base + vec2i(0, 1), size, origin, modes), loadMapTexel(idx, base + vec2i(1, 1), size, origin, modes), weight.x), weight.y);\n }\n return ${independentTextures ? 'textureSampleLevel(map[getMapLayer(idx)], mapSampler, getMapUV(idx, uv), 0.0)' : 'textureSampleLevel(map, mapSampler, getMapUV(idx, uv), getMapLayer(idx), 0.0)'};\n}\n\nfn loadMapTexel(idx: i32, coordinate: vec2i, size: vec2i, origin: vec2i, modes: vec2f) -> vec4f {\n var p = clamp(coordinate, vec2i(0), size - vec2i(1));\n if (modes.x < 0.5) { p.x = ((coordinate.x % size.x) + size.x) % size.x; }\n if (modes.y < 0.5) { p.y = ((coordinate.y % size.y) + size.y) % size.y; }\n return ${independentTextures ? 'textureLoad(map[getMapLayer(idx)], p, 0)' : 'textureLoad(map, origin + p, getMapLayer(idx), 0)'};\n}\n\n\nfn getMaterialEmission(materialIndex: i32, uv: vec2f, uv1: vec2f) -> vec3f {\n let matData = materialsBuffer[materialIndex];\n var emission = matData.emission;\n if (USE_EMISSIVE_MAPS) {\n let emissiveMapIndex = i32(matData.emissiveMapIndex);\n if (emissiveMapIndex >= 0) {\n emission *= decodeMapColor(emissiveMapIndex, sampleMap(\n emissiveMapIndex, getMapUvSet(emissiveMapIndex, uv, uv1)\n ).rgb);\n }\n }\n if (USE_COAT_WEIGHT_MAPS && matData.matType == 0.0) {\n let coatWeightMapIndex = i32(matData.coatWeightMapIndex);\n if (coatWeightMapIndex >= 0) {\n let coatWeight = clamp(matData.coatWeight, 0.0, 1.0) * sampleMap(\n coatWeightMapIndex, getMapUvSet(coatWeightMapIndex, uv, uv1)\n ).r;\n emission *= mix(vec3f(1.0), sqrt(max(matData.coatColor, vec3f(0.0))), coatWeight);\n }\n }\n return emission;\n}\n\n// OpenPBR 1.1.1: RMS-preserving GGX anisotropy, shared by base and coat.\nfn openpbr_roughness_to_alpha(roughness: f32, anisotropy: f32) -> vec2f {\n let alpha = roughness * roughness;\n let alphaMin = ROUGHNESS_MIN * ROUGHNESS_MIN;\n if (anisotropy == 0.0) { return vec2f(max(alphaMin, alpha)); }\n let complement = 1.0 - anisotropy;\n let alphaT = alpha * sqrt(2.0 / (1.0 + complement * complement));\n return max(vec2f(alphaMin), vec2f(alphaT, complement * alphaT));\n}\n\nfn getInstanceColor(instanceIndex: i32) -> vec3f {\n if (instanceIndex < 0) { return vec3f(1.0); }\n return instancesBuffer[instanceIndex * ${INSTANCE_VEC4_STRIDE} + 9].xyz;\n}\n\nfn getMaterial(\n ma: ptr<function, OpenPbrResolvedMaterial>,\n materialIndex: i32,\n uv: vec2f,\n uv1: vec2f,\n instanceIndex: i32,\n vertexColor: vec3f\n) {\n let matData = materialsBuffer[materialIndex];\n\n (*ma).baseColor = matData.color;\n (*ma).materialType = i32(matData.matType);\n (*ma).specularRoughness = matData.roughness;\n (*ma).baseMetalness = matData.metallic;\n (*ma).specularAnisotropy = clamp(matData.anisotropy, 0.0, 1.0);\n (*ma).emission = getMaterialEmission(materialIndex, uv, uv1);\n (*ma).inside = false;\n (*ma).specularIor = matData.ior;\n (*ma).transmissionWeight = matData.transmission;\n (*ma).thinWalled = matData.thin > 0.5;\n (*ma).bevel = matData.bevel;\n (*ma).transmissionDispersionScale = matData.dispersion;\n (*ma).dispersionAbbeNumber = max(matData.dispersionAbbeNumber, 1e-6);\n (*ma).mediumExtinction = max(matData.mediumExtinction, vec3f(0.0));\n (*ma).mediumScattering = max(matData.mediumScattering, vec3f(0.0));\n (*ma).mediumAnisotropy = clamp(matData.mediumAnisotropy, -1.0, 1.0);\n (*ma).mediumType = select(0, 1, max(max((*ma).mediumExtinction.x, (*ma).mediumExtinction.y), (*ma).mediumExtinction.z) > 0.0);\n (*ma).alpha = matData.alpha;\n ${alphaModeAssignment}\n\n (*ma).thinFilmThickness = matData.thinFilmThickness * 1000.0;\n (*ma).thinFilmIor = matData.thinFilmIor;\n (*ma).thinFilmWeight = select(0.0, clamp(matData.thinFilmWeight, 0.0, 1.0), HAS_THIN_FILM);\n (*ma).baseWeight = clamp(matData.baseWeight, 0.0, 1.0);\n (*ma).diffuseRoughness = clamp(matData.baseDiffuseRoughness, 0.0, 1.0);\n (*ma).specularWeight = max(matData.specularWeight, 0.0);\n (*ma).specularColor = max(matData.specularColor, vec3f(0.0));\n (*ma).subsurfaceWeight = select(0.0, clamp(matData.subsurfaceWeight, 0.0, 1.0), HAS_SUBSURFACE);\n (*ma).subsurfaceColor = max(matData.subsurfaceColor, vec3f(0.0));\n (*ma).transmissionColor = max(matData.transmissionColor, vec3f(0.0));\n (*ma).fuzzWeight = select(0.0, clamp(matData.fuzzWeight, 0.0, 1.0), HAS_FUZZ);\n (*ma).fuzzColor = max(matData.fuzzColor, vec3f(0.0));\n (*ma).fuzzRoughness = clamp(matData.fuzzRoughness, 0.0, 1.0);\n (*ma).coatWeight = select(0.0, clamp(matData.coatWeight, 0.0, 1.0), HAS_COAT);\n (*ma).coatColor = max(matData.coatColor, vec3f(0.0));\n (*ma).coatRoughness = clamp(matData.coatRoughness, ROUGHNESS_MIN, 1.0);\n (*ma).coatAnisotropy = clamp(matData.coatAnisotropy, 0.0, 1.0);\n (*ma).coatIor = max(matData.coatIor, 1.0);\n (*ma).coatDarkening = clamp(matData.coatDarkening, 0.0, 1.0);\n\n if (USE_DIFFUSE_MAPS) {\n let diffuseMapIndex = i32(matData.diffuseMapIndex);\n if (diffuseMapIndex >= 0) {\n // TODO textureSample is not supported in compute shader.\n let diffuse = sampleMap(\n diffuseMapIndex, getMapUvSet(diffuseMapIndex, uv, uv1)\n );\n // Material factors from THREE / glTF are already linear. Only color\n // textures need decoding from their stored sRGB values.\n (*ma).baseColor *= decodeMapColor(diffuseMapIndex, diffuse.rgb);\n\n // Map alpha to transmission\n if (matData.mapAlphaUsage == ${mapAlphaUsageConstants.transmission}) {\n (*ma).transmissionWeight = 1.0 - diffuse.a;\n }\n else if (matData.mapAlphaUsage == ${mapAlphaUsageConstants.alpha}) {\n (*ma).alpha *= diffuse.a;\n }\n }\n }\n\n ${simpleTextureSample('alphaMap', 'wgsl')}\n\n ${alphaModeResolution}\n\n ${simpleTextureSample('transmissionMap', 'wgsl')}\n\n if (USE_METALLIC_ROUGHNESS_MAPS) {\n // Metallic roughness transmission map index\n let mrtMapIndex = i32(matData.mrtMapIndex);\n if (mrtMapIndex >= 0) {\n let metallicRoughness = sampleMap(\n mrtMapIndex, getMapUvSet(mrtMapIndex, uv, uv1)\n );\n (*ma).baseMetalness *= metallicRoughness.b;\n (*ma).specularRoughness *= metallicRoughness.g;\n }\n }\n\n ${simpleTextureSample('roughnessMap', 'wgsl')}\n\n ${simpleTextureSample('metalnessMap', 'wgsl')}\n\n ${thinFilmTextureSample('wgsl')}\n\n ${simpleTextureSample('coatWeightMap', 'wgsl')}\n\n${hasCoatNormals ? /* wgsl */ `\n // Independent coat shading also applies when the coat has no normal map.\n (*ma).coatNormalEnabled = (*ma).coatWeight > 0.0 && (matData.normalMapIndex >= 0.0 || matData.coatNormalMapIndex >= 0.0);\n` : ''}\n\n ${simpleTextureSample('coatRoughnessMap', 'wgsl')}\n\n ${simpleTextureSample('fuzzColorMap', 'wgsl')}\n\n ${simpleTextureSample('fuzzRoughnessMap', 'wgsl')}\n\n ${simpleTextureSample('specularWeightMap', 'wgsl')}\n\n ${simpleTextureSample('specularColorMap', 'wgsl')}\n\n${hasAnisotropyDirections ? /* wgsl */ `\n (*ma).anisotropyDirection = vec2f(1.0, 0.0);\n (*ma).anisotropyDirectionEnabled = matData.specularAnisotropyRotation != 0.0;\n (*ma).coatAnisotropyRotation = matData.coatAnisotropyRotation;\n if (USE_ANISOTROPY_MAPS && matData.anisotropyMapIndex >= 0.0) {\n let index = i32(matData.anisotropyMapIndex);\n let texel = sampleMap(index, getMapUvSet(index, uv, uv1));\n (*ma).specularAnisotropy *= texel.b;\n let direction = texel.rg * 2.0 - 1.0;\n if (dot(direction, direction) > 1e-4) { (*ma).anisotropyDirection = normalize(direction); }\n (*ma).anisotropyDirectionEnabled = true;\n }\n if (matData.specularAnisotropyModel > 0.5 && (*ma).specularAnisotropy > 0.0) {\n let native = gltf_anisotropy_to_openpbr(clamp((*ma).specularRoughness, 0.0, 1.0), (*ma).specularAnisotropy);\n (*ma).specularRoughness = native.x;\n (*ma).specularAnisotropy = native.y;\n }\n if ((*ma).anisotropyDirectionEnabled) {\n let theta = matData.specularAnisotropyRotation;\n let d = (*ma).anisotropyDirection;\n (*ma).anisotropyDirection = vec2f(cos(theta)*d.x - sin(theta)*d.y, sin(theta)*d.x + cos(theta)*d.y);\n }\n\n` : /* wgsl */ ``}\n // OpenPBR 1.1.1: coat refraction broadens all base microfacet lobes.\n // Keep the zero-coat / smooth-coat paths byte-identical.\n if ((*ma).coatWeight > 0.0 && (*ma).coatRoughness > 0.0) {\n let baseRoughness2 = (*ma).specularRoughness * (*ma).specularRoughness;\n let coatRoughness2 = (*ma).coatRoughness * (*ma).coatRoughness;\n (*ma).specularRoughness = mix((*ma).specularRoughness,\n pow(min(1.0, baseRoughness2 * baseRoughness2 + 2.0 * coatRoughness2 * coatRoughness2), 0.25), (*ma).coatWeight);\n }\n ${hasTransmission ? '' : /* wgsl */ `(*ma).transmissionWeight = 0.0;`}\n ${hasMetalness ? '' : /* wgsl */ `(*ma).baseMetalness = 0.0;`}\n let color = getInstanceColor(instanceIndex) * vertexColor;\n (*ma).baseColor *= color;\n if ((*ma).materialType == UNLIT) { (*ma).emission *= color; }\n\n${caustics ? /* wgsl */ ` (*ma).causticRoughness = (*ma).specularRoughness;\n (*ma).causticNormalMapped = matData.normalMapIndex >= 0.0;\n` : ''} (*ma).specularRoughness = clamp((*ma).specularRoughness, ROUGHNESS_MIN, 1.0);\n (*ma).baseMetalness = clamp((*ma).baseMetalness, 0.0, 1.0);\n let specularAlpha = openpbr_roughness_to_alpha((*ma).specularRoughness, (*ma).specularAnisotropy);\n (*ma).alphaX = specularAlpha.x;\n (*ma).alphaY = specularAlpha.y;\n}\n\nfn getMatNormal(materialIndex: i32, uv: vec2f, normal: vec3f, dp1: vec3f, dp2: vec3f, duv1: vec2f, duv2: vec2f) -> vec3f {\n let matData = materialsBuffer[materialIndex];\n let normalMapIndex = i32(matData.normalMapIndex);\n if (normalMapIndex >= 0) {\n // http://www.thetenthplanet.de/archives/1180\n // TODO use tangent attribute\n // Compute co-tangent and co-bitangent vectors\n let dp2perp = cross(dp2, normal);\n let dp1perp = cross(normal, dp1);\n var dpdu = dp2perp * duv1.x + dp1perp * duv2.x;\n var dpdv = dp2perp * duv1.y + dp1perp * duv2.y;\n let gradientLengthSquared = max(dot(dpdu, dpdu), dot(dpdv, dpdv));\n if (gradientLengthSquared > 1e-12) {\n let invmax = inverseSqrt(gradientLengthSquared);\n dpdu *= invmax;\n dpdv *= invmax;\n }\n else {\n // Generated/triplanar UVs have no per-vertex UV derivatives. Build a\n // stable fallback basis instead of normalizing two zero vectors.\n let referenceAxis = select(\n vec3f(0.0, 1.0, 0.0),\n vec3f(0.0, 0.0, 1.0),\n abs(normal.z) < 0.999\n );\n dpdu = normalize(cross(referenceAxis, normal));\n dpdv = cross(normal, dpdu);\n }\n\n var n = 2.0 * sampleMap(normalMapIndex, uv).rgb - 1.0;\n n = normalize(vec3(n.xy * matData.normalMapScale, n.z));\n\n let tbn = mat3x3(dpdu, dpdv, normal);\n\n return normalize(tbn * n);\n } else {\n return normal;\n }\n}\n`;\n}\n\nconst materialBufferWgsl = createMaterialBufferWgsl();\n\nexport default materialBufferWgsl;\n"]}
|