@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.
Files changed (125) hide show
  1. package/dist/assets/bvh.worker.js +1 -1
  2. package/dist/mutracer.umd.js +4155 -4052
  3. package/docs/api.md +13 -10
  4. package/docs/materials.md +17 -26
  5. package/docs/threejs.md +35 -9
  6. package/docs/viewer.md +36 -3
  7. package/lib/Engine.js +18 -1
  8. package/lib/Engine.js.map +1 -1
  9. package/lib/main.d.ts +1 -1
  10. package/lib/main.js.map +1 -1
  11. package/lib/oidn.d.ts +1 -1
  12. package/lib/oidnBundledWeights.cdn.d.ts +2 -2
  13. package/lib/renderer/MaterialTable.d.ts +1 -0
  14. package/lib/renderer/MaterialTable.js +10 -4
  15. package/lib/renderer/MaterialTable.js.map +1 -1
  16. package/lib/renderer/WGPUBloomPass.js +18 -18
  17. package/lib/renderer/WGPUFullQuadPass.js +6 -6
  18. package/lib/renderer/WGPUJNLMDenoiser.js +69 -69
  19. package/lib/renderer/WGPURayTraceOutput.js +14 -14
  20. package/lib/renderer/WGPURayTracePass.d.ts +2 -0
  21. package/lib/renderer/WGPURayTracePass.js +17 -9
  22. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  23. package/lib/renderer/WGPURenderingPipeline.js +15 -15
  24. package/lib/renderer/WebGLJNLMDenoiser.js +69 -69
  25. package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
  26. package/lib/renderer/WebGLRayTracePass.d.ts +1 -0
  27. package/lib/renderer/WebGLRayTracePass.js +8 -1
  28. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  29. package/lib/renderer/envMapCreation.d.ts +5 -1
  30. package/lib/renderer/envMapCreation.js +42 -5
  31. package/lib/renderer/envMapCreation.js.map +1 -1
  32. package/lib/renderer/geometryUpdates.js +1 -1
  33. package/lib/renderer/geometryUpdates.js.map +1 -1
  34. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +12 -12
  35. package/lib/renderer/glsl/chunks/envMap.glsl.js +66 -54
  36. package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -1
  37. package/lib/renderer/glsl/chunks/intersect.glsl.js +323 -315
  38. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
  39. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +154 -121
  40. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
  41. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +434 -434
  42. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js.map +1 -1
  43. package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
  44. package/lib/renderer/glsl/chunks/random.glsl.js +3 -3
  45. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +42 -41
  46. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
  47. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +69 -69
  48. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +84 -84
  49. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
  50. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +12 -12
  51. package/lib/renderer/glsl/chunks/sampling.glsl.js +75 -75
  52. package/lib/renderer/glsl/chunks/sobol.glsl.js +61 -61
  53. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
  54. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
  55. package/lib/renderer/glsl/depthQuery.frag.js +5 -5
  56. package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
  57. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +8 -8
  58. package/lib/renderer/glsl/rayTrace.frag.js +133 -133
  59. package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
  60. package/lib/renderer/glsl/shadowCatcher.frag.js +9 -9
  61. package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
  62. package/lib/renderer/glsl/webglPipeline.frag.js +52 -52
  63. package/lib/renderer/lightsUtil.js +6 -4
  64. package/lib/renderer/lightsUtil.js.map +1 -1
  65. package/lib/renderer/materialChanges.js +1 -1
  66. package/lib/renderer/materialChanges.js.map +1 -1
  67. package/lib/renderer/materialComparison.generated.js +36 -18
  68. package/lib/renderer/materialComparison.generated.js.map +1 -1
  69. package/lib/renderer/prepareMeshBVH.js +2 -2
  70. package/lib/renderer/prepareMeshBVH.js.map +1 -1
  71. package/lib/renderer/sceneChangeDetector.js +4 -1
  72. package/lib/renderer/sceneChangeDetector.js.map +1 -1
  73. package/lib/renderer/sceneLightChanges.js +3 -2
  74. package/lib/renderer/sceneLightChanges.js.map +1 -1
  75. package/lib/renderer/scratchSampling.js +18 -18
  76. package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
  77. package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +1 -1
  78. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +39 -31
  79. package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -1
  80. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +476 -470
  81. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  82. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +8 -8
  83. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +95 -60
  84. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
  85. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +469 -469
  86. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.d.ts +1 -1
  87. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +117 -120
  88. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js.map +1 -1
  89. package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
  90. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +25 -22
  91. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
  92. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +127 -127
  93. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +136 -136
  94. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +6 -6
  95. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +73 -73
  96. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +62 -62
  97. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
  98. package/lib/renderer/wgsl/compose.frag.wgsl.js +105 -105
  99. package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
  100. package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +1 -1
  101. package/lib/renderer/wgsl/depthQuery.wgsl.js +5 -5
  102. package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
  103. package/lib/renderer/wgsl/offlineAdaptive.compute.js +28 -28
  104. package/lib/renderer/wgsl/rayTrace.compute.js +251 -248
  105. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
  106. package/lib/scene/EnvironmentLight.d.ts +9 -3
  107. package/lib/scene/EnvironmentLight.js +9 -2
  108. package/lib/scene/EnvironmentLight.js.map +1 -1
  109. package/lib/scene/OpenPBRMaterial.d.ts +1 -1
  110. package/lib/scene/OpenPBRMaterial.js +1 -1
  111. package/lib/scene/OpenPBRMaterial.js.map +1 -1
  112. package/lib/scene/Scene.d.ts +4 -0
  113. package/lib/scene/Scene.js.map +1 -1
  114. package/lib/scene/SpotLight.d.ts +2 -2
  115. package/lib/scene/SpotLight.js +1 -1
  116. package/lib/scene/SpotLight.js.map +1 -1
  117. package/lib/scene/Texture.d.ts +17 -6
  118. package/lib/scene/Texture.js +13 -4
  119. package/lib/scene/Texture.js.map +1 -1
  120. package/lib/util/fromTHREE.js +151 -29
  121. package/lib/util/fromTHREE.js.map +1 -1
  122. package/lib/version.d.ts +1 -1
  123. package/lib/version.js +1 -1
  124. package/lib/version.js.map +1 -1
  125. 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 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 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 oJ(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 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 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(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
- oE + qz * kg,
101
+ oM + qH * kn,
90
102
  dZ,
91
- lr
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
- 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 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 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 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 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 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 = 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 = 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 = gU.x;
153
- mat.transmissionWeight = gU.y;
184
+ mat.specularIor = gZ.x;
185
+ mat.transmissionWeight = gZ.y;
154
186
  #ifdef HAS_MEDIUM
155
- mat.mediumType = int(gU.z);
187
+ mat.mediumType = int(gZ.z);
156
188
  #else
157
189
  mat.mediumType = 0;
158
190
  #endif
159
- mat.thinWalled = gU.w > 0.5;
191
+ mat.thinWalled = gZ.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(mX.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 = nB.b;
197
+ mat.thinFilmWeight = clamp(mX.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(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(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(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 = nk.r;
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(gi.z);
232
+ int diffuseMapIndex = int(gp.z);
201
233
  if (diffuseMapIndex >= 0) {
202
- vec4 nQ = sampleMap(
234
+ vec4 oa = 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, oa.rgb);
208
240
 
209
241
 
210
242
  if (mapAlphaUsage == ${mapAlphaUsageConstants.transmission + ''}) {
211
- mat.transmissionWeight = 1.0 - nQ.a;
243
+ mat.transmissionWeight = 1.0 - oa.a;
212
244
  }
213
245
  else if (mapAlphaUsage == ${mapAlphaUsageConstants.alpha + ''}) {
214
- mat.alpha *= nQ.a;
246
+ mat.alpha *= oa.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), nA.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(gp.w);
229
261
  if (metallicRoughnessMapIndex >= 0) {
230
- vec4 fK = sampleMap(
262
+ vec4 fO = 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 *= 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(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,20 +283,21 @@ 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
 
263
295
  ${thinFilmTextureSample('glsl')}
264
296
 
265
297
  ${simpleTextureSample('coatWeightMap', 'glsl')}
266
- #ifdef NUM_COAT_NORMAL_MAPS
267
- mat.coatNormalEnabled = fetchMatData(i + MAT_ROW_LAYER_MAPS).z >= 0.0 && mat.coatWeight > 0.0;
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 kN = fetchMatData(i + MAT_ROW_DIRECTION_NORMAL);
313
+ vec4 kW = fetchMatData(i + MAT_ROW_DIRECTION_NORMAL);
281
314
  mat.anisotropyDirection = vec2(1.0, 0.0);
282
- mat.anisotropyDirectionEnabled = kN.y != 0.0;
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 (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;
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 sv = fb(clamp(mat.specularRoughness, 0.0, 1.0), mat.specularAnisotropy);
297
- mat.specularRoughness = sv.x;
298
- mat.specularAnisotropy = sv.y;
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 = kN.y;
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 hI = mat.specularRoughness * mat.specularRoughness;
311
- float hJ = mat.coatRoughness * mat.coatRoughness;
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, hI * hI + 2.0 * hJ * hJ), 0.25), mat.coatWeight);
346
+ pow(min(1.0, hM * hM + 2.0 * hN * hN), 0.25), mat.coatWeight);
314
347
  }
315
- vec3 instanceColor = kA(instanceIndex);
316
- mat.baseColor *= instanceColor;
317
- if (mat.materialType == UNLIT) mat.emission *= instanceColor;
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 ob(int materialIndex, vec2 uv, vec3 normal, vec3 dp1, vec3 dp2, vec2 nS, vec2 nT) {
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 hc = fetchMatData(i + MAT_ROW_ROUGHNESS_NORMAL);
330
- int normalMapIndex = int(hc.y);
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 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;
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 nf = abs(normal.z) < 0.999
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(nf, normal));
353
- se = cross(normal, dpdu);
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 *= hc.zw;
390
+ n.xy *= fo.zw;
358
391
  n = normalize(n);
359
392
 
360
- mat3 tbn = mat3(dpdu, se, normal);
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"]}