@meimu/mutracer 0.3.0 → 0.3.1

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 (304) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/LICENSES/FidelityFX-FSR.txt +19 -0
  3. package/LICENSES/pbrt-v4-Apache-2.0.txt +202 -0
  4. package/THIRD_PARTY_NOTICES.md +18 -4
  5. package/dist/assets/bvh.worker.js +1 -1
  6. package/dist/mutracer.umd.js +6260 -5580
  7. package/docs/api.md +45 -18
  8. package/docs/materials.md +4 -2
  9. package/docs/performance.md +7 -0
  10. package/docs/post-processing.md +62 -9
  11. package/docs/progressive-rendering.md +3 -0
  12. package/docs/sampling.md +4 -0
  13. package/docs/technical/acceleration.md +52 -0
  14. package/docs/technical/aovs.md +79 -0
  15. package/docs/technical/caustics.md +109 -0
  16. package/docs/technical/continuous-spectrum.md +29 -0
  17. package/docs/technical/display-upscale.md +82 -0
  18. package/docs/technical/openpbr.md +99 -0
  19. package/docs/technical/pbrt-import.md +168 -0
  20. package/docs/technical/tiling.md +74 -0
  21. package/docs/technical/webgl.md +53 -0
  22. package/docs/viewer.md +11 -1
  23. package/lib/Display.d.ts +19 -5
  24. package/lib/Display.js +10 -7
  25. package/lib/Display.js.map +1 -1
  26. package/lib/Engine.d.ts +2 -1
  27. package/lib/Engine.js +30 -2
  28. package/lib/Engine.js.map +1 -1
  29. package/lib/Render.d.ts +20 -11
  30. package/lib/Render.js +32 -7
  31. package/lib/Render.js.map +1 -1
  32. package/lib/main.d.ts +3 -1
  33. package/lib/main.js +1 -0
  34. package/lib/main.js.map +1 -1
  35. package/lib/oidn.d.ts +1 -1
  36. package/lib/renderer/AovPrimitiveCache.js +39 -8
  37. package/lib/renderer/AovPrimitiveCache.js.map +1 -1
  38. package/lib/renderer/DisplayPostProcess.d.ts +8 -3
  39. package/lib/renderer/DisplayPostProcess.js +51 -18
  40. package/lib/renderer/DisplayPostProcess.js.map +1 -1
  41. package/lib/renderer/MaterialData.js +7 -2
  42. package/lib/renderer/MaterialData.js.map +1 -1
  43. package/lib/renderer/RenderingPipeline.d.ts +7 -1
  44. package/lib/renderer/RenderingPipeline.js.map +1 -1
  45. package/lib/renderer/TileRender.d.ts +2 -2
  46. package/lib/renderer/TileRender.js +128 -7
  47. package/lib/renderer/TileRender.js.map +1 -1
  48. package/lib/renderer/WGPUAov.d.ts +6 -1
  49. package/lib/renderer/WGPUAov.js +108 -14
  50. package/lib/renderer/WGPUAov.js.map +1 -1
  51. package/lib/renderer/WGPUCanvasSurface.js +12 -1
  52. package/lib/renderer/WGPUCanvasSurface.js.map +1 -1
  53. package/lib/renderer/WGPUEnvMapDistribution.js +19 -19
  54. package/lib/renderer/WGPUFullQuadPass.js +3 -3
  55. package/lib/renderer/WGPURayTraceOutput.js +12 -12
  56. package/lib/renderer/WGPURayTracePass.d.ts +17 -4
  57. package/lib/renderer/WGPURayTracePass.js +194 -71
  58. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  59. package/lib/renderer/WGPURenderingPipeline.js +46 -40
  60. package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
  61. package/lib/renderer/WebGLAov.js +3 -3
  62. package/lib/renderer/WebGLAov.js.map +1 -1
  63. package/lib/renderer/WebGLFullQuadPass.d.ts +1 -1
  64. package/lib/renderer/WebGLFullQuadPass.js +8 -2
  65. package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
  66. package/lib/renderer/WebGLJNLMDenoiser.js +66 -66
  67. package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -1
  68. package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
  69. package/lib/renderer/WebGLRayTracePass.d.ts +14 -10
  70. package/lib/renderer/WebGLRayTracePass.js +115 -111
  71. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  72. package/lib/renderer/WebGLRenderingPipeline.js +10 -3
  73. package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
  74. package/lib/renderer/WebGLSkyBaker.js +57 -57
  75. package/lib/renderer/aov.d.ts +13 -1
  76. package/lib/renderer/aov.js +21 -2
  77. package/lib/renderer/aov.js.map +1 -1
  78. package/lib/renderer/aovDisplay.js +2 -2
  79. package/lib/renderer/aovDisplay.js.map +1 -1
  80. package/lib/renderer/binnedSahBvh.d.ts +2 -1
  81. package/lib/renderer/binnedSahBvh.js +24 -17
  82. package/lib/renderer/binnedSahBvh.js.map +1 -1
  83. package/lib/renderer/bvhAccel.d.ts +3 -1
  84. package/lib/renderer/bvhAccel.js +36 -6
  85. package/lib/renderer/bvhAccel.js.map +1 -1
  86. package/lib/renderer/cameraUniform.d.ts +1 -1
  87. package/lib/renderer/cameraUniform.js +6 -2
  88. package/lib/renderer/cameraUniform.js.map +1 -1
  89. package/lib/renderer/compactVertices.d.ts +14 -0
  90. package/lib/renderer/compactVertices.js +124 -0
  91. package/lib/renderer/compactVertices.js.map +1 -0
  92. package/lib/renderer/easu.d.ts +11 -0
  93. package/lib/renderer/easu.js +156 -0
  94. package/lib/renderer/easu.js.map +1 -0
  95. package/lib/renderer/geometryUpdateState.d.ts +1 -0
  96. package/lib/renderer/geometryUpdateState.js.map +1 -1
  97. package/lib/renderer/geometryUpdates.js +3 -2
  98. package/lib/renderer/geometryUpdates.js.map +1 -1
  99. package/lib/renderer/glsl/aovDisplay.frag.js +5 -5
  100. package/lib/renderer/glsl/aovReflectance.glsl.js +35 -35
  101. package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
  102. package/lib/renderer/glsl/aovTrace.frag.js +44 -36
  103. package/lib/renderer/glsl/aovTrace.frag.js.map +1 -1
  104. package/lib/renderer/glsl/chunks/cameraProjection.glsl.d.ts +2 -0
  105. package/lib/renderer/glsl/chunks/cameraProjection.glsl.js +16 -0
  106. package/lib/renderer/glsl/chunks/cameraProjection.glsl.js.map +1 -0
  107. package/lib/renderer/glsl/chunks/cameraRay.glsl.d.ts +1 -1
  108. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -16
  109. package/lib/renderer/glsl/chunks/cameraRay.glsl.js.map +1 -1
  110. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +8 -8
  111. package/lib/renderer/glsl/chunks/envMap.glsl.js +67 -67
  112. package/lib/renderer/glsl/chunks/intersect.glsl.js +390 -375
  113. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
  114. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +120 -120
  115. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +562 -562
  116. package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
  117. package/lib/renderer/glsl/chunks/random.glsl.js +4 -4
  118. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +37 -35
  119. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
  120. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +70 -74
  121. package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
  122. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -1
  123. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +107 -88
  124. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
  125. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +11 -11
  126. package/lib/renderer/glsl/chunks/sampling.glsl.js +77 -77
  127. package/lib/renderer/glsl/chunks/sobol.glsl.js +70 -70
  128. package/lib/renderer/glsl/chunks/spectralPrefix.glsl.d.ts +6 -0
  129. package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js +47 -0
  130. package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js.map +1 -0
  131. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
  132. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
  133. package/lib/renderer/glsl/depthQuery.frag.js +12 -6
  134. package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
  135. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +10 -10
  136. package/lib/renderer/glsl/rayTrace.frag.js +233 -170
  137. package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
  138. package/lib/renderer/glsl/shadowCatcher.frag.js +10 -9
  139. package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
  140. package/lib/renderer/glsl/webglPipeline.frag.js +58 -58
  141. package/lib/renderer/gpuMemory.js +1 -1
  142. package/lib/renderer/gpuMemory.js.map +1 -1
  143. package/lib/renderer/openPbrEnergyLut.d.ts +2 -1
  144. package/lib/renderer/openPbrEnergyLut.js +18 -1
  145. package/lib/renderer/openPbrEnergyLut.js.map +1 -1
  146. package/lib/renderer/pathLimits.d.ts +5 -4
  147. package/lib/renderer/pathLimits.js +6 -5
  148. package/lib/renderer/pathLimits.js.map +1 -1
  149. package/lib/renderer/prepareMeshBVH.d.ts +2 -0
  150. package/lib/renderer/prepareMeshBVH.js +5 -3
  151. package/lib/renderer/prepareMeshBVH.js.map +1 -1
  152. package/lib/renderer/progressiveScheduler.js +1 -1
  153. package/lib/renderer/progressiveScheduler.js.map +1 -1
  154. package/lib/renderer/renderPipeline.d.ts +4 -0
  155. package/lib/renderer/renderPipeline.js +1 -0
  156. package/lib/renderer/renderPipeline.js.map +1 -1
  157. package/lib/renderer/researchTransport.d.ts +1 -1
  158. package/lib/renderer/researchTransport.js.map +1 -1
  159. package/lib/renderer/sceneAssembly.d.ts +1 -1
  160. package/lib/renderer/sceneAssembly.js +4 -3
  161. package/lib/renderer/sceneAssembly.js.map +1 -1
  162. package/lib/renderer/sceneChangeDetector.d.ts +1 -1
  163. package/lib/renderer/sceneChangeDetector.js +3 -1
  164. package/lib/renderer/sceneChangeDetector.js.map +1 -1
  165. package/lib/renderer/sceneLayoutSchema.d.ts +1 -0
  166. package/lib/renderer/sceneLayoutSchema.js +2 -2
  167. package/lib/renderer/sceneLayoutSchema.js.map +1 -1
  168. package/lib/renderer/scenePreparation.d.ts +3 -2
  169. package/lib/renderer/scenePreparation.js +18 -2
  170. package/lib/renderer/scenePreparation.js.map +1 -1
  171. package/lib/renderer/scratchSampling.js +6 -6
  172. package/lib/renderer/spectrum.js +2 -2
  173. package/lib/renderer/staticBvhPreparation.d.ts +9 -0
  174. package/lib/renderer/staticBvhPreparation.js +8 -2
  175. package/lib/renderer/staticBvhPreparation.js.map +1 -1
  176. package/lib/renderer/surfaceHit.d.ts +10 -0
  177. package/lib/renderer/surfaceHit.js +22 -0
  178. package/lib/renderer/surfaceHit.js.map +1 -0
  179. package/lib/renderer/tangentRequirements.d.ts +2 -0
  180. package/lib/renderer/tangentRequirements.js +7 -0
  181. package/lib/renderer/tangentRequirements.js.map +1 -0
  182. package/lib/renderer/textureAtlas.d.ts +4 -0
  183. package/lib/renderer/textureAtlas.js +48 -2
  184. package/lib/renderer/textureAtlas.js.map +1 -1
  185. package/lib/renderer/webgl.js +4 -0
  186. package/lib/renderer/webgl.js.map +1 -1
  187. package/lib/renderer/webglVertexAttributes.d.ts +17 -0
  188. package/lib/renderer/webglVertexAttributes.js +44 -0
  189. package/lib/renderer/webglVertexAttributes.js.map +1 -0
  190. package/lib/renderer/wgpuBindlessSource.js +2 -2
  191. package/lib/renderer/wgpuMaterialConstants.js +4 -3
  192. package/lib/renderer/wgpuMaterialConstants.js.map +1 -1
  193. package/lib/renderer/wgpuSceneUniform.js +2 -2
  194. package/lib/renderer/wgpuSceneUniform.js.map +1 -1
  195. package/lib/renderer/wgpuShaderSource.d.ts +15 -0
  196. package/lib/renderer/wgpuShaderSource.js +1 -1
  197. package/lib/renderer/wgpuShaderSource.js.map +1 -1
  198. package/lib/renderer/wgsl/aovCompact.wgsl.d.ts +4 -0
  199. package/lib/renderer/wgsl/aovCompact.wgsl.js +26 -0
  200. package/lib/renderer/wgsl/aovCompact.wgsl.js.map +1 -0
  201. package/lib/renderer/wgsl/aovDisplay.wgsl.js +9 -9
  202. package/lib/renderer/wgsl/aovReflectance.wgsl.js +39 -39
  203. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +1 -1
  204. package/lib/renderer/wgsl/aovResolve.wgsl.d.ts +4 -0
  205. package/lib/renderer/wgsl/aovResolve.wgsl.js +21 -2
  206. package/lib/renderer/wgsl/aovResolve.wgsl.js.map +1 -1
  207. package/lib/renderer/wgsl/aovSnapshot.wgsl.js +2 -2
  208. package/lib/renderer/wgsl/aovSnapshot.wgsl.js.map +1 -1
  209. package/lib/renderer/wgsl/aovTrace.wgsl.js +31 -31
  210. package/lib/renderer/wgsl/aovTraceDisplay.wgsl.d.ts +2 -0
  211. package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js +56 -0
  212. package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js.map +1 -0
  213. package/lib/renderer/wgsl/bloom.wgsl.js +18 -18
  214. package/lib/renderer/wgsl/causticLight.compute.d.ts +1 -1
  215. package/lib/renderer/wgsl/causticLight.compute.js +121 -119
  216. package/lib/renderer/wgsl/causticLight.compute.js.map +1 -1
  217. package/lib/renderer/wgsl/chunks/background.wgsl.js +46 -46
  218. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +4 -4
  219. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +3 -3
  220. package/lib/renderer/wgsl/chunks/caustics.wgsl.js +3 -3
  221. package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
  222. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +30 -30
  223. package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +6 -2
  224. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +550 -542
  225. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  226. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.d.ts +1 -1
  227. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +18 -16
  228. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
  229. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +2 -1
  230. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +70 -69
  231. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
  232. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +593 -593
  233. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +118 -118
  234. package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
  235. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +4 -1
  236. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +32 -26
  237. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
  238. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +114 -114
  239. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
  240. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +159 -137
  241. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
  242. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +8 -8
  243. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +74 -74
  244. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +74 -74
  245. package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.d.ts +6 -0
  246. package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js +66 -0
  247. package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js.map +1 -0
  248. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
  249. package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.d.ts +2 -0
  250. package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js +61 -0
  251. package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js.map +1 -0
  252. package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +2 -0
  253. package/lib/renderer/wgsl/compose.frag.wgsl.js +99 -97
  254. package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
  255. package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
  256. package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +1 -1
  257. package/lib/renderer/wgsl/depthQuery.wgsl.js +11 -2
  258. package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
  259. package/lib/renderer/wgsl/easu.wgsl.d.ts +2 -0
  260. package/lib/renderer/wgsl/easu.wgsl.js +80 -0
  261. package/lib/renderer/wgsl/easu.wgsl.js.map +1 -0
  262. package/lib/renderer/wgsl/easuDetail.wgsl.d.ts +21 -0
  263. package/lib/renderer/wgsl/easuDetail.wgsl.js +230 -0
  264. package/lib/renderer/wgsl/easuDetail.wgsl.js.map +1 -0
  265. package/lib/renderer/wgsl/jnlm.compute.js +74 -74
  266. package/lib/renderer/wgsl/jnlm.compute.js.map +1 -1
  267. package/lib/renderer/wgsl/offlineAdaptive.compute.js +26 -26
  268. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +3 -3
  269. package/lib/renderer/wgsl/photonMap.compute.js +89 -89
  270. package/lib/renderer/wgsl/proceduralSky.compute.js +61 -61
  271. package/lib/renderer/wgsl/rayTrace.compute.d.ts +14 -0
  272. package/lib/renderer/wgsl/rayTrace.compute.js +395 -333
  273. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
  274. package/lib/scene/Scene.js.map +1 -1
  275. package/lib/settings/render.d.ts +11 -0
  276. package/lib/settings/render.js +1 -0
  277. package/lib/settings/render.js.map +1 -1
  278. package/lib/util/fromTHREE.js +21 -14
  279. package/lib/util/fromTHREE.js.map +1 -1
  280. package/lib/version.d.ts +1 -1
  281. package/lib/version.js +1 -1
  282. package/lib/version.js.map +1 -1
  283. package/package.json +5 -2
  284. package/lib/oidnBundledWeights.cdn.d.ts +0 -2
  285. package/lib/oidnBundledWeights.cdn.js +0 -5
  286. package/lib/oidnBundledWeights.cdn.js.map +0 -1
  287. package/lib/renderer/bvh.worker.d.ts +0 -1
  288. package/lib/renderer/bvh.worker.js +0 -16
  289. package/lib/renderer/bvh.worker.js.map +0 -1
  290. package/lib/renderer/bvhWorkerBuild.d.ts +0 -13
  291. package/lib/renderer/bvhWorkerBuild.js +0 -17
  292. package/lib/renderer/bvhWorkerBuild.js.map +0 -1
  293. package/lib/renderer/lightCore.d.ts +0 -12
  294. package/lib/renderer/lightCore.js +0 -13
  295. package/lib/renderer/lightCore.js.map +0 -1
  296. package/lib/renderer/materialCore.d.ts +0 -8
  297. package/lib/renderer/materialCore.js +0 -9
  298. package/lib/renderer/materialCore.js.map +0 -1
  299. package/lib/scene/PixelTexture.d.ts +0 -6
  300. package/lib/scene/PixelTexture.js +0 -10
  301. package/lib/scene/PixelTexture.js.map +0 -1
  302. package/lib/util/studioLighting.d.ts +0 -18
  303. package/lib/util/studioLighting.js +0 -36
  304. package/lib/util/studioLighting.js.map +0 -1
@@ -5,7 +5,7 @@ import { mapAlphaUsageConstants } from '../../materialConstants.js';
5
5
  // (https://github.com/hoverinc/ray-tracing-renderer).
6
6
  // Copyright (c) 2019 HOVER, MIT license; see LICENSES/RayTracingRenderer-MIT.txt.
7
7
  import { materialAlphaModeConstants } from '../../materialConstants.js';
8
- export function createMaterialBufferWgsl({ hasAnisotropyDirections = true, hasCoatNormals = false, hasSceneAlpha = true, hasTransmission = true, caustics = false, hasMetalness = true } = {}) {
8
+ export function createMaterialBufferWgsl({ independentTextures = false, hasAnisotropyDirections = true, hasCoatNormals = false, hasSceneAlpha = true, hasTransmission = true, caustics = false, hasMetalness = true } = {}) {
9
9
  const alphaModeAssignment = hasSceneAlpha
10
10
  ? '(*ma).alphaMode = i32(matData.alphaMode);'
11
11
  : '';
@@ -20,7 +20,7 @@ else if ((*ma).alphaMode == ${materialAlphaModeConstants.mask}) {
20
20
  : '(*ma).alpha = 1.0;';
21
21
  return /* wgsl */ `
22
22
 
23
- ${hasAnisotropyDirections ? /* wgsl */ `fn fb(roughness: f32, strength: f32) -> vec2f {
23
+ ${hasAnisotropyDirections ? /* wgsl */ `fn fl(roughness: f32, strength: f32) -> vec2f {
24
24
  if (strength == 0.0) { return vec2f(roughness, 0.0); }
25
25
  let u = roughness * roughness;
26
26
  let a = u + (1.0 - u) * strength * strength;
@@ -29,56 +29,57 @@ return vec2f(pow((a*a + u*u) * 0.5, 0.25), clamp(1.0 - u/a, 0.0, 1.0));
29
29
  }
30
30
  ` : /* wgsl */ ``}
31
31
 
32
- fn mq(c: vec3f) -> vec3f {
32
+ fn np(c: vec3f) -> vec3f {
33
33
  return mix(pow(c * 0.9478672986 + 0.0521327014, vec3f(2.4)), c * 0.0773993808, vec3f(c < vec3f(0.04045)));
34
34
  }
35
35
 
36
36
  fn decodeMapColor(idx: i32, c: vec3f) -> vec3f {
37
37
  if (mapInfo[idx + NUM_MAPS * 2].y > 0.5) { return c; }
38
- return mq(c);
38
+ return np(c);
39
39
  }
40
40
 
41
41
  fn af(val: i32) -> vec2f {
42
42
  return vec2f(f32(val >> 8), f32(val & 0xff) / 255.0);
43
43
  }
44
44
 
45
- fn jv(idx: i32) -> vec2f {
45
+ fn getMapSize(idx: i32) -> vec2f {
46
46
  return mapInfo[idx].xy;
47
47
  }
48
48
 
49
- fn lE(idx: i32) -> i32 {
49
+ fn getMapLayer(idx: i32) -> i32 {
50
50
  return i32(floor(mapInfo[idx].z));
51
51
  }
52
52
 
53
- fn jV(idx: i32) -> vec2f {
53
+ fn getMapOffset(idx: i32) -> vec2f {
54
54
  return vec2f(fract(mapInfo[idx].z), mapInfo[idx].w);
55
55
  }
56
56
 
57
- fn fS(value: f32, mode: f32) -> f32 {
57
+ fn gi(value: f32, mode: f32) -> f32 {
58
58
  if (mode < 0.5) { return fract(value); }
59
59
  if (mode < 1.5) { return clamp(value, 0.0, 1.0); }
60
60
  return 1.0 - abs(1.0 - (value - 2.0 * floor(value * 0.5)));
61
61
  }
62
62
 
63
- fn kF(idx: i32, uv: vec2f) -> vec2f {
63
+ fn jj(idx: i32, uv: vec2f) -> vec2f {
64
64
  let transform = mapInfo[idx + NUM_MAPS];
65
65
  let modes = mapInfo[idx + NUM_MAPS * 2].zw;
66
66
  let value = uv * transform.xy + transform.zw;
67
- return vec2f(fS(value.x, modes.x), fS(value.y, modes.y));
67
+ return vec2f(gi(value.x, modes.x), gi(value.y, modes.y));
68
68
  }
69
69
 
70
- fn tK(idx: i32, uv: vec2f) -> vec2f {
71
- let rJ = kF(idx, uv);
72
- let jn = 1.0 / vec2f(textureDimensions(map).xy);
73
- let dX = jV(idx);
74
- let kx = jv(idx) + jn;
75
- let po = dX - 0.5 * jn;
76
- let lS = dX + kx - jn;
70
+ fn getMapUV(idx: i32, uv: vec2f) -> vec2f {
71
+ ${independentTextures ? ` let wq = 0.5 / getMapSize(idx);
72
+ return clamp(jj(idx, uv), wq, 1.0 - wq);` : ` let sZ = jj(idx, uv);
73
+ let jT = 1.0 / vec2f(textureDimensions(map).xy);
74
+ let eg = getMapOffset(idx);
75
+ let lf = getMapSize(idx) + jT;
76
+ let qy = eg - 0.5 * jT;
77
+ let mM = eg + lf - jT;
77
78
  return clamp(
78
- po + rJ * kx,
79
- dX,
80
- lS
81
- );
79
+ qy + sZ * lf,
80
+ eg,
81
+ mM
82
+ );`}
82
83
  }
83
84
 
84
85
  fn getMapUvSet(idx: i32, uv: vec2f, uv1: vec2f) -> vec2f {
@@ -86,28 +87,28 @@ return select(uv, uv1, mapInfo[idx + NUM_MAPS * 2].x > 0.5);
86
87
  }
87
88
 
88
89
  fn sampleMap(idx: i32, uv: vec2f) -> vec4f {
89
- let size = vec2i(round(jv(idx) * vec2f(textureDimensions(map).xy) + vec2f(1.0)));
90
- let cR = kF(idx, uv) * vec2f(size) - vec2f(0.5);
90
+ let size = ${independentTextures ? 'vec2i(getMapSize(idx))' : 'vec2i(round(getMapSize(idx) * vec2f(textureDimensions(map).xy) + vec2f(1.0)))'};
91
+ let texel = jj(idx, uv) * vec2f(size) - vec2f(0.5);
91
92
  let modes = mapInfo[idx + NUM_MAPS * 2].zw;
92
93
 
93
94
 
94
- if ((size.x > 1 && modes.x < 0.5 && (cR.x < 0.0 || cR.x > f32(size.x - 1))) ||
95
- (size.y > 1 && modes.y < 0.5 && (cR.y < 0.0 || cR.y > f32(size.y - 1)))) {
96
- let base = vec2i(floor(cR));
97
- let weight = fract(cR);
98
- let origin = vec2i(round(jV(idx) * vec2f(textureDimensions(map).xy) - vec2f(0.5)));
95
+ if ((size.x > 1 && modes.x < 0.5 && (texel.x < 0.0 || texel.x > f32(size.x - 1))) ||
96
+ (size.y > 1 && modes.y < 0.5 && (texel.y < 0.0 || texel.y > f32(size.y - 1)))) {
97
+ let base = vec2i(floor(texel));
98
+ let weight = fract(texel);
99
+ let origin = ${independentTextures ? 'vec2i(0)' : 'vec2i(round(getMapOffset(idx) * vec2f(textureDimensions(map).xy) - vec2f(0.5)))'};
99
100
  return mix(
100
- mix(eN(idx, base, size, origin, modes), eN(idx, base + vec2i(1, 0), size, origin, modes), weight.x),
101
- mix(eN(idx, base + vec2i(0, 1), size, origin, modes), eN(idx, base + vec2i(1, 1), size, origin, modes), weight.x), weight.y);
101
+ mix(eX(idx, base, size, origin, modes), eX(idx, base + vec2i(1, 0), size, origin, modes), weight.x),
102
+ mix(eX(idx, base + vec2i(0, 1), size, origin, modes), eX(idx, base + vec2i(1, 1), size, origin, modes), weight.x), weight.y);
102
103
  }
103
- return textureSampleLevel(map, mapSampler, tK(idx, uv), lE(idx), 0.0);
104
+ return ${independentTextures ? 'textureSampleLevel(map[getMapLayer(idx)], mapSampler, getMapUV(idx, uv), 0.0)' : 'textureSampleLevel(map, mapSampler, getMapUV(idx, uv), getMapLayer(idx), 0.0)'};
104
105
  }
105
106
 
106
- fn eN(idx: i32, jq: vec2i, size: vec2i, origin: vec2i, modes: vec2f) -> vec4f {
107
- var p = clamp(jq, vec2i(0), size - vec2i(1));
108
- if (modes.x < 0.5) { p.x = ((jq.x % size.x) + size.x) % size.x; }
109
- if (modes.y < 0.5) { p.y = ((jq.y % size.y) + size.y) % size.y; }
110
- return textureLoad(map, origin + p, lE(idx), 0);
107
+ fn eX(idx: i32, jV: vec2i, size: vec2i, origin: vec2i, modes: vec2f) -> vec4f {
108
+ var p = clamp(jV, vec2i(0), size - vec2i(1));
109
+ if (modes.x < 0.5) { p.x = ((jV.x % size.x) + size.x) % size.x; }
110
+ if (modes.y < 0.5) { p.y = ((jV.y % size.y) + size.y) % size.y; }
111
+ return ${independentTextures ? 'textureLoad(map[getMapLayer(idx)], p, 0)' : 'textureLoad(map, origin + p, getMapLayer(idx), 0)'};
111
112
  }
112
113
 
113
114
 
@@ -137,14 +138,14 @@ return emission;
137
138
 
138
139
  fn aL(roughness: f32, anisotropy: f32) -> vec2f {
139
140
  let alpha = roughness * roughness;
140
- let pZ = ROUGHNESS_MIN * ROUGHNESS_MIN;
141
- if (anisotropy == 0.0) { return vec2f(max(pZ, alpha)); }
142
- let cY = 1.0 - anisotropy;
143
- let tp = alpha * sqrt(2.0 / (1.0 + cY * cY));
144
- return max(vec2f(pZ), vec2f(tp, cY * tp));
141
+ let rf = ROUGHNESS_MIN * ROUGHNESS_MIN;
142
+ if (anisotropy == 0.0) { return vec2f(max(rf, alpha)); }
143
+ let da = 1.0 - anisotropy;
144
+ let uU = alpha * sqrt(2.0 / (1.0 + da * da));
145
+ return max(vec2f(rf), vec2f(uU, da * uU));
145
146
  }
146
147
 
147
- fn kV(instanceIndex: i32) -> vec3f {
148
+ fn lO(instanceIndex: i32) -> vec3f {
148
149
  if (instanceIndex < 0) { return vec3f(1.0); }
149
150
  return instancesBuffer[instanceIndex * ${INSTANCE_VEC4_STRIDE} + 9].xyz;
150
151
  }
@@ -230,11 +231,11 @@ if (USE_METALLIC_ROUGHNESS_MAPS) {
230
231
 
231
232
  let mrtMapIndex = i32(matData.mrtMapIndex);
232
233
  if (mrtMapIndex >= 0) {
233
- let fO = sampleMap(
234
+ let ga = sampleMap(
234
235
  mrtMapIndex, getMapUvSet(mrtMapIndex, uv, uv1)
235
236
  );
236
- (*ma).baseMetalness *= fO.b;
237
- (*ma).specularRoughness *= fO.g;
237
+ (*ma).baseMetalness *= ga.b;
238
+ (*ma).specularRoughness *= ga.g;
238
239
  }
239
240
  }
240
241
 
@@ -267,16 +268,16 @@ ${hasAnisotropyDirections ? /* wgsl */ `
267
268
  (*ma).coatAnisotropyRotation = matData.coatAnisotropyRotation;
268
269
  if (USE_ANISOTROPY_MAPS && matData.anisotropyMapIndex >= 0.0) {
269
270
  let index = i32(matData.anisotropyMapIndex);
270
- let cR = sampleMap(index, getMapUvSet(index, uv, uv1));
271
- (*ma).specularAnisotropy *= cR.b;
272
- let direction = cR.rg * 2.0 - 1.0;
271
+ let texel = sampleMap(index, getMapUvSet(index, uv, uv1));
272
+ (*ma).specularAnisotropy *= texel.b;
273
+ let direction = texel.rg * 2.0 - 1.0;
273
274
  if (dot(direction, direction) > 1e-4) { (*ma).anisotropyDirection = normalize(direction); }
274
275
  (*ma).anisotropyDirectionEnabled = true;
275
276
  }
276
277
  if (matData.specularAnisotropyModel > 0.5 && (*ma).specularAnisotropy > 0.0) {
277
- let tX = fb(clamp((*ma).specularRoughness, 0.0, 1.0), (*ma).specularAnisotropy);
278
- (*ma).specularRoughness = tX.x;
279
- (*ma).specularAnisotropy = tX.y;
278
+ let vG = fl(clamp((*ma).specularRoughness, 0.0, 1.0), (*ma).specularAnisotropy);
279
+ (*ma).specularRoughness = vG.x;
280
+ (*ma).specularAnisotropy = vG.y;
280
281
  }
281
282
  if ((*ma).anisotropyDirectionEnabled) {
282
283
  let theta = matData.specularAnisotropyRotation;
@@ -288,14 +289,14 @@ let d = (*ma).anisotropyDirection;
288
289
 
289
290
 
290
291
  if ((*ma).coatWeight > 0.0 && (*ma).coatRoughness > 0.0) {
291
- let hJ = (*ma).specularRoughness * (*ma).specularRoughness;
292
- let hK = (*ma).coatRoughness * (*ma).coatRoughness;
292
+ let im = (*ma).specularRoughness * (*ma).specularRoughness;
293
+ let iq = (*ma).coatRoughness * (*ma).coatRoughness;
293
294
  (*ma).specularRoughness = mix((*ma).specularRoughness,
294
- pow(min(1.0, hJ * hJ + 2.0 * hK * hK), 0.25), (*ma).coatWeight);
295
+ pow(min(1.0, im * im + 2.0 * iq * iq), 0.25), (*ma).coatWeight);
295
296
  }
296
297
  ${hasTransmission ? '' : /* wgsl */ `(*ma).transmissionWeight = 0.0;`}
297
298
  ${hasMetalness ? '' : /* wgsl */ `(*ma).baseMetalness = 0.0;`}
298
- let color = kV(instanceIndex) * vertexColor;
299
+ let color = lO(instanceIndex) * vertexColor;
299
300
  (*ma).baseColor *= color;
300
301
  if ((*ma).materialType == UNLIT) { (*ma).emission *= color; }
301
302
 
@@ -308,39 +309,39 @@ let specularAlpha = aL((*ma).specularRoughness, (*ma).specularAnisotropy);
308
309
  (*ma).alphaY = specularAlpha.y;
309
310
  }
310
311
 
311
- fn oS(materialIndex: i32, uv: vec2f, normal: vec3f, dp1: vec3f, dp2: vec3f, oM: vec2f, oN: vec2f) -> vec3f {
312
+ fn qa(materialIndex: i32, uv: vec2f, normal: vec3f, dp1: vec3f, dp2: vec3f, pU: vec2f, pV: vec2f) -> vec3f {
312
313
  let matData = materialsBuffer[materialIndex];
313
314
  let normalMapIndex = i32(matData.normalMapIndex);
314
315
  if (normalMapIndex >= 0) {
315
316
 
316
317
 
317
318
 
318
- let rX = cross(dp2, normal);
319
- let rW = cross(normal, dp1);
320
- var dpdu = rX * oM.x + rW * oN.x;
321
- var tI = rX * oM.y + rW * oN.y;
322
- let dT = max(dot(dpdu, dpdu), dot(tI, tI));
323
- if (dT > 1e-12) {
324
- let tQ = inverseSqrt(dT);
325
- dpdu *= tQ;
326
- tI *= tQ;
319
+ let tu = cross(dp2, normal);
320
+ let tq = cross(normal, dp1);
321
+ var dpdu = tu * pU.x + tq * pV.x;
322
+ var vl = tu * pU.y + tq * pV.y;
323
+ let dZ = max(dot(dpdu, dpdu), dot(vl, vl));
324
+ if (dZ > 1e-12) {
325
+ let vw = inverseSqrt(dZ);
326
+ dpdu *= vw;
327
+ vl *= vw;
327
328
  }
328
329
  else {
329
330
 
330
331
 
331
- let ob = select(
332
+ let pa = select(
332
333
  vec3f(0.0, 1.0, 0.0),
333
334
  vec3f(0.0, 0.0, 1.0),
334
335
  abs(normal.z) < 0.999
335
336
  );
336
- dpdu = normalize(cross(ob, normal));
337
- tI = cross(normal, dpdu);
337
+ dpdu = normalize(cross(pa, normal));
338
+ vl = cross(normal, dpdu);
338
339
  }
339
340
 
340
341
  var n = 2.0 * sampleMap(normalMapIndex, uv).rgb - 1.0;
341
342
  n = normalize(vec3(n.xy * matData.normalMapScale, n.z));
342
343
 
343
- let tbn = mat3x3(dpdu, tI, normal);
344
+ let tbn = mat3x3(dpdu, vl, normal);
344
345
 
345
346
  return normalize(tbn * n);
346
347
  } else {
@@ -1 +1 @@
1
- {"version":3,"file":"materialBuffer.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/materialBuffer.wgsl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,OAAO,EACL,0BAA0B,EAC3B,MAAM,4BAA4B,CAAC;AAEpC,MAAM,UAAU,wBAAwB,CAAC,EACvC,uBAAuB,GAAG,IAAI,EAC9B,cAAc,GAAG,KAAK,EACtB,aAAa,GAAG,IAAI,EACpB,eAAe,GAAG,IAAI,EAAE,QAAQ,GAAG,KAAK,EACxC,YAAY,GAAG,IAAI,KAOjB,EAAE;IACJ,MAAM,mBAAmB,GAAG,aAAa;QACvC,CAAC,CAAC,2CAA2C;QAC7C,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,mBAAmB,GAAG,aAAa;QACvC,CAAC,CAAC,UAAU,CAAC;yBACU,0BAA0B,CAAC,MAAM;;;8BAG5B,0BAA0B,CAAC,IAAI;;EAE3D;QACA,CAAC,CAAC,oBAAoB,CAAC;IAEzB,OAAO,UAAU,CAAC;;EAElB,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;;;CAOtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAuH0B,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+B3D,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAkCc,sBAAsB,CAAC,YAAY;;;oCAG9B,sBAAsB,CAAC,KAAK;;;;;;EAMlE,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC;;EAEvC,mBAAmB;;EAEnB,mBAAmB,CAAC,iBAAiB,EAAE,MAAM,CAAC;;;;;;;;;;;;;;EAc9C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,qBAAqB,CAAC,MAAM,CAAC;;EAE7B,mBAAmB,CAAC,eAAe,EAAE,MAAM,CAAC;;EAE9C,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;;CAG7B,CAAC,CAAC,CAAC,EAAE;;EAEF,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;;EAEjD,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;CAuBtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;;;;;;;;;EASb,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,iCAAiC;EACnE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,4BAA4B;;;;;EAK7D,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;;CAEvB,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CL,CAAC;AACF,CAAC;AAED,MAAM,kBAAkB,GAAG,wBAAwB,EAAE,CAAC;AAEtD,eAAe,kBAAkB,CAAC","sourcesContent":["import { simpleTextureSample, thinFilmTextureSample } from '../../materialTextureSlots.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 {\n materialAlphaModeConstants\n} from '../../materialConstants.js';\n\nexport function createMaterialBufferWgsl({\n hasAnisotropyDirections = true,\n hasCoatNormals = false,\n hasSceneAlpha = true,\n hasTransmission = true, caustics = false,\n hasMetalness = true\n}: {\n hasSceneAlpha?: boolean;\n hasAnisotropyDirections?: boolean;\n hasCoatNormals?: boolean;\n hasTransmission?: boolean; caustics?: boolean;\n hasMetalness?: boolean;\n} = {}) {\n const alphaModeAssignment = hasSceneAlpha\n ? '(*ma).alphaMode = i32(matData.alphaMode);'\n : '';\n const alphaModeResolution = hasSceneAlpha\n ? /* wgsl */ `\n if ((*ma).alphaMode == ${materialAlphaModeConstants.opaque}) {\n (*ma).alpha = 1.0;\n }\n else if ((*ma).alphaMode == ${materialAlphaModeConstants.mask}) {\n (*ma).alpha = select(0.0, 1.0, (*ma).alpha >= matData.alphaCutoff);\n }`\n : '(*ma).alpha = 1.0;';\n\n return /* wgsl */ `\n\n${hasAnisotropyDirections ? /* wgsl */ `fn gltf_anisotropy_to_openpbr(roughness: f32, strength: f32) -> vec2f {\n if (strength == 0.0) { return vec2f(roughness, 0.0); }\n let u = roughness * roughness;\n let a = u + (1.0 - u) * strength * strength;\n if (a == 0.0) { return vec2f(0.0); }\n return vec2f(pow((a*a + u*u) * 0.5, 0.25), clamp(1.0 - u/a, 0.0, 1.0));\n}\n` : /* wgsl */ ``}\n\nfn sRGBToLinear(c: vec3f) -> vec3f {\n return mix(pow(c * 0.9478672986 + 0.0521327014, vec3f(2.4)), c * 0.0773993808, vec3f(c < vec3f(0.04045)));\n}\n\nfn decodeMapColor(idx: i32, c: vec3f) -> vec3f {\n if (mapInfo[idx + NUM_MAPS * 2].y > 0.5) { return c; }\n return sRGBToLinear(c);\n}\n\nfn unpackMaterialIndex(val: i32) -> vec2f {\n return vec2f(f32(val >> 8), f32(val & 0xff) / 255.0);\n}\n\nfn getMapSize(idx: i32) -> vec2f {\n return mapInfo[idx].xy;\n}\n\nfn getMapLayer(idx: i32) -> i32 {\n return i32(floor(mapInfo[idx].z));\n}\n\nfn getMapOffset(idx: i32) -> vec2f {\n return vec2f(fract(mapInfo[idx].z), mapInfo[idx].w);\n}\n\nfn wrapMapCoordinate(value: f32, mode: f32) -> f32 {\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\nfn wrappedMapUv(idx: i32, uv: vec2f) -> vec2f {\n let transform = mapInfo[idx + NUM_MAPS];\n let modes = mapInfo[idx + NUM_MAPS * 2].zw;\n let value = uv * transform.xy + transform.zw;\n return vec2f(wrapMapCoordinate(value.x, modes.x), wrapMapCoordinate(value.y, modes.y));\n}\n\nfn getMapUV(idx: i32, uv: vec2f) -> vec2f {\n let repeatedUv = wrappedMapUv(idx, uv);\n let atlasTexel = 1.0 / vec2f(textureDimensions(map).xy);\n let firstTexelCenter = getMapOffset(idx);\n let sourceExtent = getMapSize(idx) + atlasTexel;\n let sourceOrigin = firstTexelCenter - 0.5 * atlasTexel;\n let lastTexelCenter = firstTexelCenter + sourceExtent - atlasTexel;\n return clamp(\n sourceOrigin + repeatedUv * sourceExtent,\n firstTexelCenter,\n lastTexelCenter\n );\n}\n\nfn getMapUvSet(idx: i32, uv: vec2f, uv1: vec2f) -> vec2f {\n return select(uv, uv1, mapInfo[idx + NUM_MAPS * 2].x > 0.5);\n}\n\nfn sampleMap(idx: i32, uv: vec2f) -> vec4f {\n let size = vec2i(round(getMapSize(idx) * vec2f(textureDimensions(map).xy) + vec2f(1.0)));\n let texel = wrappedMapUv(idx, uv) * vec2f(size) - vec2f(0.5);\n let modes = mapInfo[idx + NUM_MAPS * 2].zw;\n // Repeat filtering must cross the logical image boundary, never another\n // atlas placement. Interior/clamped/mirrored footprints use hardware filtering.\n if ((size.x > 1 && modes.x < 0.5 && (texel.x < 0.0 || texel.x > f32(size.x - 1))) ||\n (size.y > 1 && modes.y < 0.5 && (texel.y < 0.0 || texel.y > f32(size.y - 1)))) {\n let base = vec2i(floor(texel));\n let weight = fract(texel);\n let origin = vec2i(round(getMapOffset(idx) * vec2f(textureDimensions(map).xy) - vec2f(0.5)));\n return mix(\n mix(loadMapTexel(idx, base, size, origin, modes), loadMapTexel(idx, base + vec2i(1, 0), size, origin, modes), weight.x),\n mix(loadMapTexel(idx, base + vec2i(0, 1), size, origin, modes), loadMapTexel(idx, base + vec2i(1, 1), size, origin, modes), weight.x), weight.y);\n }\n return textureSampleLevel(map, mapSampler, getMapUV(idx, uv), getMapLayer(idx), 0.0);\n}\n\nfn loadMapTexel(idx: i32, coordinate: vec2i, size: vec2i, origin: vec2i, modes: vec2f) -> vec4f {\n var p = clamp(coordinate, vec2i(0), size - vec2i(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 textureLoad(map, origin + p, getMapLayer(idx), 0);\n}\n\n\nfn getMaterialEmission(materialIndex: i32, uv: vec2f, uv1: vec2f) -> vec3f {\n let matData = materialsBuffer[materialIndex];\n var emission = matData.emission;\n if (USE_EMISSIVE_MAPS) {\n let emissiveMapIndex = i32(matData.emissiveMapIndex);\n if (emissiveMapIndex >= 0) {\n emission *= decodeMapColor(emissiveMapIndex, sampleMap(\n emissiveMapIndex, getMapUvSet(emissiveMapIndex, uv, uv1)\n ).rgb);\n }\n }\n if (USE_COAT_WEIGHT_MAPS && matData.matType == 0.0) {\n let coatWeightMapIndex = i32(matData.coatWeightMapIndex);\n if (coatWeightMapIndex >= 0) {\n let coatWeight = clamp(matData.coatWeight, 0.0, 1.0) * sampleMap(\n coatWeightMapIndex, getMapUvSet(coatWeightMapIndex, uv, uv1)\n ).r;\n emission *= mix(vec3f(1.0), sqrt(max(matData.coatColor, vec3f(0.0))), coatWeight);\n }\n }\n return emission;\n}\n\n// OpenPBR 1.1.1: RMS-preserving GGX anisotropy, shared by base and coat.\nfn openpbr_roughness_to_alpha(roughness: f32, anisotropy: f32) -> vec2f {\n let alpha = roughness * roughness;\n let alphaMin = ROUGHNESS_MIN * ROUGHNESS_MIN;\n if (anisotropy == 0.0) { return vec2f(max(alphaMin, alpha)); }\n let complement = 1.0 - anisotropy;\n let alphaT = alpha * sqrt(2.0 / (1.0 + complement * complement));\n return max(vec2f(alphaMin), vec2f(alphaT, complement * alphaT));\n}\n\nfn getInstanceColor(instanceIndex: i32) -> vec3f {\n if (instanceIndex < 0) { return vec3f(1.0); }\n return instancesBuffer[instanceIndex * ${INSTANCE_VEC4_STRIDE} + 9].xyz;\n}\n\nfn getMaterial(\n ma: ptr<function, OpenPbrResolvedMaterial>,\n materialIndex: i32,\n uv: vec2f,\n uv1: vec2f,\n instanceIndex: i32,\n vertexColor: vec3f\n) {\n let matData = materialsBuffer[materialIndex];\n\n (*ma).baseColor = matData.color;\n (*ma).materialType = i32(matData.matType);\n (*ma).specularRoughness = matData.roughness;\n (*ma).baseMetalness = matData.metallic;\n (*ma).specularAnisotropy = clamp(matData.anisotropy, 0.0, 1.0);\n (*ma).emission = getMaterialEmission(materialIndex, uv, uv1);\n (*ma).inside = false;\n (*ma).specularIor = matData.ior;\n (*ma).transmissionWeight = matData.transmission;\n (*ma).thinWalled = matData.thin > 0.5;\n (*ma).bevel = matData.bevel;\n (*ma).transmissionDispersionScale = matData.dispersion;\n (*ma).dispersionAbbeNumber = max(matData.dispersionAbbeNumber, 1e-6);\n (*ma).mediumExtinction = max(matData.mediumExtinction, vec3f(0.0));\n (*ma).mediumScattering = max(matData.mediumScattering, vec3f(0.0));\n (*ma).mediumAnisotropy = clamp(matData.mediumAnisotropy, -1.0, 1.0);\n (*ma).mediumType = select(0, 1, max(max((*ma).mediumExtinction.x, (*ma).mediumExtinction.y), (*ma).mediumExtinction.z) > 0.0);\n (*ma).alpha = matData.alpha;\n ${alphaModeAssignment}\n\n (*ma).thinFilmThickness = matData.thinFilmThickness * 1000.0;\n (*ma).thinFilmIor = matData.thinFilmIor;\n (*ma).thinFilmWeight = select(0.0, clamp(matData.thinFilmWeight, 0.0, 1.0), HAS_THIN_FILM);\n (*ma).baseWeight = clamp(matData.baseWeight, 0.0, 1.0);\n (*ma).diffuseRoughness = clamp(matData.baseDiffuseRoughness, 0.0, 1.0);\n (*ma).specularWeight = max(matData.specularWeight, 0.0);\n (*ma).specularColor = max(matData.specularColor, vec3f(0.0));\n (*ma).subsurfaceWeight = select(0.0, clamp(matData.subsurfaceWeight, 0.0, 1.0), HAS_SUBSURFACE);\n (*ma).subsurfaceColor = max(matData.subsurfaceColor, vec3f(0.0));\n (*ma).transmissionColor = max(matData.transmissionColor, vec3f(0.0));\n (*ma).fuzzWeight = select(0.0, clamp(matData.fuzzWeight, 0.0, 1.0), HAS_FUZZ);\n (*ma).fuzzColor = max(matData.fuzzColor, vec3f(0.0));\n (*ma).fuzzRoughness = clamp(matData.fuzzRoughness, 0.0, 1.0);\n (*ma).coatWeight = select(0.0, clamp(matData.coatWeight, 0.0, 1.0), HAS_COAT);\n (*ma).coatColor = max(matData.coatColor, vec3f(0.0));\n (*ma).coatRoughness = clamp(matData.coatRoughness, ROUGHNESS_MIN, 1.0);\n (*ma).coatAnisotropy = clamp(matData.coatAnisotropy, 0.0, 1.0);\n (*ma).coatIor = max(matData.coatIor, 1.0);\n (*ma).coatDarkening = clamp(matData.coatDarkening, 0.0, 1.0);\n\n if (USE_DIFFUSE_MAPS) {\n let diffuseMapIndex = i32(matData.diffuseMapIndex);\n if (diffuseMapIndex >= 0) {\n // TODO textureSample is not supported in compute shader.\n let 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 (*ma).baseColor *= decodeMapColor(diffuseMapIndex, diffuse.rgb);\n\n // Map alpha to transmission\n if (matData.mapAlphaUsage == ${mapAlphaUsageConstants.transmission}) {\n (*ma).transmissionWeight = 1.0 - diffuse.a;\n }\n else if (matData.mapAlphaUsage == ${mapAlphaUsageConstants.alpha}) {\n (*ma).alpha *= diffuse.a;\n }\n }\n }\n\n ${simpleTextureSample('alphaMap', 'wgsl')}\n\n ${alphaModeResolution}\n\n ${simpleTextureSample('transmissionMap', 'wgsl')}\n\n if (USE_METALLIC_ROUGHNESS_MAPS) {\n // Metallic roughness transmission map index\n let mrtMapIndex = i32(matData.mrtMapIndex);\n if (mrtMapIndex >= 0) {\n let metallicRoughness = sampleMap(\n mrtMapIndex, getMapUvSet(mrtMapIndex, uv, uv1)\n );\n (*ma).baseMetalness *= metallicRoughness.b;\n (*ma).specularRoughness *= metallicRoughness.g;\n }\n }\n\n ${simpleTextureSample('roughnessMap', 'wgsl')}\n\n ${simpleTextureSample('metalnessMap', 'wgsl')}\n\n ${thinFilmTextureSample('wgsl')}\n\n ${simpleTextureSample('coatWeightMap', 'wgsl')}\n\n${hasCoatNormals ? /* wgsl */ `\n // Independent coat shading also applies when the coat has no normal map.\n (*ma).coatNormalEnabled = (*ma).coatWeight > 0.0 && (matData.normalMapIndex >= 0.0 || matData.coatNormalMapIndex >= 0.0);\n` : ''}\n\n ${simpleTextureSample('coatRoughnessMap', 'wgsl')}\n\n ${simpleTextureSample('fuzzColorMap', 'wgsl')}\n\n ${simpleTextureSample('fuzzRoughnessMap', 'wgsl')}\n\n ${simpleTextureSample('specularWeightMap', 'wgsl')}\n\n ${simpleTextureSample('specularColorMap', 'wgsl')}\n\n${hasAnisotropyDirections ? /* wgsl */ `\n (*ma).anisotropyDirection = vec2f(1.0, 0.0);\n (*ma).anisotropyDirectionEnabled = matData.specularAnisotropyRotation != 0.0;\n (*ma).coatAnisotropyRotation = matData.coatAnisotropyRotation;\n if (USE_ANISOTROPY_MAPS && matData.anisotropyMapIndex >= 0.0) {\n let index = i32(matData.anisotropyMapIndex);\n let texel = sampleMap(index, getMapUvSet(index, uv, uv1));\n (*ma).specularAnisotropy *= texel.b;\n let direction = texel.rg * 2.0 - 1.0;\n if (dot(direction, direction) > 1e-4) { (*ma).anisotropyDirection = normalize(direction); }\n (*ma).anisotropyDirectionEnabled = true;\n }\n if (matData.specularAnisotropyModel > 0.5 && (*ma).specularAnisotropy > 0.0) {\n let native = gltf_anisotropy_to_openpbr(clamp((*ma).specularRoughness, 0.0, 1.0), (*ma).specularAnisotropy);\n (*ma).specularRoughness = native.x;\n (*ma).specularAnisotropy = native.y;\n }\n if ((*ma).anisotropyDirectionEnabled) {\n let theta = matData.specularAnisotropyRotation;\n let d = (*ma).anisotropyDirection;\n (*ma).anisotropyDirection = vec2f(cos(theta)*d.x - sin(theta)*d.y, sin(theta)*d.x + cos(theta)*d.y);\n }\n\n` : /* wgsl */ ``}\n // OpenPBR 1.1.1: coat refraction broadens all base microfacet lobes.\n // Keep the zero-coat / smooth-coat paths byte-identical.\n if ((*ma).coatWeight > 0.0 && (*ma).coatRoughness > 0.0) {\n let baseRoughness2 = (*ma).specularRoughness * (*ma).specularRoughness;\n let coatRoughness2 = (*ma).coatRoughness * (*ma).coatRoughness;\n (*ma).specularRoughness = mix((*ma).specularRoughness,\n pow(min(1.0, baseRoughness2 * baseRoughness2 + 2.0 * coatRoughness2 * coatRoughness2), 0.25), (*ma).coatWeight);\n }\n ${hasTransmission ? '' : /* wgsl */ `(*ma).transmissionWeight = 0.0;`}\n ${hasMetalness ? '' : /* wgsl */ `(*ma).baseMetalness = 0.0;`}\n let color = getInstanceColor(instanceIndex) * vertexColor;\n (*ma).baseColor *= color;\n if ((*ma).materialType == UNLIT) { (*ma).emission *= color; }\n\n${caustics ? /* wgsl */ ` (*ma).causticRoughness = (*ma).specularRoughness;\n (*ma).causticNormalMapped = matData.normalMapIndex >= 0.0;\n` : ''} (*ma).specularRoughness = clamp((*ma).specularRoughness, ROUGHNESS_MIN, 1.0);\n (*ma).baseMetalness = clamp((*ma).baseMetalness, 0.0, 1.0);\n let specularAlpha = openpbr_roughness_to_alpha((*ma).specularRoughness, (*ma).specularAnisotropy);\n (*ma).alphaX = specularAlpha.x;\n (*ma).alphaY = specularAlpha.y;\n}\n\nfn getMatNormal(materialIndex: i32, uv: vec2f, normal: vec3f, dp1: vec3f, dp2: vec3f, duv1: vec2f, duv2: vec2f) -> vec3f {\n let matData = materialsBuffer[materialIndex];\n let normalMapIndex = i32(matData.normalMapIndex);\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 let dp2perp = cross(dp2, normal);\n let dp1perp = cross(normal, dp1);\n var dpdu = dp2perp * duv1.x + dp1perp * duv2.x;\n var dpdv = dp2perp * duv1.y + dp1perp * duv2.y;\n let gradientLengthSquared = max(dot(dpdu, dpdu), dot(dpdv, dpdv));\n if (gradientLengthSquared > 1e-12) {\n let invmax = inverseSqrt(gradientLengthSquared);\n dpdu *= invmax;\n dpdv *= invmax;\n }\n else {\n // Generated/triplanar UVs have no per-vertex UV derivatives. Build a\n // stable fallback basis instead of normalizing two zero vectors.\n let referenceAxis = select(\n vec3f(0.0, 1.0, 0.0),\n vec3f(0.0, 0.0, 1.0),\n abs(normal.z) < 0.999\n );\n dpdu = normalize(cross(referenceAxis, normal));\n dpdv = cross(normal, dpdu);\n }\n\n var n = 2.0 * sampleMap(normalMapIndex, uv).rgb - 1.0;\n n = normalize(vec3(n.xy * matData.normalMapScale, n.z));\n\n let tbn = mat3x3(dpdu, dpdv, normal);\n\n return normalize(tbn * n);\n } else {\n return normal;\n }\n}\n`;\n}\n\nconst materialBufferWgsl = createMaterialBufferWgsl();\n\nexport default materialBufferWgsl;\n"]}
1
+ {"version":3,"file":"materialBuffer.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/materialBuffer.wgsl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,OAAO,EACL,0BAA0B,EAC3B,MAAM,4BAA4B,CAAC;AAEpC,MAAM,UAAU,wBAAwB,CAAC,EACvC,mBAAmB,GAAG,KAAK,EAC3B,uBAAuB,GAAG,IAAI,EAC9B,cAAc,GAAG,KAAK,EACtB,aAAa,GAAG,IAAI,EACpB,eAAe,GAAG,IAAI,EAAE,QAAQ,GAAG,KAAK,EACxC,YAAY,GAAG,IAAI,KAQjB,EAAE;IACJ,MAAM,mBAAmB,GAAG,aAAa;QACvC,CAAC,CAAC,2CAA2C;QAC7C,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,mBAAmB,GAAG,aAAa;QACvC,CAAC,CAAC,UAAU,CAAC;yBACU,0BAA0B,CAAC,MAAM;;;8BAG5B,0BAA0B,CAAC,IAAI;;EAE3D;QACA,CAAC,CAAC,oBAAoB,CAAC;IAEzB,OAAO,UAAU,CAAC;;EAElB,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;;;CAOtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCf,mBAAmB,CAAC,CAAC,CAAC;yCAC2C,CAAC,CAAC,CAAC;;;;;;;;;;GAUjE;;;;;;;;aAQU,mBAAmB,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,+EAA+E;;;;;;;;;eAS5H,mBAAmB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,iFAAiF;;;;;SAK5H,mBAAmB,CAAC,CAAC,CAAC,+EAA+E,CAAC,CAAC,CAAC,+EAA+E;;;;;;;SAOvL,mBAAmB,CAAC,CAAC,CAAC,0CAA0C,CAAC,CAAC,CAAC,mDAAmD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAuCtF,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+B3D,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAkCc,sBAAsB,CAAC,YAAY;;;oCAG9B,sBAAsB,CAAC,KAAK;;;;;;EAMlE,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC;;EAEvC,mBAAmB;;EAEnB,mBAAmB,CAAC,iBAAiB,EAAE,MAAM,CAAC;;;;;;;;;;;;;;EAc9C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,qBAAqB,CAAC,MAAM,CAAC;;EAE7B,mBAAmB,CAAC,eAAe,EAAE,MAAM,CAAC;;EAE9C,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;;CAG7B,CAAC,CAAC,CAAC,EAAE;;EAEF,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;;EAEjD,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;CAuBtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;;;;;;;;;EASb,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,iCAAiC;EACnE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,4BAA4B;;;;;EAK7D,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;;CAEvB,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CL,CAAC;AACF,CAAC;AAED,MAAM,kBAAkB,GAAG,wBAAwB,EAAE,CAAC;AAEtD,eAAe,kBAAkB,CAAC","sourcesContent":["import { simpleTextureSample, thinFilmTextureSample } from '../../materialTextureSlots.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 {\n materialAlphaModeConstants\n} from '../../materialConstants.js';\n\nexport function createMaterialBufferWgsl({\n independentTextures = false,\n hasAnisotropyDirections = true,\n hasCoatNormals = false,\n hasSceneAlpha = true,\n hasTransmission = true, caustics = false,\n hasMetalness = true\n}: {\n independentTextures?: boolean;\n hasSceneAlpha?: boolean;\n hasAnisotropyDirections?: boolean;\n hasCoatNormals?: boolean;\n hasTransmission?: boolean; caustics?: boolean;\n hasMetalness?: boolean;\n} = {}) {\n const alphaModeAssignment = hasSceneAlpha\n ? '(*ma).alphaMode = i32(matData.alphaMode);'\n : '';\n const alphaModeResolution = hasSceneAlpha\n ? /* wgsl */ `\n if ((*ma).alphaMode == ${materialAlphaModeConstants.opaque}) {\n (*ma).alpha = 1.0;\n }\n else if ((*ma).alphaMode == ${materialAlphaModeConstants.mask}) {\n (*ma).alpha = select(0.0, 1.0, (*ma).alpha >= matData.alphaCutoff);\n }`\n : '(*ma).alpha = 1.0;';\n\n return /* wgsl */ `\n\n${hasAnisotropyDirections ? /* wgsl */ `fn gltf_anisotropy_to_openpbr(roughness: f32, strength: f32) -> vec2f {\n if (strength == 0.0) { return vec2f(roughness, 0.0); }\n let u = roughness * roughness;\n let a = u + (1.0 - u) * strength * strength;\n if (a == 0.0) { return vec2f(0.0); }\n return vec2f(pow((a*a + u*u) * 0.5, 0.25), clamp(1.0 - u/a, 0.0, 1.0));\n}\n` : /* wgsl */ ``}\n\nfn sRGBToLinear(c: vec3f) -> vec3f {\n return mix(pow(c * 0.9478672986 + 0.0521327014, vec3f(2.4)), c * 0.0773993808, vec3f(c < vec3f(0.04045)));\n}\n\nfn decodeMapColor(idx: i32, c: vec3f) -> vec3f {\n if (mapInfo[idx + NUM_MAPS * 2].y > 0.5) { return c; }\n return sRGBToLinear(c);\n}\n\nfn unpackMaterialIndex(val: i32) -> vec2f {\n return vec2f(f32(val >> 8), f32(val & 0xff) / 255.0);\n}\n\nfn getMapSize(idx: i32) -> vec2f {\n return mapInfo[idx].xy;\n}\n\nfn getMapLayer(idx: i32) -> i32 {\n return i32(floor(mapInfo[idx].z));\n}\n\nfn getMapOffset(idx: i32) -> vec2f {\n return vec2f(fract(mapInfo[idx].z), mapInfo[idx].w);\n}\n\nfn wrapMapCoordinate(value: f32, mode: f32) -> f32 {\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\nfn wrappedMapUv(idx: i32, uv: vec2f) -> vec2f {\n let transform = mapInfo[idx + NUM_MAPS];\n let modes = mapInfo[idx + NUM_MAPS * 2].zw;\n let value = uv * transform.xy + transform.zw;\n return vec2f(wrapMapCoordinate(value.x, modes.x), wrapMapCoordinate(value.y, modes.y));\n}\n\nfn getMapUV(idx: i32, uv: vec2f) -> vec2f {\n${independentTextures ? ` let halfTexel = 0.5 / getMapSize(idx);\n return clamp(wrappedMapUv(idx, uv), halfTexel, 1.0 - halfTexel);` : ` let repeatedUv = wrappedMapUv(idx, uv);\n let atlasTexel = 1.0 / vec2f(textureDimensions(map).xy);\n let firstTexelCenter = getMapOffset(idx);\n let sourceExtent = getMapSize(idx) + atlasTexel;\n let sourceOrigin = firstTexelCenter - 0.5 * atlasTexel;\n let lastTexelCenter = firstTexelCenter + sourceExtent - atlasTexel;\n return clamp(\n sourceOrigin + repeatedUv * sourceExtent,\n firstTexelCenter,\n lastTexelCenter\n );`}\n}\n\nfn getMapUvSet(idx: i32, uv: vec2f, uv1: vec2f) -> vec2f {\n return select(uv, uv1, mapInfo[idx + NUM_MAPS * 2].x > 0.5);\n}\n\nfn sampleMap(idx: i32, uv: vec2f) -> vec4f {\n let size = ${independentTextures ? 'vec2i(getMapSize(idx))' : 'vec2i(round(getMapSize(idx) * vec2f(textureDimensions(map).xy) + vec2f(1.0)))'};\n let texel = wrappedMapUv(idx, uv) * vec2f(size) - vec2f(0.5);\n let modes = mapInfo[idx + NUM_MAPS * 2].zw;\n // Repeat filtering must cross the logical image boundary, never another\n // atlas placement. Interior/clamped/mirrored footprints use hardware filtering.\n if ((size.x > 1 && modes.x < 0.5 && (texel.x < 0.0 || texel.x > f32(size.x - 1))) ||\n (size.y > 1 && modes.y < 0.5 && (texel.y < 0.0 || texel.y > f32(size.y - 1)))) {\n let base = vec2i(floor(texel));\n let weight = fract(texel);\n let origin = ${independentTextures ? 'vec2i(0)' : 'vec2i(round(getMapOffset(idx) * vec2f(textureDimensions(map).xy) - vec2f(0.5)))'};\n return mix(\n mix(loadMapTexel(idx, base, size, origin, modes), loadMapTexel(idx, base + vec2i(1, 0), size, origin, modes), weight.x),\n mix(loadMapTexel(idx, base + vec2i(0, 1), size, origin, modes), loadMapTexel(idx, base + vec2i(1, 1), size, origin, modes), weight.x), weight.y);\n }\n return ${independentTextures ? 'textureSampleLevel(map[getMapLayer(idx)], mapSampler, getMapUV(idx, uv), 0.0)' : 'textureSampleLevel(map, mapSampler, getMapUV(idx, uv), getMapLayer(idx), 0.0)'};\n}\n\nfn loadMapTexel(idx: i32, coordinate: vec2i, size: vec2i, origin: vec2i, modes: vec2f) -> vec4f {\n var p = clamp(coordinate, vec2i(0), size - vec2i(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 ${independentTextures ? 'textureLoad(map[getMapLayer(idx)], p, 0)' : 'textureLoad(map, origin + p, getMapLayer(idx), 0)'};\n}\n\n\nfn getMaterialEmission(materialIndex: i32, uv: vec2f, uv1: vec2f) -> vec3f {\n let matData = materialsBuffer[materialIndex];\n var emission = matData.emission;\n if (USE_EMISSIVE_MAPS) {\n let emissiveMapIndex = i32(matData.emissiveMapIndex);\n if (emissiveMapIndex >= 0) {\n emission *= decodeMapColor(emissiveMapIndex, sampleMap(\n emissiveMapIndex, getMapUvSet(emissiveMapIndex, uv, uv1)\n ).rgb);\n }\n }\n if (USE_COAT_WEIGHT_MAPS && matData.matType == 0.0) {\n let coatWeightMapIndex = i32(matData.coatWeightMapIndex);\n if (coatWeightMapIndex >= 0) {\n let coatWeight = clamp(matData.coatWeight, 0.0, 1.0) * sampleMap(\n coatWeightMapIndex, getMapUvSet(coatWeightMapIndex, uv, uv1)\n ).r;\n emission *= mix(vec3f(1.0), sqrt(max(matData.coatColor, vec3f(0.0))), coatWeight);\n }\n }\n return emission;\n}\n\n// OpenPBR 1.1.1: RMS-preserving GGX anisotropy, shared by base and coat.\nfn openpbr_roughness_to_alpha(roughness: f32, anisotropy: f32) -> vec2f {\n let alpha = roughness * roughness;\n let alphaMin = ROUGHNESS_MIN * ROUGHNESS_MIN;\n if (anisotropy == 0.0) { return vec2f(max(alphaMin, alpha)); }\n let complement = 1.0 - anisotropy;\n let alphaT = alpha * sqrt(2.0 / (1.0 + complement * complement));\n return max(vec2f(alphaMin), vec2f(alphaT, complement * alphaT));\n}\n\nfn getInstanceColor(instanceIndex: i32) -> vec3f {\n if (instanceIndex < 0) { return vec3f(1.0); }\n return instancesBuffer[instanceIndex * ${INSTANCE_VEC4_STRIDE} + 9].xyz;\n}\n\nfn getMaterial(\n ma: ptr<function, OpenPbrResolvedMaterial>,\n materialIndex: i32,\n uv: vec2f,\n uv1: vec2f,\n instanceIndex: i32,\n vertexColor: vec3f\n) {\n let matData = materialsBuffer[materialIndex];\n\n (*ma).baseColor = matData.color;\n (*ma).materialType = i32(matData.matType);\n (*ma).specularRoughness = matData.roughness;\n (*ma).baseMetalness = matData.metallic;\n (*ma).specularAnisotropy = clamp(matData.anisotropy, 0.0, 1.0);\n (*ma).emission = getMaterialEmission(materialIndex, uv, uv1);\n (*ma).inside = false;\n (*ma).specularIor = matData.ior;\n (*ma).transmissionWeight = matData.transmission;\n (*ma).thinWalled = matData.thin > 0.5;\n (*ma).bevel = matData.bevel;\n (*ma).transmissionDispersionScale = matData.dispersion;\n (*ma).dispersionAbbeNumber = max(matData.dispersionAbbeNumber, 1e-6);\n (*ma).mediumExtinction = max(matData.mediumExtinction, vec3f(0.0));\n (*ma).mediumScattering = max(matData.mediumScattering, vec3f(0.0));\n (*ma).mediumAnisotropy = clamp(matData.mediumAnisotropy, -1.0, 1.0);\n (*ma).mediumType = select(0, 1, max(max((*ma).mediumExtinction.x, (*ma).mediumExtinction.y), (*ma).mediumExtinction.z) > 0.0);\n (*ma).alpha = matData.alpha;\n ${alphaModeAssignment}\n\n (*ma).thinFilmThickness = matData.thinFilmThickness * 1000.0;\n (*ma).thinFilmIor = matData.thinFilmIor;\n (*ma).thinFilmWeight = select(0.0, clamp(matData.thinFilmWeight, 0.0, 1.0), HAS_THIN_FILM);\n (*ma).baseWeight = clamp(matData.baseWeight, 0.0, 1.0);\n (*ma).diffuseRoughness = clamp(matData.baseDiffuseRoughness, 0.0, 1.0);\n (*ma).specularWeight = max(matData.specularWeight, 0.0);\n (*ma).specularColor = max(matData.specularColor, vec3f(0.0));\n (*ma).subsurfaceWeight = select(0.0, clamp(matData.subsurfaceWeight, 0.0, 1.0), HAS_SUBSURFACE);\n (*ma).subsurfaceColor = max(matData.subsurfaceColor, vec3f(0.0));\n (*ma).transmissionColor = max(matData.transmissionColor, vec3f(0.0));\n (*ma).fuzzWeight = select(0.0, clamp(matData.fuzzWeight, 0.0, 1.0), HAS_FUZZ);\n (*ma).fuzzColor = max(matData.fuzzColor, vec3f(0.0));\n (*ma).fuzzRoughness = clamp(matData.fuzzRoughness, 0.0, 1.0);\n (*ma).coatWeight = select(0.0, clamp(matData.coatWeight, 0.0, 1.0), HAS_COAT);\n (*ma).coatColor = max(matData.coatColor, vec3f(0.0));\n (*ma).coatRoughness = clamp(matData.coatRoughness, ROUGHNESS_MIN, 1.0);\n (*ma).coatAnisotropy = clamp(matData.coatAnisotropy, 0.0, 1.0);\n (*ma).coatIor = max(matData.coatIor, 1.0);\n (*ma).coatDarkening = clamp(matData.coatDarkening, 0.0, 1.0);\n\n if (USE_DIFFUSE_MAPS) {\n let diffuseMapIndex = i32(matData.diffuseMapIndex);\n if (diffuseMapIndex >= 0) {\n // TODO textureSample is not supported in compute shader.\n let 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 (*ma).baseColor *= decodeMapColor(diffuseMapIndex, diffuse.rgb);\n\n // Map alpha to transmission\n if (matData.mapAlphaUsage == ${mapAlphaUsageConstants.transmission}) {\n (*ma).transmissionWeight = 1.0 - diffuse.a;\n }\n else if (matData.mapAlphaUsage == ${mapAlphaUsageConstants.alpha}) {\n (*ma).alpha *= diffuse.a;\n }\n }\n }\n\n ${simpleTextureSample('alphaMap', 'wgsl')}\n\n ${alphaModeResolution}\n\n ${simpleTextureSample('transmissionMap', 'wgsl')}\n\n if (USE_METALLIC_ROUGHNESS_MAPS) {\n // Metallic roughness transmission map index\n let mrtMapIndex = i32(matData.mrtMapIndex);\n if (mrtMapIndex >= 0) {\n let metallicRoughness = sampleMap(\n mrtMapIndex, getMapUvSet(mrtMapIndex, uv, uv1)\n );\n (*ma).baseMetalness *= metallicRoughness.b;\n (*ma).specularRoughness *= metallicRoughness.g;\n }\n }\n\n ${simpleTextureSample('roughnessMap', 'wgsl')}\n\n ${simpleTextureSample('metalnessMap', 'wgsl')}\n\n ${thinFilmTextureSample('wgsl')}\n\n ${simpleTextureSample('coatWeightMap', 'wgsl')}\n\n${hasCoatNormals ? /* wgsl */ `\n // Independent coat shading also applies when the coat has no normal map.\n (*ma).coatNormalEnabled = (*ma).coatWeight > 0.0 && (matData.normalMapIndex >= 0.0 || matData.coatNormalMapIndex >= 0.0);\n` : ''}\n\n ${simpleTextureSample('coatRoughnessMap', 'wgsl')}\n\n ${simpleTextureSample('fuzzColorMap', 'wgsl')}\n\n ${simpleTextureSample('fuzzRoughnessMap', 'wgsl')}\n\n ${simpleTextureSample('specularWeightMap', 'wgsl')}\n\n ${simpleTextureSample('specularColorMap', 'wgsl')}\n\n${hasAnisotropyDirections ? /* wgsl */ `\n (*ma).anisotropyDirection = vec2f(1.0, 0.0);\n (*ma).anisotropyDirectionEnabled = matData.specularAnisotropyRotation != 0.0;\n (*ma).coatAnisotropyRotation = matData.coatAnisotropyRotation;\n if (USE_ANISOTROPY_MAPS && matData.anisotropyMapIndex >= 0.0) {\n let index = i32(matData.anisotropyMapIndex);\n let texel = sampleMap(index, getMapUvSet(index, uv, uv1));\n (*ma).specularAnisotropy *= texel.b;\n let direction = texel.rg * 2.0 - 1.0;\n if (dot(direction, direction) > 1e-4) { (*ma).anisotropyDirection = normalize(direction); }\n (*ma).anisotropyDirectionEnabled = true;\n }\n if (matData.specularAnisotropyModel > 0.5 && (*ma).specularAnisotropy > 0.0) {\n let native = gltf_anisotropy_to_openpbr(clamp((*ma).specularRoughness, 0.0, 1.0), (*ma).specularAnisotropy);\n (*ma).specularRoughness = native.x;\n (*ma).specularAnisotropy = native.y;\n }\n if ((*ma).anisotropyDirectionEnabled) {\n let theta = matData.specularAnisotropyRotation;\n let d = (*ma).anisotropyDirection;\n (*ma).anisotropyDirection = vec2f(cos(theta)*d.x - sin(theta)*d.y, sin(theta)*d.x + cos(theta)*d.y);\n }\n\n` : /* wgsl */ ``}\n // OpenPBR 1.1.1: coat refraction broadens all base microfacet lobes.\n // Keep the zero-coat / smooth-coat paths byte-identical.\n if ((*ma).coatWeight > 0.0 && (*ma).coatRoughness > 0.0) {\n let baseRoughness2 = (*ma).specularRoughness * (*ma).specularRoughness;\n let coatRoughness2 = (*ma).coatRoughness * (*ma).coatRoughness;\n (*ma).specularRoughness = mix((*ma).specularRoughness,\n pow(min(1.0, baseRoughness2 * baseRoughness2 + 2.0 * coatRoughness2 * coatRoughness2), 0.25), (*ma).coatWeight);\n }\n ${hasTransmission ? '' : /* wgsl */ `(*ma).transmissionWeight = 0.0;`}\n ${hasMetalness ? '' : /* wgsl */ `(*ma).baseMetalness = 0.0;`}\n let color = getInstanceColor(instanceIndex) * vertexColor;\n (*ma).baseColor *= color;\n if ((*ma).materialType == UNLIT) { (*ma).emission *= color; }\n\n${caustics ? /* wgsl */ ` (*ma).causticRoughness = (*ma).specularRoughness;\n (*ma).causticNormalMapped = matData.normalMapIndex >= 0.0;\n` : ''} (*ma).specularRoughness = clamp((*ma).specularRoughness, ROUGHNESS_MIN, 1.0);\n (*ma).baseMetalness = clamp((*ma).baseMetalness, 0.0, 1.0);\n let specularAlpha = openpbr_roughness_to_alpha((*ma).specularRoughness, (*ma).specularAnisotropy);\n (*ma).alphaX = specularAlpha.x;\n (*ma).alphaY = specularAlpha.y;\n}\n\nfn getMatNormal(materialIndex: i32, uv: vec2f, normal: vec3f, dp1: vec3f, dp2: vec3f, duv1: vec2f, duv2: vec2f) -> vec3f {\n let matData = materialsBuffer[materialIndex];\n let normalMapIndex = i32(matData.normalMapIndex);\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 let dp2perp = cross(dp2, normal);\n let dp1perp = cross(normal, dp1);\n var dpdu = dp2perp * duv1.x + dp1perp * duv2.x;\n var dpdv = dp2perp * duv1.y + dp1perp * duv2.y;\n let gradientLengthSquared = max(dot(dpdu, dpdu), dot(dpdv, dpdv));\n if (gradientLengthSquared > 1e-12) {\n let invmax = inverseSqrt(gradientLengthSquared);\n dpdu *= invmax;\n dpdv *= invmax;\n }\n else {\n // Generated/triplanar UVs have no per-vertex UV derivatives. Build a\n // stable fallback basis instead of normalizing two zero vectors.\n let referenceAxis = select(\n vec3f(0.0, 1.0, 0.0),\n vec3f(0.0, 0.0, 1.0),\n abs(normal.z) < 0.999\n );\n dpdu = normalize(cross(referenceAxis, normal));\n dpdv = cross(normal, dpdu);\n }\n\n var n = 2.0 * sampleMap(normalMapIndex, uv).rgb - 1.0;\n n = normalize(vec3(n.xy * matData.normalMapScale, n.z));\n\n let tbn = mat3x3(dpdu, dpdv, normal);\n\n return normalize(tbn * n);\n } else {\n return normal;\n }\n}\n`;\n}\n\nconst materialBufferWgsl = createMaterialBufferWgsl();\n\nexport default materialBufferWgsl;\n"]}