@meimu/mutracer 0.1.3 → 0.1.5
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/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +4155 -4052
- package/docs/api.md +13 -10
- package/docs/materials.md +17 -26
- package/docs/threejs.md +35 -9
- package/docs/viewer.md +36 -3
- package/lib/Engine.js +18 -1
- package/lib/Engine.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/MaterialTable.d.ts +1 -0
- package/lib/renderer/MaterialTable.js +10 -4
- package/lib/renderer/MaterialTable.js.map +1 -1
- package/lib/renderer/WGPUBloomPass.js +18 -18
- package/lib/renderer/WGPUFullQuadPass.js +6 -6
- package/lib/renderer/WGPUJNLMDenoiser.js +69 -69
- package/lib/renderer/WGPURayTraceOutput.js +14 -14
- package/lib/renderer/WGPURayTracePass.d.ts +2 -0
- package/lib/renderer/WGPURayTracePass.js +17 -9
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.js +15 -15
- package/lib/renderer/WebGLJNLMDenoiser.js +69 -69
- package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
- package/lib/renderer/WebGLRayTracePass.d.ts +1 -0
- package/lib/renderer/WebGLRayTracePass.js +8 -1
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/envMapCreation.d.ts +5 -1
- package/lib/renderer/envMapCreation.js +42 -5
- package/lib/renderer/envMapCreation.js.map +1 -1
- package/lib/renderer/geometryUpdates.js +1 -1
- package/lib/renderer/geometryUpdates.js.map +1 -1
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +12 -12
- package/lib/renderer/glsl/chunks/envMap.glsl.js +66 -54
- package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/intersect.glsl.js +323 -315
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +154 -121
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +434 -434
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +42 -41
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +69 -69
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +84 -84
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +12 -12
- package/lib/renderer/glsl/chunks/sampling.glsl.js +75 -75
- package/lib/renderer/glsl/chunks/sobol.glsl.js +61 -61
- 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 +5 -5
- package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +8 -8
- package/lib/renderer/glsl/rayTrace.frag.js +133 -133
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +9 -9
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +52 -52
- package/lib/renderer/lightsUtil.js +6 -4
- package/lib/renderer/lightsUtil.js.map +1 -1
- package/lib/renderer/materialChanges.js +1 -1
- package/lib/renderer/materialChanges.js.map +1 -1
- package/lib/renderer/materialComparison.generated.js +36 -18
- package/lib/renderer/materialComparison.generated.js.map +1 -1
- package/lib/renderer/prepareMeshBVH.js +2 -2
- package/lib/renderer/prepareMeshBVH.js.map +1 -1
- package/lib/renderer/sceneChangeDetector.js +4 -1
- package/lib/renderer/sceneChangeDetector.js.map +1 -1
- package/lib/renderer/sceneLightChanges.js +3 -2
- package/lib/renderer/sceneLightChanges.js.map +1 -1
- package/lib/renderer/scratchSampling.js +18 -18
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +39 -31
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +476 -470
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +8 -8
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +95 -60
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +469 -469
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +117 -120
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +25 -22
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +127 -127
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +136 -136
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +6 -6
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +73 -73
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +62 -62
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
- package/lib/renderer/wgsl/compose.frag.wgsl.js +105 -105
- 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 +5 -5
- package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +28 -28
- package/lib/renderer/wgsl/rayTrace.compute.js +251 -248
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/EnvironmentLight.d.ts +9 -3
- package/lib/scene/EnvironmentLight.js +9 -2
- package/lib/scene/EnvironmentLight.js.map +1 -1
- package/lib/scene/OpenPBRMaterial.d.ts +1 -1
- package/lib/scene/OpenPBRMaterial.js +1 -1
- package/lib/scene/OpenPBRMaterial.js.map +1 -1
- package/lib/scene/Scene.d.ts +4 -0
- package/lib/scene/Scene.js.map +1 -1
- package/lib/scene/SpotLight.d.ts +2 -2
- package/lib/scene/SpotLight.js +1 -1
- package/lib/scene/SpotLight.js.map +1 -1
- package/lib/scene/Texture.d.ts +17 -6
- package/lib/scene/Texture.js +13 -4
- package/lib/scene/Texture.js.map +1 -1
- package/lib/util/fromTHREE.js +151 -29
- 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 +1 -1
|
@@ -15,6 +15,7 @@ export default createShaderMixin({
|
|
|
15
15
|
mapTransform: Shader.arrayUniform('vec4', 'NUM_MAPS'),
|
|
16
16
|
mapUvChannel: Shader.arrayUniform('float', 'NUM_MAPS'),
|
|
17
17
|
mapColorLinear: Shader.arrayUniform('float', 'NUM_MAPS'),
|
|
18
|
+
mapWrap: Shader.arrayUniform('vec2', 'NUM_MAPS'),
|
|
18
19
|
map: Shader.uniform('sampler2DArray')
|
|
19
20
|
},
|
|
20
21
|
defines: {
|
|
@@ -23,7 +24,7 @@ export default createShaderMixin({
|
|
|
23
24
|
main: glsl `
|
|
24
25
|
${materialRowsGlsl()}
|
|
25
26
|
#ifdef HAS_GLTF_ANISOTROPY
|
|
26
|
-
vec2
|
|
27
|
+
vec2 fe(float roughness, float strength) {
|
|
27
28
|
if (strength == 0.0) { return vec2(roughness, 0.0); }
|
|
28
29
|
float u = roughness * roughness;
|
|
29
30
|
float a = u + (1.0 - u) * strength * strength;
|
|
@@ -33,15 +34,15 @@ return vec2(pow((a*a + u*u) * 0.5, 0.25), clamp(1.0 - u/a, 0.0, 1.0));
|
|
|
33
34
|
|
|
34
35
|
#endif
|
|
35
36
|
|
|
36
|
-
vec3
|
|
37
|
+
vec3 oJ(vec3 c) {
|
|
37
38
|
return mix(pow(c * 0.9478672986 + 0.0521327014, vec3(2.4)), c * 0.0773993808, vec3(lessThan(c, vec3(0.04045))));
|
|
38
39
|
}
|
|
39
40
|
vec4 fetchMatData(int i) {
|
|
40
|
-
return
|
|
41
|
+
return kG(materialBuffer, i, materialBufferColumns);
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
|
|
44
|
-
float
|
|
45
|
+
float lr(float alpha, int alphaMode, float alphaCutoff) {
|
|
45
46
|
if (alphaMode == ${materialAlphaModeConstants.opaque}) {
|
|
46
47
|
return 1.0;
|
|
47
48
|
}
|
|
@@ -51,7 +52,7 @@ return alpha >= alphaCutoff ? 1.0 : 0.0;
|
|
|
51
52
|
return alpha;
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
float
|
|
55
|
+
float wb(int idx) {
|
|
55
56
|
return fetchMatData(idx * MAT_DATA_SIZE + MAT_ROW_COLOR).w;
|
|
56
57
|
}
|
|
57
58
|
|
|
@@ -62,33 +63,44 @@ return vec2(float(val >> 8), float(val & 0xff) / 255.0);
|
|
|
62
63
|
#ifdef NUM_MAPS
|
|
63
64
|
vec3 decodeMapColor(int index, vec3 c) {
|
|
64
65
|
if (mapColorLinear[index] > 0.5) { return c; }
|
|
65
|
-
return
|
|
66
|
+
return oJ(c);
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
vec2
|
|
69
|
+
vec2 kJ(int index) {
|
|
69
70
|
return mapInfo[index].xy;
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
float
|
|
73
|
+
float lk(int index) {
|
|
73
74
|
return floor(mapInfo[index].z);
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
vec2
|
|
77
|
+
vec2 jP(int index) {
|
|
77
78
|
return vec2(fract(mapInfo[index].z), mapInfo[index].w);
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
|
|
81
|
+
float fT(float value, float mode) {
|
|
82
|
+
if (mode < 0.5) return fract(value);
|
|
83
|
+
if (mode < 1.5) return clamp(value, 0.0, 1.0);
|
|
84
|
+
return 1.0 - abs(1.0 - (value - 2.0 * floor(value * 0.5)));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
vec2 kv(int index, vec2 uv) {
|
|
81
88
|
vec4 transform = mapTransform[index];
|
|
82
|
-
vec2
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
vec2
|
|
87
|
-
vec2
|
|
89
|
+
vec2 value = uv * transform.xy + transform.zw;
|
|
90
|
+
return vec2(fT(value.x, mapWrap[index].x), fT(value.y, mapWrap[index].y));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
vec2 sq(int index, vec2 uv) {
|
|
94
|
+
vec2 qH = kv(index, uv);
|
|
95
|
+
vec2 jk = 1.0 / vec2(textureSize(map, 0).xy);
|
|
96
|
+
vec2 dZ = jP(index);
|
|
97
|
+
vec2 kn = kJ(index) + jk;
|
|
98
|
+
vec2 oM = dZ - 0.5 * jk;
|
|
99
|
+
vec2 lD = dZ + kn - jk;
|
|
88
100
|
return clamp(
|
|
89
|
-
|
|
101
|
+
oM + qH * kn,
|
|
90
102
|
dZ,
|
|
91
|
-
|
|
103
|
+
lD
|
|
92
104
|
);
|
|
93
105
|
}
|
|
94
106
|
|
|
@@ -96,91 +108,111 @@ vec2 getMapUvSet(int index, vec2 uv, vec2 uv1) {
|
|
|
96
108
|
return mapUvChannel[index] > 0.5 ? uv1 : uv;
|
|
97
109
|
}
|
|
98
110
|
|
|
111
|
+
vec4 eU(int index, ivec2 jm, ivec2 size, ivec2 origin, vec2 iK) {
|
|
112
|
+
ivec2 p = clamp(jm, ivec2(0), size - 1);
|
|
113
|
+
if (iK.x < 0.5) p.x = ((jm.x % size.x) + size.x) % size.x;
|
|
114
|
+
if (iK.y < 0.5) p.y = ((jm.y % size.y) + size.y) % size.y;
|
|
115
|
+
return texelFetch(map, ivec3(origin + p, int(lk(index))), 0);
|
|
116
|
+
}
|
|
117
|
+
|
|
99
118
|
vec4 sampleMap(int index, vec2 uv) {
|
|
100
|
-
|
|
119
|
+
ivec2 size = ivec2(round(kJ(index) * vec2(textureSize(map, 0).xy) + 1.0));
|
|
120
|
+
vec2 eA = kv(index, uv) * vec2(size) - 0.5;
|
|
121
|
+
vec2 iK = mapWrap[index];
|
|
122
|
+
if ((size.x > 1 && iK.x < 0.5 && (eA.x < 0.0 || eA.x > float(size.x - 1))) ||
|
|
123
|
+
(size.y > 1 && iK.y < 0.5 && (eA.y < 0.0 || eA.y > float(size.y - 1)))) {
|
|
124
|
+
ivec2 base = ivec2(floor(eA));
|
|
125
|
+
vec2 weight = fract(eA);
|
|
126
|
+
ivec2 origin = ivec2(round(jP(index) * vec2(textureSize(map, 0).xy) - 0.5));
|
|
127
|
+
return mix(
|
|
128
|
+
mix(eU(index, base, size, origin, iK), eU(index, base + ivec2(1, 0), size, origin, iK), weight.x),
|
|
129
|
+
mix(eU(index, base + ivec2(0, 1), size, origin, iK), eU(index, base + ivec2(1, 1), size, origin, iK), weight.x), weight.y);
|
|
130
|
+
}
|
|
131
|
+
return texture(map, vec3(sq(index, uv), lk(index)));
|
|
101
132
|
}
|
|
102
133
|
#endif
|
|
103
134
|
|
|
104
135
|
|
|
105
136
|
vec2 aK(float roughness, float anisotropy) {
|
|
106
137
|
float alpha = roughness * roughness;
|
|
107
|
-
float
|
|
108
|
-
if (anisotropy == 0.0) { return vec2(max(
|
|
109
|
-
float
|
|
110
|
-
float
|
|
111
|
-
return max(vec2(
|
|
138
|
+
float pg = ROUGHNESS_MIN * ROUGHNESS_MIN;
|
|
139
|
+
if (anisotropy == 0.0) { return vec2(max(pg, alpha)); }
|
|
140
|
+
float di = 1.0 - anisotropy;
|
|
141
|
+
float sh = alpha * sqrt(2.0 / (1.0 + di * di));
|
|
142
|
+
return max(vec2(pg), vec2(sh, di * sh));
|
|
112
143
|
}
|
|
113
144
|
|
|
114
145
|
vec4 bv(int i);
|
|
115
|
-
vec3
|
|
146
|
+
vec3 kI(int instanceIndex) {
|
|
116
147
|
if (instanceIndex < 0) return vec3(1.0);
|
|
117
148
|
return bv(instanceIndex * ${INSTANCE_VEC4_STRIDE + ''} + 9).rgb;
|
|
118
149
|
}
|
|
119
150
|
|
|
120
|
-
void
|
|
151
|
+
void eX(
|
|
121
152
|
inout J mat,
|
|
122
153
|
int materialIndex,
|
|
123
154
|
vec2 uv,
|
|
124
155
|
vec2 uv1,
|
|
125
|
-
int instanceIndex
|
|
156
|
+
int instanceIndex,
|
|
157
|
+
vec3 vertexColor
|
|
126
158
|
) {
|
|
127
159
|
int i = materialIndex * MAT_DATA_SIZE;
|
|
128
|
-
vec4
|
|
129
|
-
vec4
|
|
130
|
-
vec4
|
|
131
|
-
vec4
|
|
132
|
-
vec4
|
|
160
|
+
vec4 oV = fetchMatData(i + MAT_ROW_COLOR);
|
|
161
|
+
vec4 fo = fetchMatData(i + MAT_ROW_ROUGHNESS_NORMAL);
|
|
162
|
+
vec4 gp = fetchMatData(i + MAT_ROW_METALLIC_MAPS);
|
|
163
|
+
vec4 hI = fetchMatData(i + MAT_ROW_EMISSION);
|
|
164
|
+
vec4 gZ = fetchMatData(i + MAT_ROW_IOR_TRANSMISSION);
|
|
133
165
|
vec4 misc = fetchMatData(i + MAT_ROW_MISC);
|
|
134
|
-
vec4
|
|
135
|
-
vec4
|
|
136
|
-
vec4
|
|
166
|
+
vec4 nB = fetchMatData(i + MAT_ROW_ALPHA_FILM);
|
|
167
|
+
vec4 lR = fetchMatData(i + MAT_ROW_BASE_CONTROLS);
|
|
168
|
+
vec4 oZ = fetchMatData(i + MAT_ROW_SPECULAR_FUZZ);
|
|
137
169
|
vec4 subsurface = fetchMatData(i + MAT_ROW_SUBSURFACE);
|
|
138
|
-
vec4
|
|
139
|
-
vec4
|
|
140
|
-
vec4
|
|
141
|
-
vec4
|
|
142
|
-
vec4
|
|
170
|
+
vec4 wq = fetchMatData(i + MAT_ROW_FUZZ);
|
|
171
|
+
vec4 vL = fetchMatData(i + MAT_ROW_COAT);
|
|
172
|
+
vec4 lS = fetchMatData(i + MAT_ROW_COAT_CONTROLS);
|
|
173
|
+
vec4 mX = fetchMatData(i + MAT_ROW_FILM_DISPERSION);
|
|
174
|
+
vec4 nA = fetchMatData(i + MAT_ROW_STANDALONE_MAPS);
|
|
143
175
|
int mapAlphaUsage = int(misc.a);
|
|
144
176
|
|
|
145
|
-
mat.baseColor =
|
|
146
|
-
mat.materialType = int(
|
|
147
|
-
mat.specularRoughness =
|
|
148
|
-
mat.baseMetalness =
|
|
149
|
-
mat.specularAnisotropy = clamp(
|
|
150
|
-
mat.emission =
|
|
177
|
+
mat.baseColor = oV.rgb;
|
|
178
|
+
mat.materialType = int(oV.w);
|
|
179
|
+
mat.specularRoughness = fo.x;
|
|
180
|
+
mat.baseMetalness = gp.x;
|
|
181
|
+
mat.specularAnisotropy = clamp(gp.y, 0.0, 1.0);
|
|
182
|
+
mat.emission = hI.rgb;
|
|
151
183
|
mat.inside = false;
|
|
152
|
-
mat.specularIor =
|
|
153
|
-
mat.transmissionWeight =
|
|
184
|
+
mat.specularIor = gZ.x;
|
|
185
|
+
mat.transmissionWeight = gZ.y;
|
|
154
186
|
#ifdef HAS_MEDIUM
|
|
155
|
-
mat.mediumType = int(
|
|
187
|
+
mat.mediumType = int(gZ.z);
|
|
156
188
|
#else
|
|
157
189
|
mat.mediumType = 0;
|
|
158
190
|
#endif
|
|
159
|
-
mat.thinWalled =
|
|
191
|
+
mat.thinWalled = gZ.w > 0.5;
|
|
160
192
|
mat.bevel = misc.r;
|
|
161
193
|
mat.transmissionDispersionScale = misc.g;
|
|
162
|
-
mat.dispersionAbbeNumber = max(
|
|
194
|
+
mat.dispersionAbbeNumber = max(mX.y, 1e-6);
|
|
163
195
|
mat.thinFilmThickness = misc.b;
|
|
164
|
-
mat.thinFilmIor =
|
|
165
|
-
mat.thinFilmWeight = clamp(
|
|
196
|
+
mat.thinFilmIor = nB.b;
|
|
197
|
+
mat.thinFilmWeight = clamp(mX.x, 0.0, 1.0);
|
|
166
198
|
|
|
167
199
|
mat.thinFilmThickness *= 1000.0;
|
|
168
|
-
mat.baseWeight = clamp(
|
|
169
|
-
mat.diffuseRoughness = clamp(
|
|
170
|
-
mat.specularWeight = max(0.0,
|
|
171
|
-
mat.subsurfaceWeight = clamp(
|
|
172
|
-
mat.specularColor = max(
|
|
173
|
-
mat.fuzzWeight = clamp(
|
|
200
|
+
mat.baseWeight = clamp(lR.x, 0.0, 1.0);
|
|
201
|
+
mat.diffuseRoughness = clamp(lR.y, 0.0, 1.0);
|
|
202
|
+
mat.specularWeight = max(0.0, lR.z);
|
|
203
|
+
mat.subsurfaceWeight = clamp(lR.w, 0.0, 1.0);
|
|
204
|
+
mat.specularColor = max(oZ.rgb, vec3(0.0));
|
|
205
|
+
mat.fuzzWeight = clamp(oZ.w, 0.0, 1.0);
|
|
174
206
|
mat.subsurfaceColor = max(subsurface.rgb, vec3(0.0));
|
|
175
207
|
mat.transmissionColor = max(fetchMatData(i + MAT_ROW_TRANSMISSION_COLOR).rgb, vec3(0.0));
|
|
176
|
-
mat.fuzzColor = max(
|
|
177
|
-
mat.fuzzRoughness = clamp(
|
|
178
|
-
mat.coatColor = max(
|
|
179
|
-
mat.coatWeight = clamp(
|
|
180
|
-
mat.coatRoughness = clamp(
|
|
181
|
-
mat.coatAnisotropy = clamp(
|
|
182
|
-
mat.coatIor = max(
|
|
183
|
-
mat.coatDarkening = clamp(
|
|
208
|
+
mat.fuzzColor = max(wq.rgb, vec3(0.0));
|
|
209
|
+
mat.fuzzRoughness = clamp(wq.w, 0.0, 1.0);
|
|
210
|
+
mat.coatColor = max(vL.rgb, vec3(0.0));
|
|
211
|
+
mat.coatWeight = clamp(vL.w, 0.0, 1.0);
|
|
212
|
+
mat.coatRoughness = clamp(lS.x, ROUGHNESS_MIN, 1.0);
|
|
213
|
+
mat.coatAnisotropy = clamp(lS.y, 0.0, 1.0);
|
|
214
|
+
mat.coatIor = max(lS.z, 1.0);
|
|
215
|
+
mat.coatDarkening = clamp(lS.w, 0.0, 1.0);
|
|
184
216
|
|
|
185
217
|
#ifdef HAS_MEDIUM
|
|
186
218
|
mat.mediumExtinction = max(fetchMatData(i + MAT_ROW_MEDIUM_EXTINCTION).rgb, vec3(0.0));
|
|
@@ -191,48 +223,48 @@ mat.mediumType = max(max(mat.mediumExtinction.x, mat.mediumExtinction.y), mat.me
|
|
|
191
223
|
|
|
192
224
|
|
|
193
225
|
#ifdef HAS_ALPHA
|
|
194
|
-
mat.alpha =
|
|
226
|
+
mat.alpha = nB.r;
|
|
195
227
|
#else
|
|
196
228
|
mat.alpha = 1.0;
|
|
197
229
|
#endif
|
|
198
230
|
|
|
199
231
|
#ifdef NUM_DIFFUSE_MAPS
|
|
200
|
-
int diffuseMapIndex = int(
|
|
232
|
+
int diffuseMapIndex = int(gp.z);
|
|
201
233
|
if (diffuseMapIndex >= 0) {
|
|
202
|
-
vec4
|
|
234
|
+
vec4 oa = sampleMap(
|
|
203
235
|
diffuseMapIndex, getMapUvSet(diffuseMapIndex, uv, uv1)
|
|
204
236
|
);
|
|
205
237
|
|
|
206
238
|
|
|
207
|
-
mat.baseColor *= decodeMapColor(diffuseMapIndex,
|
|
239
|
+
mat.baseColor *= decodeMapColor(diffuseMapIndex, oa.rgb);
|
|
208
240
|
|
|
209
241
|
|
|
210
242
|
if (mapAlphaUsage == ${mapAlphaUsageConstants.transmission + ''}) {
|
|
211
|
-
mat.transmissionWeight = 1.0 -
|
|
243
|
+
mat.transmissionWeight = 1.0 - oa.a;
|
|
212
244
|
}
|
|
213
245
|
else if (mapAlphaUsage == ${mapAlphaUsageConstants.alpha + ''}) {
|
|
214
|
-
mat.alpha *=
|
|
246
|
+
mat.alpha *= oa.a;
|
|
215
247
|
}
|
|
216
248
|
}
|
|
217
249
|
#endif
|
|
218
250
|
|
|
219
251
|
${simpleTextureSample('alphaMap', 'glsl')}
|
|
220
252
|
|
|
221
|
-
mat.alpha =
|
|
222
|
-
mat.alpha, int(fetchMatData(i + MAT_ROW_ALPHA).w),
|
|
253
|
+
mat.alpha = lr(
|
|
254
|
+
mat.alpha, int(fetchMatData(i + MAT_ROW_ALPHA).w), nA.w
|
|
223
255
|
);
|
|
224
256
|
|
|
225
257
|
${simpleTextureSample('transmissionMap', 'glsl')}
|
|
226
258
|
|
|
227
259
|
#ifdef NUM_METALLIC_ROUGHNESS_MAPS
|
|
228
|
-
int metallicRoughnessMapIndex = int(
|
|
260
|
+
int metallicRoughnessMapIndex = int(gp.w);
|
|
229
261
|
if (metallicRoughnessMapIndex >= 0) {
|
|
230
|
-
vec4
|
|
262
|
+
vec4 fO = sampleMap(
|
|
231
263
|
metallicRoughnessMapIndex,
|
|
232
264
|
getMapUvSet(metallicRoughnessMapIndex, uv, uv1)
|
|
233
265
|
);
|
|
234
|
-
mat.baseMetalness *=
|
|
235
|
-
mat.specularRoughness *=
|
|
266
|
+
mat.baseMetalness *= fO.b;
|
|
267
|
+
mat.specularRoughness *= fO.g;
|
|
236
268
|
}
|
|
237
269
|
#endif
|
|
238
270
|
|
|
@@ -241,7 +273,7 @@ ${simpleTextureSample('roughnessMap', 'glsl')}
|
|
|
241
273
|
${simpleTextureSample('metalnessMap', 'glsl')}
|
|
242
274
|
|
|
243
275
|
#ifdef NUM_EMISSIVE_MAPS
|
|
244
|
-
int emissiveMapIndex = int(
|
|
276
|
+
int emissiveMapIndex = int(hI.w);
|
|
245
277
|
if (emissiveMapIndex >= 0) {
|
|
246
278
|
vec3 emissive = sampleMap(
|
|
247
279
|
emissiveMapIndex, getMapUvSet(emissiveMapIndex, uv, uv1)
|
|
@@ -251,20 +283,21 @@ mat.emission *= decodeMapColor(emissiveMapIndex, emissive);
|
|
|
251
283
|
#endif
|
|
252
284
|
|
|
253
285
|
#ifdef NUM_COAT_WEIGHT_MAPS
|
|
254
|
-
int
|
|
255
|
-
if (
|
|
256
|
-
float
|
|
257
|
-
|
|
286
|
+
int hQ = int(fetchMatData(i + MAT_ROW_LAYER_MAPS).x);
|
|
287
|
+
if (hQ >= 0 && mat.materialType == 0) {
|
|
288
|
+
float qw = clamp(vL.w, 0.0, 1.0) * sampleMap(
|
|
289
|
+
hQ, getMapUvSet(hQ, uv, uv1)
|
|
258
290
|
).r;
|
|
259
|
-
mat.emission *= mix(vec3(1.0), sqrt(max(
|
|
291
|
+
mat.emission *= mix(vec3(1.0), sqrt(max(vL.rgb, vec3(0.0))), qw);
|
|
260
292
|
}
|
|
261
293
|
#endif
|
|
262
294
|
|
|
263
295
|
${thinFilmTextureSample('glsl')}
|
|
264
296
|
|
|
265
297
|
${simpleTextureSample('coatWeightMap', 'glsl')}
|
|
266
|
-
#ifdef
|
|
267
|
-
|
|
298
|
+
#ifdef USE_COAT_NORMAL_FRAMES
|
|
299
|
+
|
|
300
|
+
mat.coatNormalEnabled = mat.coatWeight > 0.0 && (fo.y >= 0.0 || fetchMatData(i + MAT_ROW_LAYER_MAPS).z >= 0.0);
|
|
268
301
|
#endif
|
|
269
302
|
|
|
270
303
|
${simpleTextureSample('coatRoughnessMap', 'glsl')}
|
|
@@ -277,29 +310,29 @@ ${simpleTextureSample('specularWeightMap', 'glsl')}
|
|
|
277
310
|
|
|
278
311
|
${simpleTextureSample('specularColorMap', 'glsl')}
|
|
279
312
|
|
|
280
|
-
vec4
|
|
313
|
+
vec4 kW = fetchMatData(i + MAT_ROW_DIRECTION_NORMAL);
|
|
281
314
|
mat.anisotropyDirection = vec2(1.0, 0.0);
|
|
282
|
-
mat.anisotropyDirectionEnabled =
|
|
315
|
+
mat.anisotropyDirectionEnabled = kW.y != 0.0;
|
|
283
316
|
mat.coatAnisotropyRotation = fetchMatData(i + MAT_ROW_FILM_TEXTURE).x;
|
|
284
317
|
#ifdef NUM_ANISOTROPY_MAPS
|
|
285
|
-
if (
|
|
286
|
-
int index = int(
|
|
287
|
-
vec4
|
|
288
|
-
mat.specularAnisotropy *=
|
|
289
|
-
vec2 direction =
|
|
318
|
+
if (kW.x >= 0.0) {
|
|
319
|
+
int index = int(kW.x);
|
|
320
|
+
vec4 eA = sampleMap(index, getMapUvSet(index, uv, uv1));
|
|
321
|
+
mat.specularAnisotropy *= eA.b;
|
|
322
|
+
vec2 direction = eA.rg * 2.0 - 1.0;
|
|
290
323
|
if (dot(direction, direction) > 1e-4) mat.anisotropyDirection = normalize(direction);
|
|
291
324
|
mat.anisotropyDirectionEnabled = true;
|
|
292
325
|
}
|
|
293
326
|
#endif
|
|
294
327
|
#ifdef HAS_GLTF_ANISOTROPY
|
|
295
328
|
if (fetchMatData(i + MAT_ROW_FILM_TEXTURE).y > 0.5 && mat.specularAnisotropy > 0.0) {
|
|
296
|
-
vec2
|
|
297
|
-
mat.specularRoughness =
|
|
298
|
-
mat.specularAnisotropy =
|
|
329
|
+
vec2 sF = fe(clamp(mat.specularRoughness, 0.0, 1.0), mat.specularAnisotropy);
|
|
330
|
+
mat.specularRoughness = sF.x;
|
|
331
|
+
mat.specularAnisotropy = sF.y;
|
|
299
332
|
}
|
|
300
333
|
#endif
|
|
301
334
|
if (mat.anisotropyDirectionEnabled) {
|
|
302
|
-
float theta =
|
|
335
|
+
float theta = kW.y;
|
|
303
336
|
vec2 d = mat.anisotropyDirection;
|
|
304
337
|
mat.anisotropyDirection = vec2(cos(theta)*d.x - sin(theta)*d.y, sin(theta)*d.x + cos(theta)*d.y);
|
|
305
338
|
}
|
|
@@ -307,14 +340,14 @@ mat.anisotropyDirection = vec2(cos(theta)*d.x - sin(theta)*d.y, sin(theta)*d.x +
|
|
|
307
340
|
|
|
308
341
|
|
|
309
342
|
if (mat.coatWeight > 0.0 && mat.coatRoughness > 0.0) {
|
|
310
|
-
float
|
|
311
|
-
float
|
|
343
|
+
float hM = mat.specularRoughness * mat.specularRoughness;
|
|
344
|
+
float hN = mat.coatRoughness * mat.coatRoughness;
|
|
312
345
|
mat.specularRoughness = mix(mat.specularRoughness,
|
|
313
|
-
pow(min(1.0,
|
|
346
|
+
pow(min(1.0, hM * hM + 2.0 * hN * hN), 0.25), mat.coatWeight);
|
|
314
347
|
}
|
|
315
|
-
vec3
|
|
316
|
-
mat.baseColor *=
|
|
317
|
-
if (mat.materialType == UNLIT) mat.emission *=
|
|
348
|
+
vec3 color = kI(instanceIndex) * vertexColor;
|
|
349
|
+
mat.baseColor *= color;
|
|
350
|
+
if (mat.materialType == UNLIT) mat.emission *= color;
|
|
318
351
|
|
|
319
352
|
mat.specularRoughness = clamp(mat.specularRoughness, ROUGHNESS_MIN, 1.0);
|
|
320
353
|
mat.baseMetalness = clamp(mat.baseMetalness, 0.0, 1.0);
|
|
@@ -324,40 +357,40 @@ mat.alphaY = specularAlpha.y;
|
|
|
324
357
|
}
|
|
325
358
|
|
|
326
359
|
#if defined(NUM_NORMAL_MAPS)
|
|
327
|
-
vec3
|
|
360
|
+
vec3 ol(int materialIndex, vec2 uv, vec3 normal, vec3 dp1, vec3 dp2, vec2 oc, vec2 od) {
|
|
328
361
|
int i = materialIndex * MAT_DATA_SIZE;
|
|
329
|
-
vec4
|
|
330
|
-
int normalMapIndex = int(
|
|
362
|
+
vec4 fo = fetchMatData(i + MAT_ROW_ROUGHNESS_NORMAL);
|
|
363
|
+
int normalMapIndex = int(fo.y);
|
|
331
364
|
if (normalMapIndex >= 0) {
|
|
332
365
|
|
|
333
366
|
|
|
334
367
|
|
|
335
|
-
vec3
|
|
336
|
-
vec3
|
|
337
|
-
vec3 dpdu =
|
|
338
|
-
vec3
|
|
339
|
-
float
|
|
340
|
-
if (
|
|
341
|
-
float
|
|
342
|
-
dpdu *=
|
|
343
|
-
|
|
368
|
+
vec3 qW = cross(dp2, normal);
|
|
369
|
+
vec3 qV = cross(normal, dp1);
|
|
370
|
+
vec3 dpdu = qW * oc.x + qV * od.x;
|
|
371
|
+
vec3 sn = qW * oc.y + qV * od.y;
|
|
372
|
+
float dT = max(dot(dpdu, dpdu), dot(sn, sn));
|
|
373
|
+
if (dT > 1e-12) {
|
|
374
|
+
float sz = inversesqrt(dT);
|
|
375
|
+
dpdu *= sz;
|
|
376
|
+
sn *= sz;
|
|
344
377
|
}
|
|
345
378
|
else {
|
|
346
379
|
|
|
347
380
|
|
|
348
381
|
|
|
349
|
-
vec3
|
|
382
|
+
vec3 ns = abs(normal.z) < 0.999
|
|
350
383
|
? vec3(0.0, 0.0, 1.0)
|
|
351
384
|
: vec3(0.0, 1.0, 0.0);
|
|
352
|
-
dpdu = normalize(cross(
|
|
353
|
-
|
|
385
|
+
dpdu = normalize(cross(ns, normal));
|
|
386
|
+
sn = cross(normal, dpdu);
|
|
354
387
|
}
|
|
355
388
|
|
|
356
389
|
vec3 n = 2.0 * sampleMap(normalMapIndex, uv).rgb - 1.0;
|
|
357
|
-
n.xy *=
|
|
390
|
+
n.xy *= fo.zw;
|
|
358
391
|
n = normalize(n);
|
|
359
392
|
|
|
360
|
-
mat3 tbn = mat3(dpdu,
|
|
393
|
+
mat3 tbn = mat3(dpdu, sn, normal);
|
|
361
394
|
|
|
362
395
|
return normalize(tbn * n);
|
|
363
396
|
} else {
|
|
@@ -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,yBAAyB,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAC/E,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,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAqEhB,oBAAoB,GAAG,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBA6FhC,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;;;;;EAK5C,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 '../../materialLayout.js';\nimport { materialAlphaModeConstants } from '../../../scene/OpenPBRMaterial.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 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\nvec2 getMapUV(int index, vec2 uv) {\n vec4 transform = mapTransform[index];\n vec2 repeatedUv = fract(uv * transform.xy + transform.zw);\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 sampleMap(int index, vec2 uv) {\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) {\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 NUM_COAT_NORMAL_MAPS\n mat.coatNormalEnabled = fetchMatData(i + MAT_ROW_LAYER_MAPS).z >= 0.0 && mat.coatWeight > 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 instanceColor = getInstanceColor(instanceIndex);\n mat.baseColor *= instanceColor;\n if (mat.materialType == UNLIT) mat.emission *= instanceColor;\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,yBAAyB,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAC/E,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 '../../materialLayout.js';\nimport { materialAlphaModeConstants } from '../../../scene/OpenPBRMaterial.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"]}
|