@meimu/mutracer 0.2.0 → 0.3.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/README.md +3 -0
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +8949 -7915
- package/docs/api.md +42 -21
- package/docs/caustics.md +80 -0
- package/docs/materials.md +5 -4
- package/docs/progressive-rendering.md +50 -9
- package/docs/technical/continuous-spectrum.md +93 -0
- package/docs/updates.md +3 -1
- package/docs/viewer-checklist.md +65 -0
- package/docs/viewer.md +7 -5
- package/lib/Display.js +1 -1
- package/lib/Display.js.map +1 -1
- package/lib/Engine.d.ts +2 -0
- package/lib/Engine.js +47 -12
- package/lib/Engine.js.map +1 -1
- package/lib/Render.d.ts +61 -13
- package/lib/Render.js +169 -19
- package/lib/Render.js.map +1 -1
- package/lib/RenderLoop.d.ts +7 -3
- package/lib/RenderLoop.js +68 -44
- package/lib/RenderLoop.js.map +1 -1
- package/lib/main.d.ts +1 -1
- package/lib/main.js.map +1 -1
- package/lib/oidn.d.ts +1 -1
- package/lib/oidnBundledWeights.cdn.d.ts +2 -2
- package/lib/renderer/GPUTraceQueue.d.ts +2 -1
- package/lib/renderer/GPUTraceQueue.js +3 -1
- package/lib/renderer/GPUTraceQueue.js.map +1 -1
- package/lib/renderer/RenderingPipeline.d.ts +4 -0
- package/lib/renderer/RenderingPipeline.js.map +1 -1
- package/lib/renderer/WGPUCausticLightPass.d.ts +48 -0
- package/lib/renderer/WGPUCausticLightPass.js +217 -0
- package/lib/renderer/WGPUCausticLightPass.js.map +1 -0
- package/lib/renderer/WGPUEnvMapDistribution.js +18 -18
- package/lib/renderer/WGPUFullQuadPass.js +3 -3
- package/lib/renderer/WGPUPhotonMap.d.ts +37 -0
- package/lib/renderer/WGPUPhotonMap.js +191 -0
- package/lib/renderer/WGPUPhotonMap.js.map +1 -0
- package/lib/renderer/WGPURayTraceOutput.d.ts +13 -1
- package/lib/renderer/WGPURayTraceOutput.js +122 -28
- package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
- package/lib/renderer/WGPURayTracePass.d.ts +48 -17
- package/lib/renderer/WGPURayTracePass.js +538 -340
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.js +83 -47
- package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLFullQuadPass.d.ts +2 -1
- package/lib/renderer/WebGLFullQuadPass.js +4 -0
- package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
- package/lib/renderer/WebGLJNLMDenoiser.js +66 -66
- package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
- package/lib/renderer/WebGLRayTracePass.d.ts +6 -1
- package/lib/renderer/WebGLRayTracePass.js +43 -6
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/WebGLRenderingPipeline.js +10 -14
- package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLSkyBaker.js +60 -60
- package/lib/renderer/accumulationTarget.d.ts +2 -1
- package/lib/renderer/accumulationTarget.js.map +1 -1
- package/lib/renderer/causticDiagnostics.d.ts +31 -0
- package/lib/renderer/causticDiagnostics.js +5 -0
- package/lib/renderer/causticDiagnostics.js.map +1 -0
- package/lib/renderer/causticEmission.d.ts +10 -0
- package/lib/renderer/causticEmission.js +40 -0
- package/lib/renderer/causticEmission.js.map +1 -0
- package/lib/renderer/causticUniform.d.ts +12 -0
- package/lib/renderer/causticUniform.js +22 -0
- package/lib/renderer/causticUniform.js.map +1 -0
- package/lib/renderer/caustics.d.ts +16 -0
- package/lib/renderer/caustics.js +93 -0
- package/lib/renderer/caustics.js.map +1 -0
- package/lib/renderer/glsl/aovDisplay.frag.js +5 -5
- package/lib/renderer/glsl/aovReflectance.glsl.js +53 -53
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
- package/lib/renderer/glsl/aovTrace.frag.js +33 -33
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -9
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +35 -0
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/envMap.glsl.js +73 -73
- package/lib/renderer/glsl/chunks/intersect.glsl.js +426 -428
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +156 -153
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +771 -771
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +6 -6
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +68 -63
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +94 -76
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +140 -117
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +14 -14
- package/lib/renderer/glsl/chunks/sampling.glsl.js +89 -92
- package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sobol.glsl.js +79 -79
- 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 +2 -2
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +10 -10
- package/lib/renderer/glsl/rayTrace.frag.d.ts +1 -1
- package/lib/renderer/glsl/rayTrace.frag.js +260 -237
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +26 -26
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +59 -59
- package/lib/renderer/lightSampling.d.ts +3 -2
- package/lib/renderer/lightSampling.js +14 -8
- package/lib/renderer/lightSampling.js.map +1 -1
- package/lib/renderer/progressiveScheduler.js +4 -3
- package/lib/renderer/progressiveScheduler.js.map +1 -1
- package/lib/renderer/renderPipeline.d.ts +1 -0
- package/lib/renderer/renderPipeline.js.map +1 -1
- package/lib/renderer/researchTransport.d.ts +31 -0
- package/lib/renderer/researchTransport.js +5 -0
- package/lib/renderer/researchTransport.js.map +1 -0
- 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/scratchSampling.js +6 -6
- package/lib/renderer/spectrum.d.ts +21 -0
- package/lib/renderer/spectrum.js +154 -0
- package/lib/renderer/spectrum.js.map +1 -0
- package/lib/renderer/webglLightSampling.d.ts +39 -0
- package/lib/renderer/webglLightSampling.js +15 -0
- package/lib/renderer/webglLightSampling.js.map +1 -0
- package/lib/renderer/wgpuBindlessSource.js +3 -3
- package/lib/renderer/wgpuShaderSource.d.ts +7 -0
- package/lib/renderer/wgpuShaderSource.js +2 -0
- package/lib/renderer/wgpuShaderSource.js.map +1 -1
- package/lib/renderer/wgsl/aovDisplay.wgsl.js +9 -9
- package/lib/renderer/wgsl/aovReflectance.wgsl.js +55 -55
- package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +1 -1
- package/lib/renderer/wgsl/aovResolve.wgsl.js +2 -2
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js +1 -1
- package/lib/renderer/wgsl/aovTrace.wgsl.js +33 -33
- package/lib/renderer/wgsl/bloom.wgsl.js +18 -18
- package/lib/renderer/wgsl/causticLight.compute.d.ts +6 -0
- package/lib/renderer/wgsl/causticLight.compute.js +537 -0
- package/lib/renderer/wgsl/causticLight.compute.js.map +1 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.js +102 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +12 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +16 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.d.ts +1 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js +62 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +37 -37
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +598 -592
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +14 -14
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +2 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +75 -73
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +794 -794
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +139 -139
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +2 -1
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +35 -25
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +142 -138
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +204 -187
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +11 -11
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +89 -93
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +83 -83
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
- package/lib/renderer/wgsl/compose.frag.wgsl.js +98 -98
- package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
- package/lib/renderer/wgsl/depthQuery.wgsl.js +2 -2
- package/lib/renderer/wgsl/jnlm.compute.js +74 -74
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +25 -25
- package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +3 -3
- package/lib/renderer/wgsl/photonMap.compute.d.ts +29 -0
- package/lib/renderer/wgsl/photonMap.compute.js +352 -0
- package/lib/renderer/wgsl/photonMap.compute.js.map +1 -0
- package/lib/renderer/wgsl/proceduralSky.compute.js +64 -64
- package/lib/renderer/wgsl/rayTrace.compute.d.ts +9 -1
- package/lib/renderer/wgsl/rayTrace.compute.js +448 -522
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/MaterialState.d.ts +2 -2
- package/lib/scene/MaterialState.js +2 -2
- package/lib/scene/MaterialState.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 +2 -2
- 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/llms.txt +2 -1
- package/package.json +3 -3
|
@@ -7,24 +7,25 @@ import { mapAlphaUsageConstants } from '../../materialConstants.js';
|
|
|
7
7
|
// (https://github.com/hoverinc/ray-tracing-renderer).
|
|
8
8
|
// Copyright (c) 2019 HOVER, MIT license; see LICENSES/RayTracingRenderer-MIT.txt.
|
|
9
9
|
import { createShaderMixin, glsl, Shader } from '../../shader.js';
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
10
|
+
export function createMaterialBufferGlsl(fragments = {}) {
|
|
11
|
+
return createShaderMixin({
|
|
12
|
+
uniforms: {
|
|
13
|
+
materialBuffer: Shader.uniform('sampler2D'),
|
|
14
|
+
materialBufferColumns: Shader.uniform('int', 1),
|
|
15
|
+
mapInfo: Shader.arrayUniform('vec4', 'NUM_MAPS'),
|
|
16
|
+
mapTransform: Shader.arrayUniform('vec4', 'NUM_MAPS'),
|
|
17
|
+
mapUvChannel: Shader.arrayUniform('float', 'NUM_MAPS'),
|
|
18
|
+
mapColorLinear: Shader.arrayUniform('float', 'NUM_MAPS'),
|
|
19
|
+
mapWrap: Shader.arrayUniform('vec2', 'NUM_MAPS'),
|
|
20
|
+
map: Shader.uniform('sampler2DArray')
|
|
21
|
+
},
|
|
22
|
+
defines: {
|
|
23
|
+
NUM_MATERIALS: 1
|
|
24
|
+
},
|
|
25
|
+
main: glsl `
|
|
25
26
|
${materialRowsGlsl()}
|
|
26
27
|
#ifdef HAS_GLTF_ANISOTROPY
|
|
27
|
-
vec2
|
|
28
|
+
vec2 fb(float roughness, float strength) {
|
|
28
29
|
if (strength == 0.0) { return vec2(roughness, 0.0); }
|
|
29
30
|
float u = roughness * roughness;
|
|
30
31
|
float a = u + (1.0 - u) * strength * strength;
|
|
@@ -34,15 +35,15 @@ return vec2(pow((a*a + u*u) * 0.5, 0.25), clamp(1.0 - u/a, 0.0, 1.0));
|
|
|
34
35
|
|
|
35
36
|
#endif
|
|
36
37
|
|
|
37
|
-
vec3
|
|
38
|
+
vec3 mq(vec3 c) {
|
|
38
39
|
return mix(pow(c * 0.9478672986 + 0.0521327014, vec3(2.4)), c * 0.0773993808, vec3(lessThan(c, vec3(0.04045))));
|
|
39
40
|
}
|
|
40
41
|
vec4 fetchMatData(int i) {
|
|
41
|
-
return
|
|
42
|
+
return fetchData(materialBuffer, i, materialBufferColumns);
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
|
|
45
|
-
float
|
|
46
|
+
float lJ(float alpha, int alphaMode, float alphaCutoff) {
|
|
46
47
|
if (alphaMode == ${materialAlphaModeConstants.opaque}) {
|
|
47
48
|
return 1.0;
|
|
48
49
|
}
|
|
@@ -52,55 +53,55 @@ return alpha >= alphaCutoff ? 1.0 : 0.0;
|
|
|
52
53
|
return alpha;
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
float
|
|
56
|
+
float yt(int idx) {
|
|
56
57
|
return fetchMatData(idx * MAT_DATA_SIZE + MAT_ROW_COLOR).w;
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
vec2
|
|
60
|
+
vec2 af(int val) {
|
|
60
61
|
return vec2(float(val >> 8), float(val & 0xff) / 255.0);
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
#ifdef NUM_MAPS
|
|
64
65
|
vec3 decodeMapColor(int index, vec3 c) {
|
|
65
66
|
if (mapColorLinear[index] > 0.5) { return c; }
|
|
66
|
-
return
|
|
67
|
+
return mq(c);
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
vec2
|
|
70
|
+
vec2 jv(int index) {
|
|
70
71
|
return mapInfo[index].xy;
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
float
|
|
74
|
+
float lE(int index) {
|
|
74
75
|
return floor(mapInfo[index].z);
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
vec2
|
|
78
|
+
vec2 jV(int index) {
|
|
78
79
|
return vec2(fract(mapInfo[index].z), mapInfo[index].w);
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
float
|
|
82
|
+
float fS(float value, float mode) {
|
|
82
83
|
if (mode < 0.5) return fract(value);
|
|
83
84
|
if (mode < 1.5) return clamp(value, 0.0, 1.0);
|
|
84
85
|
return 1.0 - abs(1.0 - (value - 2.0 * floor(value * 0.5)));
|
|
85
86
|
}
|
|
86
87
|
|
|
87
|
-
vec2
|
|
88
|
+
vec2 kF(int index, vec2 uv) {
|
|
88
89
|
vec4 transform = mapTransform[index];
|
|
89
90
|
vec2 value = uv * transform.xy + transform.zw;
|
|
90
|
-
return vec2(
|
|
91
|
+
return vec2(fS(value.x, mapWrap[index].x), fS(value.y, mapWrap[index].y));
|
|
91
92
|
}
|
|
92
93
|
|
|
93
|
-
vec2
|
|
94
|
-
vec2
|
|
95
|
-
vec2
|
|
96
|
-
vec2
|
|
97
|
-
vec2
|
|
98
|
-
vec2
|
|
99
|
-
vec2
|
|
94
|
+
vec2 tK(int index, vec2 uv) {
|
|
95
|
+
vec2 rJ = kF(index, uv);
|
|
96
|
+
vec2 jn = 1.0 / vec2(textureSize(map, 0).xy);
|
|
97
|
+
vec2 dX = jV(index);
|
|
98
|
+
vec2 kx = jv(index) + jn;
|
|
99
|
+
vec2 po = dX - 0.5 * jn;
|
|
100
|
+
vec2 lS = dX + kx - jn;
|
|
100
101
|
return clamp(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
po + rJ * kx,
|
|
103
|
+
dX,
|
|
104
|
+
lS
|
|
104
105
|
);
|
|
105
106
|
}
|
|
106
107
|
|
|
@@ -108,47 +109,47 @@ vec2 getMapUvSet(int index, vec2 uv, vec2 uv1) {
|
|
|
108
109
|
return mapUvChannel[index] > 0.5 ? uv1 : uv;
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
vec4
|
|
112
|
-
ivec2 p = clamp(
|
|
113
|
-
if (modes.x < 0.5) p.x = ((
|
|
114
|
-
if (modes.y < 0.5) p.y = ((
|
|
115
|
-
return texelFetch(map, ivec3(origin + p, int(
|
|
112
|
+
vec4 eN(int index, ivec2 jq, ivec2 size, ivec2 origin, vec2 modes) {
|
|
113
|
+
ivec2 p = clamp(jq, ivec2(0), size - 1);
|
|
114
|
+
if (modes.x < 0.5) p.x = ((jq.x % size.x) + size.x) % size.x;
|
|
115
|
+
if (modes.y < 0.5) p.y = ((jq.y % size.y) + size.y) % size.y;
|
|
116
|
+
return texelFetch(map, ivec3(origin + p, int(lE(index))), 0);
|
|
116
117
|
}
|
|
117
118
|
|
|
118
119
|
vec4 sampleMap(int index, vec2 uv) {
|
|
119
|
-
ivec2 size = ivec2(round(
|
|
120
|
-
vec2
|
|
120
|
+
ivec2 size = ivec2(round(jv(index) * vec2(textureSize(map, 0).xy) + 1.0));
|
|
121
|
+
vec2 cR = kF(index, uv) * vec2(size) - 0.5;
|
|
121
122
|
vec2 modes = mapWrap[index];
|
|
122
|
-
if ((size.x > 1 && modes.x < 0.5 && (
|
|
123
|
-
(size.y > 1 && modes.y < 0.5 && (
|
|
124
|
-
ivec2 base = ivec2(floor(
|
|
125
|
-
vec2 weight = fract(
|
|
126
|
-
ivec2 origin = ivec2(round(
|
|
123
|
+
if ((size.x > 1 && modes.x < 0.5 && (cR.x < 0.0 || cR.x > float(size.x - 1))) ||
|
|
124
|
+
(size.y > 1 && modes.y < 0.5 && (cR.y < 0.0 || cR.y > float(size.y - 1)))) {
|
|
125
|
+
ivec2 base = ivec2(floor(cR));
|
|
126
|
+
vec2 weight = fract(cR);
|
|
127
|
+
ivec2 origin = ivec2(round(jV(index) * vec2(textureSize(map, 0).xy) - 0.5));
|
|
127
128
|
return mix(
|
|
128
|
-
mix(
|
|
129
|
-
mix(
|
|
129
|
+
mix(eN(index, base, size, origin, modes), eN(index, base + ivec2(1, 0), size, origin, modes), weight.x),
|
|
130
|
+
mix(eN(index, base + ivec2(0, 1), size, origin, modes), eN(index, base + ivec2(1, 1), size, origin, modes), weight.x), weight.y);
|
|
130
131
|
}
|
|
131
|
-
return texture(map, vec3(
|
|
132
|
+
return texture(map, vec3(tK(index, uv), lE(index)));
|
|
132
133
|
}
|
|
133
134
|
#endif
|
|
134
135
|
|
|
135
136
|
|
|
136
|
-
vec2
|
|
137
|
+
vec2 aL(float roughness, float anisotropy) {
|
|
137
138
|
float alpha = roughness * roughness;
|
|
138
|
-
float
|
|
139
|
-
if (anisotropy == 0.0) { return vec2(max(
|
|
140
|
-
float
|
|
141
|
-
float tp = alpha * sqrt(2.0 / (1.0 +
|
|
142
|
-
return max(vec2(
|
|
139
|
+
float pZ = ROUGHNESS_MIN * ROUGHNESS_MIN;
|
|
140
|
+
if (anisotropy == 0.0) { return vec2(max(pZ, alpha)); }
|
|
141
|
+
float cY = 1.0 - anisotropy;
|
|
142
|
+
float tp = alpha * sqrt(2.0 / (1.0 + cY * cY));
|
|
143
|
+
return max(vec2(pZ), vec2(tp, cY * tp));
|
|
143
144
|
}
|
|
144
145
|
|
|
145
|
-
vec4
|
|
146
|
-
vec3
|
|
146
|
+
vec4 fetchIns(int i);
|
|
147
|
+
vec3 kV(int instanceIndex) {
|
|
147
148
|
if (instanceIndex < 0) return vec3(1.0);
|
|
148
|
-
return
|
|
149
|
+
return fetchIns(instanceIndex * ${INSTANCE_VEC4_STRIDE + ''} + 9).rgb;
|
|
149
150
|
}
|
|
150
151
|
|
|
151
|
-
void
|
|
152
|
+
void getMaterial(
|
|
152
153
|
inout OpenPbrResolvedMaterial mat,
|
|
153
154
|
int materialIndex,
|
|
154
155
|
vec2 uv,
|
|
@@ -157,62 +158,62 @@ int instanceIndex,
|
|
|
157
158
|
vec3 vertexColor
|
|
158
159
|
) {
|
|
159
160
|
int i = materialIndex * MAT_DATA_SIZE;
|
|
160
|
-
vec4
|
|
161
|
-
vec4
|
|
162
|
-
vec4
|
|
163
|
-
vec4
|
|
164
|
-
vec4
|
|
161
|
+
vec4 pI = fetchMatData(i + MAT_ROW_COLOR);
|
|
162
|
+
vec4 roughnessAndNormal = fetchMatData(i + MAT_ROW_ROUGHNESS_NORMAL);
|
|
163
|
+
vec4 gm = fetchMatData(i + MAT_ROW_METALLIC_MAPS);
|
|
164
|
+
vec4 hF = fetchMatData(i + MAT_ROW_EMISSION);
|
|
165
|
+
vec4 gT = fetchMatData(i + MAT_ROW_IOR_TRANSMISSION);
|
|
165
166
|
vec4 misc = fetchMatData(i + MAT_ROW_MISC);
|
|
166
|
-
vec4
|
|
167
|
-
vec4
|
|
168
|
-
vec4
|
|
167
|
+
vec4 oh = fetchMatData(i + MAT_ROW_ALPHA_FILM);
|
|
168
|
+
vec4 mi = fetchMatData(i + MAT_ROW_BASE_CONTROLS);
|
|
169
|
+
vec4 pP = fetchMatData(i + MAT_ROW_SPECULAR_FUZZ);
|
|
169
170
|
vec4 subsurface = fetchMatData(i + MAT_ROW_SUBSURFACE);
|
|
170
|
-
vec4
|
|
171
|
-
vec4
|
|
172
|
-
vec4
|
|
173
|
-
vec4
|
|
174
|
-
vec4
|
|
171
|
+
vec4 yJ = fetchMatData(i + MAT_ROW_FUZZ);
|
|
172
|
+
vec4 coat = fetchMatData(i + MAT_ROW_COAT);
|
|
173
|
+
vec4 mk = fetchMatData(i + MAT_ROW_COAT_CONTROLS);
|
|
174
|
+
vec4 nL = fetchMatData(i + MAT_ROW_FILM_DISPERSION);
|
|
175
|
+
vec4 og = fetchMatData(i + MAT_ROW_STANDALONE_MAPS);
|
|
175
176
|
int mapAlphaUsage = int(misc.a);
|
|
176
177
|
|
|
177
|
-
mat.baseColor =
|
|
178
|
-
mat.materialType = int(
|
|
179
|
-
mat.specularRoughness =
|
|
180
|
-
mat.baseMetalness =
|
|
181
|
-
mat.specularAnisotropy = clamp(
|
|
182
|
-
mat.emission =
|
|
178
|
+
mat.baseColor = pI.rgb;
|
|
179
|
+
mat.materialType = int(pI.w);
|
|
180
|
+
mat.specularRoughness = roughnessAndNormal.x;
|
|
181
|
+
mat.baseMetalness = gm.x;
|
|
182
|
+
mat.specularAnisotropy = clamp(gm.y, 0.0, 1.0);
|
|
183
|
+
mat.emission = hF.rgb;
|
|
183
184
|
mat.inside = false;
|
|
184
|
-
mat.specularIor =
|
|
185
|
-
mat.transmissionWeight =
|
|
185
|
+
mat.specularIor = gT.x;
|
|
186
|
+
mat.transmissionWeight = gT.y;
|
|
186
187
|
#ifdef HAS_MEDIUM
|
|
187
|
-
mat.mediumType = int(
|
|
188
|
+
mat.mediumType = int(gT.z);
|
|
188
189
|
#else
|
|
189
190
|
mat.mediumType = 0;
|
|
190
191
|
#endif
|
|
191
|
-
mat.thinWalled =
|
|
192
|
+
mat.thinWalled = gT.w > 0.5;
|
|
192
193
|
mat.bevel = misc.r;
|
|
193
194
|
mat.transmissionDispersionScale = misc.g;
|
|
194
|
-
mat.dispersionAbbeNumber = max(
|
|
195
|
+
mat.dispersionAbbeNumber = max(nL.y, 1e-6);
|
|
195
196
|
mat.thinFilmThickness = misc.b;
|
|
196
|
-
mat.thinFilmIor =
|
|
197
|
-
mat.thinFilmWeight = clamp(
|
|
197
|
+
mat.thinFilmIor = oh.b;
|
|
198
|
+
mat.thinFilmWeight = clamp(nL.x, 0.0, 1.0);
|
|
198
199
|
|
|
199
200
|
mat.thinFilmThickness *= 1000.0;
|
|
200
|
-
mat.baseWeight = clamp(
|
|
201
|
-
mat.diffuseRoughness = clamp(
|
|
202
|
-
mat.specularWeight = max(0.0,
|
|
203
|
-
mat.subsurfaceWeight = clamp(
|
|
204
|
-
mat.specularColor = max(
|
|
205
|
-
mat.fuzzWeight = clamp(
|
|
201
|
+
mat.baseWeight = clamp(mi.x, 0.0, 1.0);
|
|
202
|
+
mat.diffuseRoughness = clamp(mi.y, 0.0, 1.0);
|
|
203
|
+
mat.specularWeight = max(0.0, mi.z);
|
|
204
|
+
mat.subsurfaceWeight = clamp(mi.w, 0.0, 1.0);
|
|
205
|
+
mat.specularColor = max(pP.rgb, vec3(0.0));
|
|
206
|
+
mat.fuzzWeight = clamp(pP.w, 0.0, 1.0);
|
|
206
207
|
mat.subsurfaceColor = max(subsurface.rgb, vec3(0.0));
|
|
207
208
|
mat.transmissionColor = max(fetchMatData(i + MAT_ROW_TRANSMISSION_COLOR).rgb, vec3(0.0));
|
|
208
|
-
mat.fuzzColor = max(
|
|
209
|
-
mat.fuzzRoughness = clamp(
|
|
210
|
-
mat.coatColor = max(
|
|
211
|
-
mat.coatWeight = clamp(
|
|
212
|
-
mat.coatRoughness = clamp(
|
|
213
|
-
mat.coatAnisotropy = clamp(
|
|
214
|
-
mat.coatIor = max(
|
|
215
|
-
mat.coatDarkening = clamp(
|
|
209
|
+
mat.fuzzColor = max(yJ.rgb, vec3(0.0));
|
|
210
|
+
mat.fuzzRoughness = clamp(yJ.w, 0.0, 1.0);
|
|
211
|
+
mat.coatColor = max(coat.rgb, vec3(0.0));
|
|
212
|
+
mat.coatWeight = clamp(coat.w, 0.0, 1.0);
|
|
213
|
+
mat.coatRoughness = clamp(mk.x, ROUGHNESS_MIN, 1.0);
|
|
214
|
+
mat.coatAnisotropy = clamp(mk.y, 0.0, 1.0);
|
|
215
|
+
mat.coatIor = max(mk.z, 1.0);
|
|
216
|
+
mat.coatDarkening = clamp(mk.w, 0.0, 1.0);
|
|
216
217
|
|
|
217
218
|
#ifdef HAS_MEDIUM
|
|
218
219
|
mat.mediumExtinction = max(fetchMatData(i + MAT_ROW_MEDIUM_EXTINCTION).rgb, vec3(0.0));
|
|
@@ -223,13 +224,13 @@ mat.mediumType = max(max(mat.mediumExtinction.x, mat.mediumExtinction.y), mat.me
|
|
|
223
224
|
|
|
224
225
|
|
|
225
226
|
#ifdef HAS_ALPHA
|
|
226
|
-
mat.alpha =
|
|
227
|
+
mat.alpha = oh.r;
|
|
227
228
|
#else
|
|
228
229
|
mat.alpha = 1.0;
|
|
229
230
|
#endif
|
|
230
231
|
|
|
231
232
|
#ifdef NUM_DIFFUSE_MAPS
|
|
232
|
-
int diffuseMapIndex = int(
|
|
233
|
+
int diffuseMapIndex = int(gm.z);
|
|
233
234
|
if (diffuseMapIndex >= 0) {
|
|
234
235
|
vec4 diffuse = sampleMap(
|
|
235
236
|
diffuseMapIndex, getMapUvSet(diffuseMapIndex, uv, uv1)
|
|
@@ -250,21 +251,21 @@ mat.alpha *= diffuse.a;
|
|
|
250
251
|
|
|
251
252
|
${simpleTextureSample('alphaMap', 'glsl')}
|
|
252
253
|
|
|
253
|
-
mat.alpha =
|
|
254
|
-
mat.alpha, int(fetchMatData(i + MAT_ROW_ALPHA).w),
|
|
254
|
+
mat.alpha = lJ(
|
|
255
|
+
mat.alpha, int(fetchMatData(i + MAT_ROW_ALPHA).w), og.w
|
|
255
256
|
);
|
|
256
257
|
|
|
257
258
|
${simpleTextureSample('transmissionMap', 'glsl')}
|
|
258
259
|
|
|
259
260
|
#ifdef NUM_METALLIC_ROUGHNESS_MAPS
|
|
260
|
-
int metallicRoughnessMapIndex = int(
|
|
261
|
+
int metallicRoughnessMapIndex = int(gm.w);
|
|
261
262
|
if (metallicRoughnessMapIndex >= 0) {
|
|
262
|
-
vec4
|
|
263
|
+
vec4 fO = sampleMap(
|
|
263
264
|
metallicRoughnessMapIndex,
|
|
264
265
|
getMapUvSet(metallicRoughnessMapIndex, uv, uv1)
|
|
265
266
|
);
|
|
266
|
-
mat.baseMetalness *=
|
|
267
|
-
mat.specularRoughness *=
|
|
267
|
+
mat.baseMetalness *= fO.b;
|
|
268
|
+
mat.specularRoughness *= fO.g;
|
|
268
269
|
}
|
|
269
270
|
#endif
|
|
270
271
|
|
|
@@ -273,7 +274,7 @@ ${simpleTextureSample('roughnessMap', 'glsl')}
|
|
|
273
274
|
${simpleTextureSample('metalnessMap', 'glsl')}
|
|
274
275
|
|
|
275
276
|
#ifdef NUM_EMISSIVE_MAPS
|
|
276
|
-
int emissiveMapIndex = int(
|
|
277
|
+
int emissiveMapIndex = int(hF.w);
|
|
277
278
|
if (emissiveMapIndex >= 0) {
|
|
278
279
|
vec3 emissive = sampleMap(
|
|
279
280
|
emissiveMapIndex, getMapUvSet(emissiveMapIndex, uv, uv1)
|
|
@@ -283,12 +284,12 @@ mat.emission *= decodeMapColor(emissiveMapIndex, emissive);
|
|
|
283
284
|
#endif
|
|
284
285
|
|
|
285
286
|
#ifdef NUM_COAT_WEIGHT_MAPS
|
|
286
|
-
int
|
|
287
|
-
if (
|
|
288
|
-
float
|
|
289
|
-
|
|
287
|
+
int hM = int(fetchMatData(i + MAT_ROW_LAYER_MAPS).x);
|
|
288
|
+
if (hM >= 0 && mat.materialType == 0) {
|
|
289
|
+
float rs = clamp(coat.w, 0.0, 1.0) * sampleMap(
|
|
290
|
+
hM, getMapUvSet(hM, uv, uv1)
|
|
290
291
|
).r;
|
|
291
|
-
mat.emission *= mix(vec3(1.0), sqrt(max(
|
|
292
|
+
mat.emission *= mix(vec3(1.0), sqrt(max(coat.rgb, vec3(0.0))), rs);
|
|
292
293
|
}
|
|
293
294
|
#endif
|
|
294
295
|
|
|
@@ -297,7 +298,7 @@ ${thinFilmTextureSample('glsl')}
|
|
|
297
298
|
${simpleTextureSample('coatWeightMap', 'glsl')}
|
|
298
299
|
#ifdef USE_COAT_NORMAL_FRAMES
|
|
299
300
|
|
|
300
|
-
mat.coatNormalEnabled = mat.coatWeight > 0.0 && (
|
|
301
|
+
mat.coatNormalEnabled = mat.coatWeight > 0.0 && (roughnessAndNormal.y >= 0.0 || fetchMatData(i + MAT_ROW_LAYER_MAPS).z >= 0.0);
|
|
301
302
|
#endif
|
|
302
303
|
|
|
303
304
|
${simpleTextureSample('coatRoughnessMap', 'glsl')}
|
|
@@ -310,29 +311,29 @@ ${simpleTextureSample('specularWeightMap', 'glsl')}
|
|
|
310
311
|
|
|
311
312
|
${simpleTextureSample('specularColorMap', 'glsl')}
|
|
312
313
|
|
|
313
|
-
vec4
|
|
314
|
+
vec4 lk = fetchMatData(i + MAT_ROW_DIRECTION_NORMAL);
|
|
314
315
|
mat.anisotropyDirection = vec2(1.0, 0.0);
|
|
315
|
-
mat.anisotropyDirectionEnabled =
|
|
316
|
+
mat.anisotropyDirectionEnabled = lk.y != 0.0;
|
|
316
317
|
mat.coatAnisotropyRotation = fetchMatData(i + MAT_ROW_FILM_TEXTURE).x;
|
|
317
318
|
#ifdef NUM_ANISOTROPY_MAPS
|
|
318
|
-
if (
|
|
319
|
-
int index = int(
|
|
320
|
-
vec4
|
|
321
|
-
mat.specularAnisotropy *=
|
|
322
|
-
vec2 direction =
|
|
319
|
+
if (lk.x >= 0.0) {
|
|
320
|
+
int index = int(lk.x);
|
|
321
|
+
vec4 cR = sampleMap(index, getMapUvSet(index, uv, uv1));
|
|
322
|
+
mat.specularAnisotropy *= cR.b;
|
|
323
|
+
vec2 direction = cR.rg * 2.0 - 1.0;
|
|
323
324
|
if (dot(direction, direction) > 1e-4) mat.anisotropyDirection = normalize(direction);
|
|
324
325
|
mat.anisotropyDirectionEnabled = true;
|
|
325
326
|
}
|
|
326
327
|
#endif
|
|
327
328
|
#ifdef HAS_GLTF_ANISOTROPY
|
|
328
329
|
if (fetchMatData(i + MAT_ROW_FILM_TEXTURE).y > 0.5 && mat.specularAnisotropy > 0.0) {
|
|
329
|
-
vec2
|
|
330
|
-
mat.specularRoughness =
|
|
331
|
-
mat.specularAnisotropy =
|
|
330
|
+
vec2 tX = fb(clamp(mat.specularRoughness, 0.0, 1.0), mat.specularAnisotropy);
|
|
331
|
+
mat.specularRoughness = tX.x;
|
|
332
|
+
mat.specularAnisotropy = tX.y;
|
|
332
333
|
}
|
|
333
334
|
#endif
|
|
334
335
|
if (mat.anisotropyDirectionEnabled) {
|
|
335
|
-
float theta =
|
|
336
|
+
float theta = lk.y;
|
|
336
337
|
vec2 d = mat.anisotropyDirection;
|
|
337
338
|
mat.anisotropyDirection = vec2(cos(theta)*d.x - sin(theta)*d.y, sin(theta)*d.x + cos(theta)*d.y);
|
|
338
339
|
}
|
|
@@ -340,57 +341,57 @@ mat.anisotropyDirection = vec2(cos(theta)*d.x - sin(theta)*d.y, sin(theta)*d.x +
|
|
|
340
341
|
|
|
341
342
|
|
|
342
343
|
if (mat.coatWeight > 0.0 && mat.coatRoughness > 0.0) {
|
|
343
|
-
float
|
|
344
|
-
float
|
|
344
|
+
float hJ = mat.specularRoughness * mat.specularRoughness;
|
|
345
|
+
float hK = mat.coatRoughness * mat.coatRoughness;
|
|
345
346
|
mat.specularRoughness = mix(mat.specularRoughness,
|
|
346
|
-
pow(min(1.0,
|
|
347
|
+
pow(min(1.0, hJ * hJ + 2.0 * hK * hK), 0.25), mat.coatWeight);
|
|
347
348
|
}
|
|
348
|
-
vec3 color =
|
|
349
|
+
vec3 color = kV(instanceIndex) * vertexColor;
|
|
349
350
|
mat.baseColor *= color;
|
|
350
351
|
if (mat.materialType == UNLIT) mat.emission *= color;
|
|
351
352
|
|
|
352
|
-
mat.specularRoughness = clamp(mat.specularRoughness, ROUGHNESS_MIN, 1.0);
|
|
353
|
+
${fragments['material0'] ?? ''} mat.specularRoughness = clamp(mat.specularRoughness, ROUGHNESS_MIN, 1.0);
|
|
353
354
|
mat.baseMetalness = clamp(mat.baseMetalness, 0.0, 1.0);
|
|
354
|
-
vec2 specularAlpha =
|
|
355
|
+
vec2 specularAlpha = aL(mat.specularRoughness, mat.specularAnisotropy);
|
|
355
356
|
mat.alphaX = specularAlpha.x;
|
|
356
357
|
mat.alphaY = specularAlpha.y;
|
|
357
358
|
}
|
|
358
359
|
|
|
359
360
|
#if defined(NUM_NORMAL_MAPS)
|
|
360
|
-
vec3
|
|
361
|
+
vec3 oS(int materialIndex, vec2 uv, vec3 normal, vec3 dp1, vec3 dp2, vec2 oM, vec2 oN) {
|
|
361
362
|
int i = materialIndex * MAT_DATA_SIZE;
|
|
362
|
-
vec4
|
|
363
|
-
int normalMapIndex = int(
|
|
363
|
+
vec4 roughnessAndNormal = fetchMatData(i + MAT_ROW_ROUGHNESS_NORMAL);
|
|
364
|
+
int normalMapIndex = int(roughnessAndNormal.y);
|
|
364
365
|
if (normalMapIndex >= 0) {
|
|
365
366
|
|
|
366
367
|
|
|
367
368
|
|
|
368
|
-
vec3
|
|
369
|
-
vec3
|
|
370
|
-
vec3 dpdu =
|
|
371
|
-
vec3
|
|
372
|
-
float
|
|
373
|
-
if (
|
|
374
|
-
float
|
|
375
|
-
dpdu *=
|
|
376
|
-
|
|
369
|
+
vec3 rX = cross(dp2, normal);
|
|
370
|
+
vec3 rW = cross(normal, dp1);
|
|
371
|
+
vec3 dpdu = rX * oM.x + rW * oN.x;
|
|
372
|
+
vec3 tI = rX * oM.y + rW * oN.y;
|
|
373
|
+
float dT = max(dot(dpdu, dpdu), dot(tI, tI));
|
|
374
|
+
if (dT > 1e-12) {
|
|
375
|
+
float tQ = inversesqrt(dT);
|
|
376
|
+
dpdu *= tQ;
|
|
377
|
+
tI *= tQ;
|
|
377
378
|
}
|
|
378
379
|
else {
|
|
379
380
|
|
|
380
381
|
|
|
381
382
|
|
|
382
|
-
vec3
|
|
383
|
+
vec3 ob = abs(normal.z) < 0.999
|
|
383
384
|
? vec3(0.0, 0.0, 1.0)
|
|
384
385
|
: vec3(0.0, 1.0, 0.0);
|
|
385
|
-
dpdu = normalize(cross(
|
|
386
|
-
|
|
386
|
+
dpdu = normalize(cross(ob, normal));
|
|
387
|
+
tI = cross(normal, dpdu);
|
|
387
388
|
}
|
|
388
389
|
|
|
389
390
|
vec3 n = 2.0 * sampleMap(normalMapIndex, uv).rgb - 1.0;
|
|
390
|
-
n.xy *=
|
|
391
|
+
n.xy *= roughnessAndNormal.zw;
|
|
391
392
|
n = normalize(n);
|
|
392
393
|
|
|
393
|
-
mat3 tbn = mat3(dpdu,
|
|
394
|
+
mat3 tbn = mat3(dpdu, tI, normal);
|
|
394
395
|
|
|
395
396
|
return normalize(tbn * n);
|
|
396
397
|
} else {
|
|
@@ -400,5 +401,7 @@ return normal;
|
|
|
400
401
|
#endif
|
|
401
402
|
|
|
402
403
|
`
|
|
403
|
-
});
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
export default createMaterialBufferGlsl();
|
|
404
407
|
//# sourceMappingURL=materialBuffer.glsl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"materialBuffer.glsl.js","sourceRoot":"","sources":["../../../../src/renderer/glsl/chunks/materialBuffer.glsl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAElE,eAAe,iBAAiB,CAAC;IAC/B,QAAQ,EAAE;QACR,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;QAC3C,qBAAqB,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/C,OAAO,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC;QAChD,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC;QACrD,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC;QACtD,cAAc,EAAE,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC;QACxD,OAAO,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC;QAChD,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC;KACtC;IACD,OAAO,EAAE;QACP,aAAa,EAAE,CAAC;KACjB;IACD,IAAI,EAAE,IAAI,CAAA;EACV,gBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;mBAqBC,0BAA0B,CAAC,MAAM;;;mBAGjC,0BAA0B,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAmGhB,oBAAoB,GAAG,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBA8FhC,sBAAsB,CAAC,YAAY,GAAG,EAAE;;;4BAGnC,sBAAsB,CAAC,KAAK,GAAG,EAAE;;;;;;EAM/D,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC;;;;;;EAMvC,mBAAmB,CAAC,iBAAiB,EAAE,MAAM,CAAC;;;;;;;;;;;;;;EAc9C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;EAsB3C,qBAAqB,CAAC,MAAM,CAAC;;EAE7B,mBAAmB,CAAC,eAAe,EAAE,MAAM,CAAC;;;;;;EAM5C,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2FlD;CACA,CAAC,CAAC","sourcesContent":["import { simpleTextureSample, thinFilmTextureSample } from '../../materialTextureSlots.js';\nimport { materialRowsGlsl } from '../../materialLayoutSchema.js';\nimport { materialAlphaModeConstants } from '../../materialConstants.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 { createShaderMixin, glsl, Shader } from '../../shader.js';\n\nexport default createShaderMixin({\n uniforms: {\n materialBuffer: Shader.uniform('sampler2D'),\n materialBufferColumns: Shader.uniform('int', 1),\n mapInfo: Shader.arrayUniform('vec4', 'NUM_MAPS'),\n mapTransform: Shader.arrayUniform('vec4', 'NUM_MAPS'),\n mapUvChannel: Shader.arrayUniform('float', 'NUM_MAPS'),\n mapColorLinear: Shader.arrayUniform('float', 'NUM_MAPS'),\n mapWrap: Shader.arrayUniform('vec2', 'NUM_MAPS'),\n map: Shader.uniform('sampler2DArray')\n },\n defines: {\n NUM_MATERIALS: 1\n },\n main: glsl`\n${materialRowsGlsl()}\n#ifdef HAS_GLTF_ANISOTROPY\nvec2 gltf_anisotropy_to_openpbr(float roughness, float strength) {\n if (strength == 0.0) { return vec2(roughness, 0.0); }\n float u = roughness * roughness;\n float a = u + (1.0 - u) * strength * strength;\n if (a == 0.0) { return vec2(0.0); }\n return vec2(pow((a*a + u*u) * 0.5, 0.25), clamp(1.0 - u/a, 0.0, 1.0));\n}\n\n#endif\n\nvec3 sRGBToLinear(vec3 c) {\n return mix(pow(c * 0.9478672986 + 0.0521327014, vec3(2.4)), c * 0.0773993808, vec3(lessThan(c, vec3(0.04045))));\n}\nvec4 fetchMatData(int i) {\n return fetchData(materialBuffer, i, materialBufferColumns);\n}\n\n// Shared by surface evaluation and shadow occlusion, after texture factors.\nfloat resolveMaterialAlpha(float alpha, int alphaMode, float alphaCutoff) {\n if (alphaMode == ${materialAlphaModeConstants.opaque}) {\n return 1.0;\n }\n if (alphaMode == ${materialAlphaModeConstants.mask}) {\n return alpha >= alphaCutoff ? 1.0 : 0.0;\n }\n return alpha;\n}\n\nfloat getMatType(int idx) {\n return fetchMatData(idx * MAT_DATA_SIZE + MAT_ROW_COLOR).w;\n}\n\nvec2 unpackMaterialIndex(int val) {\n return vec2(float(val >> 8), float(val & 0xff) / 255.0);\n}\n\n#ifdef NUM_MAPS\nvec3 decodeMapColor(int index, vec3 c) {\n if (mapColorLinear[index] > 0.5) { return c; }\n return sRGBToLinear(c);\n}\n\nvec2 getMapSize(int index) {\n return mapInfo[index].xy;\n}\n\nfloat getMapLayer(int index) {\n return floor(mapInfo[index].z);\n}\n\nvec2 getMapOffset(int index) {\n return vec2(fract(mapInfo[index].z), mapInfo[index].w);\n}\n\nfloat wrapMapCoordinate(float value, float mode) {\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\nvec2 wrappedMapUv(int index, vec2 uv) {\n vec4 transform = mapTransform[index];\n vec2 value = uv * transform.xy + transform.zw;\n return vec2(wrapMapCoordinate(value.x, mapWrap[index].x), wrapMapCoordinate(value.y, mapWrap[index].y));\n}\n\nvec2 getMapUV(int index, vec2 uv) {\n vec2 repeatedUv = wrappedMapUv(index, uv);\n vec2 atlasTexel = 1.0 / vec2(textureSize(map, 0).xy);\n vec2 firstTexelCenter = getMapOffset(index);\n vec2 sourceExtent = getMapSize(index) + atlasTexel;\n vec2 sourceOrigin = firstTexelCenter - 0.5 * atlasTexel;\n vec2 lastTexelCenter = firstTexelCenter + sourceExtent - atlasTexel;\n return clamp(\n sourceOrigin + repeatedUv * sourceExtent,\n firstTexelCenter,\n lastTexelCenter\n );\n}\n\nvec2 getMapUvSet(int index, vec2 uv, vec2 uv1) {\n return mapUvChannel[index] > 0.5 ? uv1 : uv;\n}\n\nvec4 loadMapTexel(int index, ivec2 coordinate, ivec2 size, ivec2 origin, vec2 modes) {\n ivec2 p = clamp(coordinate, ivec2(0), size - 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 texelFetch(map, ivec3(origin + p, int(getMapLayer(index))), 0);\n}\n\nvec4 sampleMap(int index, vec2 uv) {\n ivec2 size = ivec2(round(getMapSize(index) * vec2(textureSize(map, 0).xy) + 1.0));\n vec2 texel = wrappedMapUv(index, uv) * vec2(size) - 0.5;\n vec2 modes = mapWrap[index];\n if ((size.x > 1 && modes.x < 0.5 && (texel.x < 0.0 || texel.x > float(size.x - 1))) ||\n (size.y > 1 && modes.y < 0.5 && (texel.y < 0.0 || texel.y > float(size.y - 1)))) {\n ivec2 base = ivec2(floor(texel));\n vec2 weight = fract(texel);\n ivec2 origin = ivec2(round(getMapOffset(index) * vec2(textureSize(map, 0).xy) - 0.5));\n return mix(\n mix(loadMapTexel(index, base, size, origin, modes), loadMapTexel(index, base + ivec2(1, 0), size, origin, modes), weight.x),\n mix(loadMapTexel(index, base + ivec2(0, 1), size, origin, modes), loadMapTexel(index, base + ivec2(1, 1), size, origin, modes), weight.x), weight.y);\n }\n return texture(map, vec3(getMapUV(index, uv), getMapLayer(index)));\n}\n#endif\n\n// OpenPBR 1.1.1: RMS-preserving GGX anisotropy, shared by base and coat.\nvec2 openpbr_roughness_to_alpha(float roughness, float anisotropy) {\n float alpha = roughness * roughness;\n float alphaMin = ROUGHNESS_MIN * ROUGHNESS_MIN;\n if (anisotropy == 0.0) { return vec2(max(alphaMin, alpha)); }\n float complement = 1.0 - anisotropy;\n float alphaT = alpha * sqrt(2.0 / (1.0 + complement * complement));\n return max(vec2(alphaMin), vec2(alphaT, complement * alphaT));\n}\n\nvec4 fetchIns(int i);\nvec3 getInstanceColor(int instanceIndex) {\n if (instanceIndex < 0) return vec3(1.0);\n return fetchIns(instanceIndex * ${INSTANCE_VEC4_STRIDE + ''} + 9).rgb;\n}\n\nvoid getMaterial(\n inout OpenPbrResolvedMaterial mat,\n int materialIndex,\n vec2 uv,\n vec2 uv1,\n int instanceIndex,\n vec3 vertexColor\n) {\n int i = materialIndex * MAT_DATA_SIZE;\n vec4 colorAndMatType = fetchMatData(i + MAT_ROW_COLOR);\n vec4 roughnessAndNormal = fetchMatData(i + MAT_ROW_ROUGHNESS_NORMAL);\n vec4 metallicAndMapIndex = fetchMatData(i + MAT_ROW_METALLIC_MAPS);\n vec4 emissionAndEmissiveMapIndex = fetchMatData(i + MAT_ROW_EMISSION);\n vec4 iorAndTransmission = fetchMatData(i + MAT_ROW_IOR_TRANSMISSION);\n vec4 misc = fetchMatData(i + MAT_ROW_MISC);\n vec4 alphaAndThinFilm = fetchMatData(i + MAT_ROW_ALPHA_FILM);\n vec4 baseControls = fetchMatData(i + MAT_ROW_BASE_CONTROLS);\n vec4 specularAndFuzz = fetchMatData(i + MAT_ROW_SPECULAR_FUZZ);\n vec4 subsurface = fetchMatData(i + MAT_ROW_SUBSURFACE);\n vec4 fuzz = fetchMatData(i + MAT_ROW_FUZZ);\n vec4 coat = fetchMatData(i + MAT_ROW_COAT);\n vec4 coatControls = fetchMatData(i + MAT_ROW_COAT_CONTROLS);\n vec4 filmAndDispersion = fetchMatData(i + MAT_ROW_FILM_DISPERSION);\n vec4 standaloneMetalRoughMaps = fetchMatData(i + MAT_ROW_STANDALONE_MAPS);\n int mapAlphaUsage = int(misc.a);\n\n mat.baseColor = colorAndMatType.rgb;\n mat.materialType = int(colorAndMatType.w);\n mat.specularRoughness = roughnessAndNormal.x;\n mat.baseMetalness = metallicAndMapIndex.x;\n mat.specularAnisotropy = clamp(metallicAndMapIndex.y, 0.0, 1.0);\n mat.emission = emissionAndEmissiveMapIndex.rgb;\n mat.inside = false;\n mat.specularIor = iorAndTransmission.x;\n mat.transmissionWeight = iorAndTransmission.y;\n#ifdef HAS_MEDIUM\n mat.mediumType = int(iorAndTransmission.z);\n#else\n mat.mediumType = 0;\n#endif\n mat.thinWalled = iorAndTransmission.w > 0.5;\n mat.bevel = misc.r;\n mat.transmissionDispersionScale = misc.g;\n mat.dispersionAbbeNumber = max(filmAndDispersion.y, 1e-6);\n mat.thinFilmThickness = misc.b;\n mat.thinFilmIor = alphaAndThinFilm.b;\n mat.thinFilmWeight = clamp(filmAndDispersion.x, 0.0, 1.0);\n // OpenPBR specifies micrometres; the interference routine uses nanometres.\n mat.thinFilmThickness *= 1000.0;\n mat.baseWeight = clamp(baseControls.x, 0.0, 1.0);\n mat.diffuseRoughness = clamp(baseControls.y, 0.0, 1.0);\n mat.specularWeight = max(0.0, baseControls.z);\n mat.subsurfaceWeight = clamp(baseControls.w, 0.0, 1.0);\n mat.specularColor = max(specularAndFuzz.rgb, vec3(0.0));\n mat.fuzzWeight = clamp(specularAndFuzz.w, 0.0, 1.0);\n mat.subsurfaceColor = max(subsurface.rgb, vec3(0.0));\n mat.transmissionColor = max(fetchMatData(i + MAT_ROW_TRANSMISSION_COLOR).rgb, vec3(0.0));\n mat.fuzzColor = max(fuzz.rgb, vec3(0.0));\n mat.fuzzRoughness = clamp(fuzz.w, 0.0, 1.0);\n mat.coatColor = max(coat.rgb, vec3(0.0));\n mat.coatWeight = clamp(coat.w, 0.0, 1.0);\n mat.coatRoughness = clamp(coatControls.x, ROUGHNESS_MIN, 1.0);\n mat.coatAnisotropy = clamp(coatControls.y, 0.0, 1.0);\n mat.coatIor = max(coatControls.z, 1.0);\n mat.coatDarkening = clamp(coatControls.w, 0.0, 1.0);\n\n#ifdef HAS_MEDIUM\n mat.mediumExtinction = max(fetchMatData(i + MAT_ROW_MEDIUM_EXTINCTION).rgb, vec3(0.0));\n mat.mediumAnisotropy = clamp(fetchMatData(i + MAT_ROW_MEDIUM_EXTINCTION).a, -1.0, 1.0);\n mat.mediumScattering = max(fetchMatData(i + MAT_ROW_MEDIUM_SCATTERING).rgb, vec3(0.0));\n mat.mediumType = max(max(mat.mediumExtinction.x, mat.mediumExtinction.y), mat.mediumExtinction.z) > 0.0 ? 1 : 0;\n#endif\n\n\n#ifdef HAS_ALPHA\n mat.alpha = alphaAndThinFilm.r;\n#else\n mat.alpha = 1.0;\n#endif\n\n #ifdef NUM_DIFFUSE_MAPS\n int diffuseMapIndex = int(metallicAndMapIndex.z);\n if (diffuseMapIndex >= 0) {\n vec4 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 mat.baseColor *= decodeMapColor(diffuseMapIndex, diffuse.rgb);\n\n // Map alpha to transmission\n if (mapAlphaUsage == ${mapAlphaUsageConstants.transmission + ''}) {\n mat.transmissionWeight = 1.0 - diffuse.a;\n }\n else if (mapAlphaUsage == ${mapAlphaUsageConstants.alpha + ''}) {\n mat.alpha *= diffuse.a;\n }\n }\n #endif\n\n ${simpleTextureSample('alphaMap', 'glsl')}\n\n mat.alpha = resolveMaterialAlpha(\n mat.alpha, int(fetchMatData(i + MAT_ROW_ALPHA).w), standaloneMetalRoughMaps.w\n );\n\n ${simpleTextureSample('transmissionMap', 'glsl')}\n\n #ifdef NUM_METALLIC_ROUGHNESS_MAPS\n int metallicRoughnessMapIndex = int(metallicAndMapIndex.w);\n if (metallicRoughnessMapIndex >= 0) {\n vec4 metallicRoughness = sampleMap(\n metallicRoughnessMapIndex,\n getMapUvSet(metallicRoughnessMapIndex, uv, uv1)\n );\n mat.baseMetalness *= metallicRoughness.b;\n mat.specularRoughness *= metallicRoughness.g;\n }\n #endif\n\n ${simpleTextureSample('roughnessMap', 'glsl')}\n\n ${simpleTextureSample('metalnessMap', 'glsl')}\n\n #ifdef NUM_EMISSIVE_MAPS\n int emissiveMapIndex = int(emissionAndEmissiveMapIndex.w);\n if (emissiveMapIndex >= 0) {\n vec3 emissive = sampleMap(\n emissiveMapIndex, getMapUvSet(emissiveMapIndex, uv, uv1)\n ).rgb;\n mat.emission *= decodeMapColor(emissiveMapIndex, emissive);\n }\n #endif\n\n #ifdef NUM_COAT_WEIGHT_MAPS\n int emissionCoatMapIndex = int(fetchMatData(i + MAT_ROW_LAYER_MAPS).x);\n if (emissionCoatMapIndex >= 0 && mat.materialType == 0) {\n float emissionCoatWeight = clamp(coat.w, 0.0, 1.0) * sampleMap(\n emissionCoatMapIndex, getMapUvSet(emissionCoatMapIndex, uv, uv1)\n ).r;\n mat.emission *= mix(vec3(1.0), sqrt(max(coat.rgb, vec3(0.0))), emissionCoatWeight);\n }\n #endif\n\n ${thinFilmTextureSample('glsl')}\n\n ${simpleTextureSample('coatWeightMap', 'glsl')}\n#ifdef USE_COAT_NORMAL_FRAMES\n // Independent coat shading also applies when the coat has no normal map.\n mat.coatNormalEnabled = mat.coatWeight > 0.0 && (roughnessAndNormal.y >= 0.0 || fetchMatData(i + MAT_ROW_LAYER_MAPS).z >= 0.0);\n#endif\n\n ${simpleTextureSample('coatRoughnessMap', 'glsl')}\n\n ${simpleTextureSample('fuzzColorMap', 'glsl')}\n\n ${simpleTextureSample('fuzzRoughnessMap', 'glsl')}\n\n ${simpleTextureSample('specularWeightMap', 'glsl')}\n\n ${simpleTextureSample('specularColorMap', 'glsl')}\n\n vec4 directionInfo = fetchMatData(i + MAT_ROW_DIRECTION_NORMAL);\n mat.anisotropyDirection = vec2(1.0, 0.0);\n mat.anisotropyDirectionEnabled = directionInfo.y != 0.0;\n mat.coatAnisotropyRotation = fetchMatData(i + MAT_ROW_FILM_TEXTURE).x;\n#ifdef NUM_ANISOTROPY_MAPS\n if (directionInfo.x >= 0.0) {\n int index = int(directionInfo.x);\n vec4 texel = sampleMap(index, getMapUvSet(index, uv, uv1));\n mat.specularAnisotropy *= texel.b;\n vec2 direction = texel.rg * 2.0 - 1.0;\n if (dot(direction, direction) > 1e-4) mat.anisotropyDirection = normalize(direction);\n mat.anisotropyDirectionEnabled = true;\n }\n#endif\n#ifdef HAS_GLTF_ANISOTROPY\n if (fetchMatData(i + MAT_ROW_FILM_TEXTURE).y > 0.5 && mat.specularAnisotropy > 0.0) {\n vec2 native = gltf_anisotropy_to_openpbr(clamp(mat.specularRoughness, 0.0, 1.0), mat.specularAnisotropy);\n mat.specularRoughness = native.x;\n mat.specularAnisotropy = native.y;\n }\n#endif\n if (mat.anisotropyDirectionEnabled) {\n float theta = directionInfo.y;\n vec2 d = mat.anisotropyDirection;\n mat.anisotropyDirection = vec2(cos(theta)*d.x - sin(theta)*d.y, sin(theta)*d.x + cos(theta)*d.y);\n }\n\n // OpenPBR 1.1.1: coat refraction broadens all base microfacet lobes.\n // Keep the zero-coat / smooth-coat paths byte-identical.\n if (mat.coatWeight > 0.0 && mat.coatRoughness > 0.0) {\n float baseRoughness2 = mat.specularRoughness * mat.specularRoughness;\n float coatRoughness2 = mat.coatRoughness * mat.coatRoughness;\n mat.specularRoughness = mix(mat.specularRoughness,\n pow(min(1.0, baseRoughness2 * baseRoughness2 + 2.0 * coatRoughness2 * coatRoughness2), 0.25), mat.coatWeight);\n }\n vec3 color = getInstanceColor(instanceIndex) * vertexColor;\n mat.baseColor *= color;\n if (mat.materialType == UNLIT) mat.emission *= color;\n\n mat.specularRoughness = clamp(mat.specularRoughness, ROUGHNESS_MIN, 1.0);\n mat.baseMetalness = clamp(mat.baseMetalness, 0.0, 1.0);\n vec2 specularAlpha = openpbr_roughness_to_alpha(mat.specularRoughness, mat.specularAnisotropy);\n mat.alphaX = specularAlpha.x;\n mat.alphaY = specularAlpha.y;\n}\n\n#if defined(NUM_NORMAL_MAPS)\nvec3 getMatNormal(int materialIndex, vec2 uv, vec3 normal, vec3 dp1, vec3 dp2, vec2 duv1, vec2 duv2) {\n int i = materialIndex * MAT_DATA_SIZE;\n vec4 roughnessAndNormal = fetchMatData(i + MAT_ROW_ROUGHNESS_NORMAL);\n int normalMapIndex = int(roughnessAndNormal.y);\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 vec3 dp2perp = cross(dp2, normal);\n vec3 dp1perp = cross(normal, dp1);\n vec3 dpdu = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 dpdv = dp2perp * duv1.y + dp1perp * duv2.y;\n float gradientLengthSquared = max(dot(dpdu, dpdu), dot(dpdv, dpdv));\n if (gradientLengthSquared > 1e-12) {\n float invmax = inversesqrt(gradientLengthSquared);\n dpdu *= invmax;\n dpdv *= invmax;\n }\n else {\n // Imported meshes can legitimately omit UVs and use generated or\n // triplanar projection. Their zero UV derivatives must not turn the TBN\n // basis (and then every lighting result) into NaN.\n vec3 referenceAxis = abs(normal.z) < 0.999\n ? vec3(0.0, 0.0, 1.0)\n : vec3(0.0, 1.0, 0.0);\n dpdu = normalize(cross(referenceAxis, normal));\n dpdv = cross(normal, dpdu);\n }\n\n vec3 n = 2.0 * sampleMap(normalMapIndex, uv).rgb - 1.0;\n n.xy *= roughnessAndNormal.zw;\n n = normalize(n);\n\n mat3 tbn = mat3(dpdu, dpdv, normal);\n\n return normalize(tbn * n);\n } else {\n return normal;\n }\n}\n#endif\n\n`\n});\n"]}
|
|
1
|
+
{"version":3,"file":"materialBuffer.glsl.js","sourceRoot":"","sources":["../../../../src/renderer/glsl/chunks/materialBuffer.glsl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAElE,MAAM,UAAU,wBAAwB,CAAC,YAA8C,EAAE;IAAI,OAAO,iBAAiB,CAAC;QACpH,QAAQ,EAAE;YACR,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;YAC3C,qBAAqB,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;YAC/C,OAAO,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC;YAChD,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC;YACrD,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC;YACtD,cAAc,EAAE,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC;YACxD,OAAO,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC;YAChD,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC;SACtC;QACD,OAAO,EAAE;YACP,aAAa,EAAE,CAAC;SACjB;QACD,IAAI,EAAE,IAAI,CAAA;EACV,gBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;mBAqBC,0BAA0B,CAAC,MAAM;;;mBAGjC,0BAA0B,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kCAmGhB,oBAAoB,GAAG,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBA8FhC,sBAAsB,CAAC,YAAY,GAAG,EAAE;;;4BAGnC,sBAAsB,CAAC,KAAK,GAAG,EAAE;;;;;;EAM/D,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC;;;;;;EAMvC,mBAAmB,CAAC,iBAAiB,EAAE,MAAM,CAAC;;;;;;;;;;;;;;EAc9C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;EAsB3C,qBAAqB,CAAC,MAAM,CAAC;;EAE7B,mBAAmB,CAAC,eAAe,EAAE,MAAM,CAAC;;;;;;EAM5C,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCjD,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkD7B;KACA,CAAC,CAAC;AACH,CAAC;AACD,eAAe,wBAAwB,EAAE,CAAC","sourcesContent":["import { simpleTextureSample, thinFilmTextureSample } from '../../materialTextureSlots.js';\nimport { materialRowsGlsl } from '../../materialLayoutSchema.js';\nimport { materialAlphaModeConstants } from '../../materialConstants.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 { createShaderMixin, glsl, Shader } from '../../shader.js';\n\nexport function createMaterialBufferGlsl(fragments: Readonly<Record<string, string>> = {}) { return createShaderMixin({\n uniforms: {\n materialBuffer: Shader.uniform('sampler2D'),\n materialBufferColumns: Shader.uniform('int', 1),\n mapInfo: Shader.arrayUniform('vec4', 'NUM_MAPS'),\n mapTransform: Shader.arrayUniform('vec4', 'NUM_MAPS'),\n mapUvChannel: Shader.arrayUniform('float', 'NUM_MAPS'),\n mapColorLinear: Shader.arrayUniform('float', 'NUM_MAPS'),\n mapWrap: Shader.arrayUniform('vec2', 'NUM_MAPS'),\n map: Shader.uniform('sampler2DArray')\n },\n defines: {\n NUM_MATERIALS: 1\n },\n main: glsl`\n${materialRowsGlsl()}\n#ifdef HAS_GLTF_ANISOTROPY\nvec2 gltf_anisotropy_to_openpbr(float roughness, float strength) {\n if (strength == 0.0) { return vec2(roughness, 0.0); }\n float u = roughness * roughness;\n float a = u + (1.0 - u) * strength * strength;\n if (a == 0.0) { return vec2(0.0); }\n return vec2(pow((a*a + u*u) * 0.5, 0.25), clamp(1.0 - u/a, 0.0, 1.0));\n}\n\n#endif\n\nvec3 sRGBToLinear(vec3 c) {\n return mix(pow(c * 0.9478672986 + 0.0521327014, vec3(2.4)), c * 0.0773993808, vec3(lessThan(c, vec3(0.04045))));\n}\nvec4 fetchMatData(int i) {\n return fetchData(materialBuffer, i, materialBufferColumns);\n}\n\n// Shared by surface evaluation and shadow occlusion, after texture factors.\nfloat resolveMaterialAlpha(float alpha, int alphaMode, float alphaCutoff) {\n if (alphaMode == ${materialAlphaModeConstants.opaque}) {\n return 1.0;\n }\n if (alphaMode == ${materialAlphaModeConstants.mask}) {\n return alpha >= alphaCutoff ? 1.0 : 0.0;\n }\n return alpha;\n}\n\nfloat getMatType(int idx) {\n return fetchMatData(idx * MAT_DATA_SIZE + MAT_ROW_COLOR).w;\n}\n\nvec2 unpackMaterialIndex(int val) {\n return vec2(float(val >> 8), float(val & 0xff) / 255.0);\n}\n\n#ifdef NUM_MAPS\nvec3 decodeMapColor(int index, vec3 c) {\n if (mapColorLinear[index] > 0.5) { return c; }\n return sRGBToLinear(c);\n}\n\nvec2 getMapSize(int index) {\n return mapInfo[index].xy;\n}\n\nfloat getMapLayer(int index) {\n return floor(mapInfo[index].z);\n}\n\nvec2 getMapOffset(int index) {\n return vec2(fract(mapInfo[index].z), mapInfo[index].w);\n}\n\nfloat wrapMapCoordinate(float value, float mode) {\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\nvec2 wrappedMapUv(int index, vec2 uv) {\n vec4 transform = mapTransform[index];\n vec2 value = uv * transform.xy + transform.zw;\n return vec2(wrapMapCoordinate(value.x, mapWrap[index].x), wrapMapCoordinate(value.y, mapWrap[index].y));\n}\n\nvec2 getMapUV(int index, vec2 uv) {\n vec2 repeatedUv = wrappedMapUv(index, uv);\n vec2 atlasTexel = 1.0 / vec2(textureSize(map, 0).xy);\n vec2 firstTexelCenter = getMapOffset(index);\n vec2 sourceExtent = getMapSize(index) + atlasTexel;\n vec2 sourceOrigin = firstTexelCenter - 0.5 * atlasTexel;\n vec2 lastTexelCenter = firstTexelCenter + sourceExtent - atlasTexel;\n return clamp(\n sourceOrigin + repeatedUv * sourceExtent,\n firstTexelCenter,\n lastTexelCenter\n );\n}\n\nvec2 getMapUvSet(int index, vec2 uv, vec2 uv1) {\n return mapUvChannel[index] > 0.5 ? uv1 : uv;\n}\n\nvec4 loadMapTexel(int index, ivec2 coordinate, ivec2 size, ivec2 origin, vec2 modes) {\n ivec2 p = clamp(coordinate, ivec2(0), size - 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 texelFetch(map, ivec3(origin + p, int(getMapLayer(index))), 0);\n}\n\nvec4 sampleMap(int index, vec2 uv) {\n ivec2 size = ivec2(round(getMapSize(index) * vec2(textureSize(map, 0).xy) + 1.0));\n vec2 texel = wrappedMapUv(index, uv) * vec2(size) - 0.5;\n vec2 modes = mapWrap[index];\n if ((size.x > 1 && modes.x < 0.5 && (texel.x < 0.0 || texel.x > float(size.x - 1))) ||\n (size.y > 1 && modes.y < 0.5 && (texel.y < 0.0 || texel.y > float(size.y - 1)))) {\n ivec2 base = ivec2(floor(texel));\n vec2 weight = fract(texel);\n ivec2 origin = ivec2(round(getMapOffset(index) * vec2(textureSize(map, 0).xy) - 0.5));\n return mix(\n mix(loadMapTexel(index, base, size, origin, modes), loadMapTexel(index, base + ivec2(1, 0), size, origin, modes), weight.x),\n mix(loadMapTexel(index, base + ivec2(0, 1), size, origin, modes), loadMapTexel(index, base + ivec2(1, 1), size, origin, modes), weight.x), weight.y);\n }\n return texture(map, vec3(getMapUV(index, uv), getMapLayer(index)));\n}\n#endif\n\n// OpenPBR 1.1.1: RMS-preserving GGX anisotropy, shared by base and coat.\nvec2 openpbr_roughness_to_alpha(float roughness, float anisotropy) {\n float alpha = roughness * roughness;\n float alphaMin = ROUGHNESS_MIN * ROUGHNESS_MIN;\n if (anisotropy == 0.0) { return vec2(max(alphaMin, alpha)); }\n float complement = 1.0 - anisotropy;\n float alphaT = alpha * sqrt(2.0 / (1.0 + complement * complement));\n return max(vec2(alphaMin), vec2(alphaT, complement * alphaT));\n}\n\nvec4 fetchIns(int i);\nvec3 getInstanceColor(int instanceIndex) {\n if (instanceIndex < 0) return vec3(1.0);\n return fetchIns(instanceIndex * ${INSTANCE_VEC4_STRIDE + ''} + 9).rgb;\n}\n\nvoid getMaterial(\n inout OpenPbrResolvedMaterial mat,\n int materialIndex,\n vec2 uv,\n vec2 uv1,\n int instanceIndex,\n vec3 vertexColor\n) {\n int i = materialIndex * MAT_DATA_SIZE;\n vec4 colorAndMatType = fetchMatData(i + MAT_ROW_COLOR);\n vec4 roughnessAndNormal = fetchMatData(i + MAT_ROW_ROUGHNESS_NORMAL);\n vec4 metallicAndMapIndex = fetchMatData(i + MAT_ROW_METALLIC_MAPS);\n vec4 emissionAndEmissiveMapIndex = fetchMatData(i + MAT_ROW_EMISSION);\n vec4 iorAndTransmission = fetchMatData(i + MAT_ROW_IOR_TRANSMISSION);\n vec4 misc = fetchMatData(i + MAT_ROW_MISC);\n vec4 alphaAndThinFilm = fetchMatData(i + MAT_ROW_ALPHA_FILM);\n vec4 baseControls = fetchMatData(i + MAT_ROW_BASE_CONTROLS);\n vec4 specularAndFuzz = fetchMatData(i + MAT_ROW_SPECULAR_FUZZ);\n vec4 subsurface = fetchMatData(i + MAT_ROW_SUBSURFACE);\n vec4 fuzz = fetchMatData(i + MAT_ROW_FUZZ);\n vec4 coat = fetchMatData(i + MAT_ROW_COAT);\n vec4 coatControls = fetchMatData(i + MAT_ROW_COAT_CONTROLS);\n vec4 filmAndDispersion = fetchMatData(i + MAT_ROW_FILM_DISPERSION);\n vec4 standaloneMetalRoughMaps = fetchMatData(i + MAT_ROW_STANDALONE_MAPS);\n int mapAlphaUsage = int(misc.a);\n\n mat.baseColor = colorAndMatType.rgb;\n mat.materialType = int(colorAndMatType.w);\n mat.specularRoughness = roughnessAndNormal.x;\n mat.baseMetalness = metallicAndMapIndex.x;\n mat.specularAnisotropy = clamp(metallicAndMapIndex.y, 0.0, 1.0);\n mat.emission = emissionAndEmissiveMapIndex.rgb;\n mat.inside = false;\n mat.specularIor = iorAndTransmission.x;\n mat.transmissionWeight = iorAndTransmission.y;\n#ifdef HAS_MEDIUM\n mat.mediumType = int(iorAndTransmission.z);\n#else\n mat.mediumType = 0;\n#endif\n mat.thinWalled = iorAndTransmission.w > 0.5;\n mat.bevel = misc.r;\n mat.transmissionDispersionScale = misc.g;\n mat.dispersionAbbeNumber = max(filmAndDispersion.y, 1e-6);\n mat.thinFilmThickness = misc.b;\n mat.thinFilmIor = alphaAndThinFilm.b;\n mat.thinFilmWeight = clamp(filmAndDispersion.x, 0.0, 1.0);\n // OpenPBR specifies micrometres; the interference routine uses nanometres.\n mat.thinFilmThickness *= 1000.0;\n mat.baseWeight = clamp(baseControls.x, 0.0, 1.0);\n mat.diffuseRoughness = clamp(baseControls.y, 0.0, 1.0);\n mat.specularWeight = max(0.0, baseControls.z);\n mat.subsurfaceWeight = clamp(baseControls.w, 0.0, 1.0);\n mat.specularColor = max(specularAndFuzz.rgb, vec3(0.0));\n mat.fuzzWeight = clamp(specularAndFuzz.w, 0.0, 1.0);\n mat.subsurfaceColor = max(subsurface.rgb, vec3(0.0));\n mat.transmissionColor = max(fetchMatData(i + MAT_ROW_TRANSMISSION_COLOR).rgb, vec3(0.0));\n mat.fuzzColor = max(fuzz.rgb, vec3(0.0));\n mat.fuzzRoughness = clamp(fuzz.w, 0.0, 1.0);\n mat.coatColor = max(coat.rgb, vec3(0.0));\n mat.coatWeight = clamp(coat.w, 0.0, 1.0);\n mat.coatRoughness = clamp(coatControls.x, ROUGHNESS_MIN, 1.0);\n mat.coatAnisotropy = clamp(coatControls.y, 0.0, 1.0);\n mat.coatIor = max(coatControls.z, 1.0);\n mat.coatDarkening = clamp(coatControls.w, 0.0, 1.0);\n\n#ifdef HAS_MEDIUM\n mat.mediumExtinction = max(fetchMatData(i + MAT_ROW_MEDIUM_EXTINCTION).rgb, vec3(0.0));\n mat.mediumAnisotropy = clamp(fetchMatData(i + MAT_ROW_MEDIUM_EXTINCTION).a, -1.0, 1.0);\n mat.mediumScattering = max(fetchMatData(i + MAT_ROW_MEDIUM_SCATTERING).rgb, vec3(0.0));\n mat.mediumType = max(max(mat.mediumExtinction.x, mat.mediumExtinction.y), mat.mediumExtinction.z) > 0.0 ? 1 : 0;\n#endif\n\n\n#ifdef HAS_ALPHA\n mat.alpha = alphaAndThinFilm.r;\n#else\n mat.alpha = 1.0;\n#endif\n\n #ifdef NUM_DIFFUSE_MAPS\n int diffuseMapIndex = int(metallicAndMapIndex.z);\n if (diffuseMapIndex >= 0) {\n vec4 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 mat.baseColor *= decodeMapColor(diffuseMapIndex, diffuse.rgb);\n\n // Map alpha to transmission\n if (mapAlphaUsage == ${mapAlphaUsageConstants.transmission + ''}) {\n mat.transmissionWeight = 1.0 - diffuse.a;\n }\n else if (mapAlphaUsage == ${mapAlphaUsageConstants.alpha + ''}) {\n mat.alpha *= diffuse.a;\n }\n }\n #endif\n\n ${simpleTextureSample('alphaMap', 'glsl')}\n\n mat.alpha = resolveMaterialAlpha(\n mat.alpha, int(fetchMatData(i + MAT_ROW_ALPHA).w), standaloneMetalRoughMaps.w\n );\n\n ${simpleTextureSample('transmissionMap', 'glsl')}\n\n #ifdef NUM_METALLIC_ROUGHNESS_MAPS\n int metallicRoughnessMapIndex = int(metallicAndMapIndex.w);\n if (metallicRoughnessMapIndex >= 0) {\n vec4 metallicRoughness = sampleMap(\n metallicRoughnessMapIndex,\n getMapUvSet(metallicRoughnessMapIndex, uv, uv1)\n );\n mat.baseMetalness *= metallicRoughness.b;\n mat.specularRoughness *= metallicRoughness.g;\n }\n #endif\n\n ${simpleTextureSample('roughnessMap', 'glsl')}\n\n ${simpleTextureSample('metalnessMap', 'glsl')}\n\n #ifdef NUM_EMISSIVE_MAPS\n int emissiveMapIndex = int(emissionAndEmissiveMapIndex.w);\n if (emissiveMapIndex >= 0) {\n vec3 emissive = sampleMap(\n emissiveMapIndex, getMapUvSet(emissiveMapIndex, uv, uv1)\n ).rgb;\n mat.emission *= decodeMapColor(emissiveMapIndex, emissive);\n }\n #endif\n\n #ifdef NUM_COAT_WEIGHT_MAPS\n int emissionCoatMapIndex = int(fetchMatData(i + MAT_ROW_LAYER_MAPS).x);\n if (emissionCoatMapIndex >= 0 && mat.materialType == 0) {\n float emissionCoatWeight = clamp(coat.w, 0.0, 1.0) * sampleMap(\n emissionCoatMapIndex, getMapUvSet(emissionCoatMapIndex, uv, uv1)\n ).r;\n mat.emission *= mix(vec3(1.0), sqrt(max(coat.rgb, vec3(0.0))), emissionCoatWeight);\n }\n #endif\n\n ${thinFilmTextureSample('glsl')}\n\n ${simpleTextureSample('coatWeightMap', 'glsl')}\n#ifdef USE_COAT_NORMAL_FRAMES\n // Independent coat shading also applies when the coat has no normal map.\n mat.coatNormalEnabled = mat.coatWeight > 0.0 && (roughnessAndNormal.y >= 0.0 || fetchMatData(i + MAT_ROW_LAYER_MAPS).z >= 0.0);\n#endif\n\n ${simpleTextureSample('coatRoughnessMap', 'glsl')}\n\n ${simpleTextureSample('fuzzColorMap', 'glsl')}\n\n ${simpleTextureSample('fuzzRoughnessMap', 'glsl')}\n\n ${simpleTextureSample('specularWeightMap', 'glsl')}\n\n ${simpleTextureSample('specularColorMap', 'glsl')}\n\n vec4 directionInfo = fetchMatData(i + MAT_ROW_DIRECTION_NORMAL);\n mat.anisotropyDirection = vec2(1.0, 0.0);\n mat.anisotropyDirectionEnabled = directionInfo.y != 0.0;\n mat.coatAnisotropyRotation = fetchMatData(i + MAT_ROW_FILM_TEXTURE).x;\n#ifdef NUM_ANISOTROPY_MAPS\n if (directionInfo.x >= 0.0) {\n int index = int(directionInfo.x);\n vec4 texel = sampleMap(index, getMapUvSet(index, uv, uv1));\n mat.specularAnisotropy *= texel.b;\n vec2 direction = texel.rg * 2.0 - 1.0;\n if (dot(direction, direction) > 1e-4) mat.anisotropyDirection = normalize(direction);\n mat.anisotropyDirectionEnabled = true;\n }\n#endif\n#ifdef HAS_GLTF_ANISOTROPY\n if (fetchMatData(i + MAT_ROW_FILM_TEXTURE).y > 0.5 && mat.specularAnisotropy > 0.0) {\n vec2 native = gltf_anisotropy_to_openpbr(clamp(mat.specularRoughness, 0.0, 1.0), mat.specularAnisotropy);\n mat.specularRoughness = native.x;\n mat.specularAnisotropy = native.y;\n }\n#endif\n if (mat.anisotropyDirectionEnabled) {\n float theta = directionInfo.y;\n vec2 d = mat.anisotropyDirection;\n mat.anisotropyDirection = vec2(cos(theta)*d.x - sin(theta)*d.y, sin(theta)*d.x + cos(theta)*d.y);\n }\n\n // OpenPBR 1.1.1: coat refraction broadens all base microfacet lobes.\n // Keep the zero-coat / smooth-coat paths byte-identical.\n if (mat.coatWeight > 0.0 && mat.coatRoughness > 0.0) {\n float baseRoughness2 = mat.specularRoughness * mat.specularRoughness;\n float coatRoughness2 = mat.coatRoughness * mat.coatRoughness;\n mat.specularRoughness = mix(mat.specularRoughness,\n pow(min(1.0, baseRoughness2 * baseRoughness2 + 2.0 * coatRoughness2 * coatRoughness2), 0.25), mat.coatWeight);\n }\n vec3 color = getInstanceColor(instanceIndex) * vertexColor;\n mat.baseColor *= color;\n if (mat.materialType == UNLIT) mat.emission *= color;\n\n${fragments['material0'] ?? ''} mat.specularRoughness = clamp(mat.specularRoughness, ROUGHNESS_MIN, 1.0);\n mat.baseMetalness = clamp(mat.baseMetalness, 0.0, 1.0);\n vec2 specularAlpha = openpbr_roughness_to_alpha(mat.specularRoughness, mat.specularAnisotropy);\n mat.alphaX = specularAlpha.x;\n mat.alphaY = specularAlpha.y;\n}\n\n#if defined(NUM_NORMAL_MAPS)\nvec3 getMatNormal(int materialIndex, vec2 uv, vec3 normal, vec3 dp1, vec3 dp2, vec2 duv1, vec2 duv2) {\n int i = materialIndex * MAT_DATA_SIZE;\n vec4 roughnessAndNormal = fetchMatData(i + MAT_ROW_ROUGHNESS_NORMAL);\n int normalMapIndex = int(roughnessAndNormal.y);\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 vec3 dp2perp = cross(dp2, normal);\n vec3 dp1perp = cross(normal, dp1);\n vec3 dpdu = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 dpdv = dp2perp * duv1.y + dp1perp * duv2.y;\n float gradientLengthSquared = max(dot(dpdu, dpdu), dot(dpdv, dpdv));\n if (gradientLengthSquared > 1e-12) {\n float invmax = inversesqrt(gradientLengthSquared);\n dpdu *= invmax;\n dpdv *= invmax;\n }\n else {\n // Imported meshes can legitimately omit UVs and use generated or\n // triplanar projection. Their zero UV derivatives must not turn the TBN\n // basis (and then every lighting result) into NaN.\n vec3 referenceAxis = abs(normal.z) < 0.999\n ? vec3(0.0, 0.0, 1.0)\n : vec3(0.0, 1.0, 0.0);\n dpdu = normalize(cross(referenceAxis, normal));\n dpdv = cross(normal, dpdu);\n }\n\n vec3 n = 2.0 * sampleMap(normalMapIndex, uv).rgb - 1.0;\n n.xy *= roughnessAndNormal.zw;\n n = normalize(n);\n\n mat3 tbn = mat3(dpdu, dpdv, normal);\n\n return normalize(tbn * n);\n } else {\n return normal;\n }\n}\n#endif\n\n`\n});\n}\nexport default createMaterialBufferGlsl();\n"]}
|