@meimu/mutracer 0.1.3 → 0.1.4

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.
Files changed (118) hide show
  1. package/dist/assets/bvh.worker.js +1 -1
  2. package/dist/mutracer.umd.js +4114 -4015
  3. package/docs/api.md +11 -9
  4. package/docs/threejs.md +30 -4
  5. package/lib/Engine.js +18 -1
  6. package/lib/Engine.js.map +1 -1
  7. package/lib/main.d.ts +1 -1
  8. package/lib/main.js.map +1 -1
  9. package/lib/oidn.d.ts +1 -1
  10. package/lib/oidnBundledWeights.cdn.d.ts +2 -2
  11. package/lib/renderer/MaterialTable.d.ts +1 -0
  12. package/lib/renderer/MaterialTable.js +10 -4
  13. package/lib/renderer/MaterialTable.js.map +1 -1
  14. package/lib/renderer/WGPUBloomPass.js +18 -18
  15. package/lib/renderer/WGPUFullQuadPass.js +6 -6
  16. package/lib/renderer/WGPUJNLMDenoiser.js +69 -69
  17. package/lib/renderer/WGPURayTraceOutput.js +14 -14
  18. package/lib/renderer/WGPURayTracePass.d.ts +2 -0
  19. package/lib/renderer/WGPURayTracePass.js +12 -6
  20. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  21. package/lib/renderer/WGPURenderingPipeline.js +15 -15
  22. package/lib/renderer/WebGLJNLMDenoiser.js +69 -69
  23. package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
  24. package/lib/renderer/WebGLRayTracePass.d.ts +1 -0
  25. package/lib/renderer/WebGLRayTracePass.js +7 -1
  26. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  27. package/lib/renderer/envMapCreation.d.ts +5 -1
  28. package/lib/renderer/envMapCreation.js +42 -5
  29. package/lib/renderer/envMapCreation.js.map +1 -1
  30. package/lib/renderer/geometryUpdates.js +1 -1
  31. package/lib/renderer/geometryUpdates.js.map +1 -1
  32. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +12 -12
  33. package/lib/renderer/glsl/chunks/envMap.glsl.js +66 -54
  34. package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -1
  35. package/lib/renderer/glsl/chunks/intersect.glsl.js +316 -310
  36. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
  37. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +151 -119
  38. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
  39. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +414 -414
  40. package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
  41. package/lib/renderer/glsl/chunks/random.glsl.js +3 -3
  42. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +40 -39
  43. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
  44. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +69 -69
  45. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +78 -78
  46. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +12 -12
  47. package/lib/renderer/glsl/chunks/sampling.glsl.js +75 -75
  48. package/lib/renderer/glsl/chunks/sobol.glsl.js +61 -61
  49. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
  50. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
  51. package/lib/renderer/glsl/depthQuery.frag.js +5 -5
  52. package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
  53. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +8 -8
  54. package/lib/renderer/glsl/rayTrace.frag.js +133 -133
  55. package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
  56. package/lib/renderer/glsl/shadowCatcher.frag.js +9 -9
  57. package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
  58. package/lib/renderer/glsl/webglPipeline.frag.js +52 -52
  59. package/lib/renderer/lightsUtil.js +6 -4
  60. package/lib/renderer/lightsUtil.js.map +1 -1
  61. package/lib/renderer/materialChanges.js +1 -1
  62. package/lib/renderer/materialChanges.js.map +1 -1
  63. package/lib/renderer/materialComparison.generated.js +36 -18
  64. package/lib/renderer/materialComparison.generated.js.map +1 -1
  65. package/lib/renderer/prepareMeshBVH.js +2 -2
  66. package/lib/renderer/prepareMeshBVH.js.map +1 -1
  67. package/lib/renderer/sceneChangeDetector.js +4 -1
  68. package/lib/renderer/sceneChangeDetector.js.map +1 -1
  69. package/lib/renderer/sceneLightChanges.js +3 -2
  70. package/lib/renderer/sceneLightChanges.js.map +1 -1
  71. package/lib/renderer/scratchSampling.js +18 -18
  72. package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
  73. package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +1 -1
  74. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +39 -31
  75. package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -1
  76. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +475 -469
  77. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  78. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +8 -8
  79. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +93 -59
  80. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
  81. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +469 -469
  82. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.d.ts +1 -1
  83. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +117 -120
  84. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js.map +1 -1
  85. package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
  86. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +25 -22
  87. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
  88. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +127 -127
  89. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +136 -136
  90. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +6 -6
  91. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +73 -73
  92. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +62 -62
  93. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
  94. package/lib/renderer/wgsl/compose.frag.wgsl.js +105 -105
  95. package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
  96. package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +1 -1
  97. package/lib/renderer/wgsl/depthQuery.wgsl.js +5 -5
  98. package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
  99. package/lib/renderer/wgsl/offlineAdaptive.compute.js +28 -28
  100. package/lib/renderer/wgsl/rayTrace.compute.js +251 -248
  101. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
  102. package/lib/scene/EnvironmentLight.d.ts +9 -3
  103. package/lib/scene/EnvironmentLight.js +9 -2
  104. package/lib/scene/EnvironmentLight.js.map +1 -1
  105. package/lib/scene/Scene.d.ts +4 -0
  106. package/lib/scene/Scene.js.map +1 -1
  107. package/lib/scene/SpotLight.d.ts +2 -2
  108. package/lib/scene/SpotLight.js +1 -1
  109. package/lib/scene/SpotLight.js.map +1 -1
  110. package/lib/scene/Texture.d.ts +17 -6
  111. package/lib/scene/Texture.js +13 -4
  112. package/lib/scene/Texture.js.map +1 -1
  113. package/lib/util/fromTHREE.js +151 -29
  114. package/lib/util/fromTHREE.js.map +1 -1
  115. package/lib/version.d.ts +1 -1
  116. package/lib/version.js +1 -1
  117. package/lib/version.js.map +1 -1
  118. 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 fb(float roughness, float strength) {
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 oB(vec3 c) {
37
+ vec3 oK(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 ky(materialBuffer, i, materialBufferColumns);
41
+ return kG(materialBuffer, i, materialBufferColumns);
41
42
  }
42
43
 
43
44
 
44
- float lg(float alpha, int alphaMode, float alphaCutoff) {
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 vU(int idx) {
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 oB(c);
66
+ return oK(c);
66
67
  }
67
68
 
68
- vec2 oa(int index) {
69
+ vec2 kJ(int index) {
69
70
  return mapInfo[index].xy;
70
71
  }
71
72
 
72
- float pj(int index) {
73
+ float lk(int index) {
73
74
  return floor(mapInfo[index].z);
74
75
  }
75
76
 
76
- vec2 nZ(int index) {
77
+ vec2 jP(int index) {
77
78
  return vec2(fract(mapInfo[index].z), mapInfo[index].w);
78
79
  }
79
80
 
80
- vec2 sg(int index, vec2 uv) {
81
+ float fS(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 qz = fract(uv * transform.xy + transform.zw);
83
- vec2 jg = 1.0 / vec2(textureSize(map, 0).xy);
84
- vec2 dZ = nZ(index);
85
- vec2 kg = oa(index) + jg;
86
- vec2 oE = dZ - 0.5 * jg;
87
- vec2 lr = dZ + kg - jg;
89
+ vec2 value = uv * transform.xy + transform.zw;
90
+ return vec2(fS(value.x, mapWrap[index].x), fS(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 oN = dZ - 0.5 * jk;
99
+ vec2 lE = dZ + kn - jk;
88
100
  return clamp(
89
- oE + qz * kg,
101
+ oN + qH * kn,
90
102
  dZ,
91
- lr
103
+ lE
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
- return texture(map, vec3(sg(index, uv), pj(index)));
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 oX = ROUGHNESS_MIN * ROUGHNESS_MIN;
108
- if (anisotropy == 0.0) { return vec2(max(oX, alpha)); }
109
- float dg = 1.0 - anisotropy;
110
- float rZ = alpha * sqrt(2.0 / (1.0 + dg * dg));
111
- return max(vec2(oX), vec2(rZ, dg * rZ));
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 kA(int instanceIndex) {
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 eT(
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 oM = fetchMatData(i + MAT_ROW_COLOR);
129
- vec4 hc = fetchMatData(i + MAT_ROW_ROUGHNESS_NORMAL);
130
- vec4 gi = fetchMatData(i + MAT_ROW_METALLIC_MAPS);
131
- vec4 hE = fetchMatData(i + MAT_ROW_EMISSION);
132
- vec4 gU = fetchMatData(i + MAT_ROW_IOR_TRANSMISSION);
160
+ vec4 oV = fetchMatData(i + MAT_ROW_COLOR);
161
+ vec4 hh = fetchMatData(i + MAT_ROW_ROUGHNESS_NORMAL);
162
+ vec4 gn = fetchMatData(i + MAT_ROW_METALLIC_MAPS);
163
+ vec4 hI = fetchMatData(i + MAT_ROW_EMISSION);
164
+ vec4 gY = fetchMatData(i + MAT_ROW_IOR_TRANSMISSION);
133
165
  vec4 misc = fetchMatData(i + MAT_ROW_MISC);
134
- vec4 nk = fetchMatData(i + MAT_ROW_ALPHA_FILM);
135
- vec4 lI = fetchMatData(i + MAT_ROW_BASE_CONTROLS);
136
- vec4 oQ = fetchMatData(i + MAT_ROW_SPECULAR_FUZZ);
166
+ vec4 nC = fetchMatData(i + MAT_ROW_ALPHA_FILM);
167
+ vec4 lS = 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 wj = fetchMatData(i + MAT_ROW_FUZZ);
139
- vec4 vE = fetchMatData(i + MAT_ROW_COAT);
140
- vec4 lJ = fetchMatData(i + MAT_ROW_COAT_CONTROLS);
141
- vec4 mN = fetchMatData(i + MAT_ROW_FILM_DISPERSION);
142
- vec4 nj = fetchMatData(i + MAT_ROW_STANDALONE_MAPS);
170
+ vec4 wq = fetchMatData(i + MAT_ROW_FUZZ);
171
+ vec4 vL = fetchMatData(i + MAT_ROW_COAT);
172
+ vec4 lT = fetchMatData(i + MAT_ROW_COAT_CONTROLS);
173
+ vec4 mY = fetchMatData(i + MAT_ROW_FILM_DISPERSION);
174
+ vec4 nB = fetchMatData(i + MAT_ROW_STANDALONE_MAPS);
143
175
  int mapAlphaUsage = int(misc.a);
144
176
 
145
- mat.baseColor = oM.rgb;
146
- mat.materialType = int(oM.w);
147
- mat.specularRoughness = hc.x;
148
- mat.baseMetalness = gi.x;
149
- mat.specularAnisotropy = clamp(gi.y, 0.0, 1.0);
150
- mat.emission = hE.rgb;
177
+ mat.baseColor = oV.rgb;
178
+ mat.materialType = int(oV.w);
179
+ mat.specularRoughness = hh.x;
180
+ mat.baseMetalness = gn.x;
181
+ mat.specularAnisotropy = clamp(gn.y, 0.0, 1.0);
182
+ mat.emission = hI.rgb;
151
183
  mat.inside = false;
152
- mat.specularIor = gU.x;
153
- mat.transmissionWeight = gU.y;
184
+ mat.specularIor = gY.x;
185
+ mat.transmissionWeight = gY.y;
154
186
  #ifdef HAS_MEDIUM
155
- mat.mediumType = int(gU.z);
187
+ mat.mediumType = int(gY.z);
156
188
  #else
157
189
  mat.mediumType = 0;
158
190
  #endif
159
- mat.thinWalled = gU.w > 0.5;
191
+ mat.thinWalled = gY.w > 0.5;
160
192
  mat.bevel = misc.r;
161
193
  mat.transmissionDispersionScale = misc.g;
162
- mat.dispersionAbbeNumber = max(mN.y, 1e-6);
194
+ mat.dispersionAbbeNumber = max(mY.y, 1e-6);
163
195
  mat.thinFilmThickness = misc.b;
164
- mat.thinFilmIor = nk.b;
165
- mat.thinFilmWeight = clamp(mN.x, 0.0, 1.0);
196
+ mat.thinFilmIor = nC.b;
197
+ mat.thinFilmWeight = clamp(mY.x, 0.0, 1.0);
166
198
 
167
199
  mat.thinFilmThickness *= 1000.0;
168
- mat.baseWeight = clamp(lI.x, 0.0, 1.0);
169
- mat.diffuseRoughness = clamp(lI.y, 0.0, 1.0);
170
- mat.specularWeight = max(0.0, lI.z);
171
- mat.subsurfaceWeight = clamp(lI.w, 0.0, 1.0);
172
- mat.specularColor = max(oQ.rgb, vec3(0.0));
173
- mat.fuzzWeight = clamp(oQ.w, 0.0, 1.0);
200
+ mat.baseWeight = clamp(lS.x, 0.0, 1.0);
201
+ mat.diffuseRoughness = clamp(lS.y, 0.0, 1.0);
202
+ mat.specularWeight = max(0.0, lS.z);
203
+ mat.subsurfaceWeight = clamp(lS.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(wj.rgb, vec3(0.0));
177
- mat.fuzzRoughness = clamp(wj.w, 0.0, 1.0);
178
- mat.coatColor = max(vE.rgb, vec3(0.0));
179
- mat.coatWeight = clamp(vE.w, 0.0, 1.0);
180
- mat.coatRoughness = clamp(lJ.x, ROUGHNESS_MIN, 1.0);
181
- mat.coatAnisotropy = clamp(lJ.y, 0.0, 1.0);
182
- mat.coatIor = max(lJ.z, 1.0);
183
- mat.coatDarkening = clamp(lJ.w, 0.0, 1.0);
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(lT.x, ROUGHNESS_MIN, 1.0);
213
+ mat.coatAnisotropy = clamp(lT.y, 0.0, 1.0);
214
+ mat.coatIor = max(lT.z, 1.0);
215
+ mat.coatDarkening = clamp(lT.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 = nk.r;
226
+ mat.alpha = nC.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(gi.z);
232
+ int diffuseMapIndex = int(gn.z);
201
233
  if (diffuseMapIndex >= 0) {
202
- vec4 nQ = sampleMap(
234
+ vec4 ob = sampleMap(
203
235
  diffuseMapIndex, getMapUvSet(diffuseMapIndex, uv, uv1)
204
236
  );
205
237
 
206
238
 
207
- mat.baseColor *= decodeMapColor(diffuseMapIndex, nQ.rgb);
239
+ mat.baseColor *= decodeMapColor(diffuseMapIndex, ob.rgb);
208
240
 
209
241
 
210
242
  if (mapAlphaUsage == ${mapAlphaUsageConstants.transmission + ''}) {
211
- mat.transmissionWeight = 1.0 - nQ.a;
243
+ mat.transmissionWeight = 1.0 - ob.a;
212
244
  }
213
245
  else if (mapAlphaUsage == ${mapAlphaUsageConstants.alpha + ''}) {
214
- mat.alpha *= nQ.a;
246
+ mat.alpha *= ob.a;
215
247
  }
216
248
  }
217
249
  #endif
218
250
 
219
251
  ${simpleTextureSample('alphaMap', 'glsl')}
220
252
 
221
- mat.alpha = lg(
222
- mat.alpha, int(fetchMatData(i + MAT_ROW_ALPHA).w), nj.w
253
+ mat.alpha = lr(
254
+ mat.alpha, int(fetchMatData(i + MAT_ROW_ALPHA).w), nB.w
223
255
  );
224
256
 
225
257
  ${simpleTextureSample('transmissionMap', 'glsl')}
226
258
 
227
259
  #ifdef NUM_METALLIC_ROUGHNESS_MAPS
228
- int metallicRoughnessMapIndex = int(gi.w);
260
+ int metallicRoughnessMapIndex = int(gn.w);
229
261
  if (metallicRoughnessMapIndex >= 0) {
230
- vec4 fK = sampleMap(
262
+ vec4 fN = sampleMap(
231
263
  metallicRoughnessMapIndex,
232
264
  getMapUvSet(metallicRoughnessMapIndex, uv, uv1)
233
265
  );
234
- mat.baseMetalness *= fK.b;
235
- mat.specularRoughness *= fK.g;
266
+ mat.baseMetalness *= fN.b;
267
+ mat.specularRoughness *= fN.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(hE.w);
276
+ int emissiveMapIndex = int(hI.w);
245
277
  if (emissiveMapIndex >= 0) {
246
278
  vec3 emissive = sampleMap(
247
279
  emissiveMapIndex, getMapUvSet(emissiveMapIndex, uv, uv1)
@@ -251,12 +283,12 @@ mat.emission *= decodeMapColor(emissiveMapIndex, emissive);
251
283
  #endif
252
284
 
253
285
  #ifdef NUM_COAT_WEIGHT_MAPS
254
- int hM = int(fetchMatData(i + MAT_ROW_LAYER_MAPS).x);
255
- if (hM >= 0 && mat.materialType == 0) {
256
- float qo = clamp(vE.w, 0.0, 1.0) * sampleMap(
257
- hM, getMapUvSet(hM, uv, uv1)
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(vE.rgb, vec3(0.0))), qo);
291
+ mat.emission *= mix(vec3(1.0), sqrt(max(vL.rgb, vec3(0.0))), qw);
260
292
  }
261
293
  #endif
262
294
 
@@ -277,29 +309,29 @@ ${simpleTextureSample('specularWeightMap', 'glsl')}
277
309
 
278
310
  ${simpleTextureSample('specularColorMap', 'glsl')}
279
311
 
280
- vec4 kN = fetchMatData(i + MAT_ROW_DIRECTION_NORMAL);
312
+ vec4 kW = fetchMatData(i + MAT_ROW_DIRECTION_NORMAL);
281
313
  mat.anisotropyDirection = vec2(1.0, 0.0);
282
- mat.anisotropyDirectionEnabled = kN.y != 0.0;
314
+ mat.anisotropyDirectionEnabled = kW.y != 0.0;
283
315
  mat.coatAnisotropyRotation = fetchMatData(i + MAT_ROW_FILM_TEXTURE).x;
284
316
  #ifdef NUM_ANISOTROPY_MAPS
285
- if (kN.x >= 0.0) {
286
- int index = int(kN.x);
287
- vec4 iX = sampleMap(index, getMapUvSet(index, uv, uv1));
288
- mat.specularAnisotropy *= iX.b;
289
- vec2 direction = iX.rg * 2.0 - 1.0;
317
+ if (kW.x >= 0.0) {
318
+ int index = int(kW.x);
319
+ vec4 eA = sampleMap(index, getMapUvSet(index, uv, uv1));
320
+ mat.specularAnisotropy *= eA.b;
321
+ vec2 direction = eA.rg * 2.0 - 1.0;
290
322
  if (dot(direction, direction) > 1e-4) mat.anisotropyDirection = normalize(direction);
291
323
  mat.anisotropyDirectionEnabled = true;
292
324
  }
293
325
  #endif
294
326
  #ifdef HAS_GLTF_ANISOTROPY
295
327
  if (fetchMatData(i + MAT_ROW_FILM_TEXTURE).y > 0.5 && mat.specularAnisotropy > 0.0) {
296
- vec2 sv = fb(clamp(mat.specularRoughness, 0.0, 1.0), mat.specularAnisotropy);
297
- mat.specularRoughness = sv.x;
298
- mat.specularAnisotropy = sv.y;
328
+ vec2 sF = fe(clamp(mat.specularRoughness, 0.0, 1.0), mat.specularAnisotropy);
329
+ mat.specularRoughness = sF.x;
330
+ mat.specularAnisotropy = sF.y;
299
331
  }
300
332
  #endif
301
333
  if (mat.anisotropyDirectionEnabled) {
302
- float theta = kN.y;
334
+ float theta = kW.y;
303
335
  vec2 d = mat.anisotropyDirection;
304
336
  mat.anisotropyDirection = vec2(cos(theta)*d.x - sin(theta)*d.y, sin(theta)*d.x + cos(theta)*d.y);
305
337
  }
@@ -307,14 +339,14 @@ mat.anisotropyDirection = vec2(cos(theta)*d.x - sin(theta)*d.y, sin(theta)*d.x +
307
339
 
308
340
 
309
341
  if (mat.coatWeight > 0.0 && mat.coatRoughness > 0.0) {
310
- float hI = mat.specularRoughness * mat.specularRoughness;
311
- float hJ = mat.coatRoughness * mat.coatRoughness;
342
+ float hM = mat.specularRoughness * mat.specularRoughness;
343
+ float hN = mat.coatRoughness * mat.coatRoughness;
312
344
  mat.specularRoughness = mix(mat.specularRoughness,
313
- pow(min(1.0, hI * hI + 2.0 * hJ * hJ), 0.25), mat.coatWeight);
345
+ pow(min(1.0, hM * hM + 2.0 * hN * hN), 0.25), mat.coatWeight);
314
346
  }
315
- vec3 instanceColor = kA(instanceIndex);
316
- mat.baseColor *= instanceColor;
317
- if (mat.materialType == UNLIT) mat.emission *= instanceColor;
347
+ vec3 color = kI(instanceIndex) * vertexColor;
348
+ mat.baseColor *= color;
349
+ if (mat.materialType == UNLIT) mat.emission *= color;
318
350
 
319
351
  mat.specularRoughness = clamp(mat.specularRoughness, ROUGHNESS_MIN, 1.0);
320
352
  mat.baseMetalness = clamp(mat.baseMetalness, 0.0, 1.0);
@@ -324,40 +356,40 @@ mat.alphaY = specularAlpha.y;
324
356
  }
325
357
 
326
358
  #if defined(NUM_NORMAL_MAPS)
327
- vec3 ob(int materialIndex, vec2 uv, vec3 normal, vec3 dp1, vec3 dp2, vec2 nS, vec2 nT) {
359
+ vec3 om(int materialIndex, vec2 uv, vec3 normal, vec3 dp1, vec3 dp2, vec2 od, vec2 oe) {
328
360
  int i = materialIndex * MAT_DATA_SIZE;
329
- vec4 hc = fetchMatData(i + MAT_ROW_ROUGHNESS_NORMAL);
330
- int normalMapIndex = int(hc.y);
361
+ vec4 hh = fetchMatData(i + MAT_ROW_ROUGHNESS_NORMAL);
362
+ int normalMapIndex = int(hh.y);
331
363
  if (normalMapIndex >= 0) {
332
364
 
333
365
 
334
366
 
335
- vec3 qO = cross(dp2, normal);
336
- vec3 qM = cross(normal, dp1);
337
- vec3 dpdu = qO * nS.x + qM * nT.x;
338
- vec3 se = qO * nS.y + qM * nT.y;
339
- float dS = max(dot(dpdu, dpdu), dot(se, se));
340
- if (dS > 1e-12) {
341
- float sn = inversesqrt(dS);
342
- dpdu *= sn;
343
- se *= sn;
367
+ vec3 qW = cross(dp2, normal);
368
+ vec3 qV = cross(normal, dp1);
369
+ vec3 dpdu = qW * od.x + qV * oe.x;
370
+ vec3 sn = qW * od.y + qV * oe.y;
371
+ float dT = max(dot(dpdu, dpdu), dot(sn, sn));
372
+ if (dT > 1e-12) {
373
+ float sz = inversesqrt(dT);
374
+ dpdu *= sz;
375
+ sn *= sz;
344
376
  }
345
377
  else {
346
378
 
347
379
 
348
380
 
349
- vec3 nf = abs(normal.z) < 0.999
381
+ vec3 nt = abs(normal.z) < 0.999
350
382
  ? vec3(0.0, 0.0, 1.0)
351
383
  : vec3(0.0, 1.0, 0.0);
352
- dpdu = normalize(cross(nf, normal));
353
- se = cross(normal, dpdu);
384
+ dpdu = normalize(cross(nt, normal));
385
+ sn = cross(normal, dpdu);
354
386
  }
355
387
 
356
388
  vec3 n = 2.0 * sampleMap(normalMapIndex, uv).rgb - 1.0;
357
- n.xy *= hc.zw;
389
+ n.xy *= hh.zw;
358
390
  n = normalize(n);
359
391
 
360
- mat3 tbn = mat3(dpdu, se, normal);
392
+ mat3 tbn = mat3(dpdu, sn, normal);
361
393
 
362
394
  return normalize(tbn * n);
363
395
  } 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;;;;;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 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 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 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"]}