@meimu/mutracer 0.2.0 → 0.3.0

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