@meimu/mutracer 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/dist/assets/bvh.worker.js +1 -1
  2. package/dist/mutracer.umd.js +4155 -4052
  3. package/docs/api.md +13 -10
  4. package/docs/materials.md +17 -26
  5. package/docs/threejs.md +35 -9
  6. package/docs/viewer.md +36 -3
  7. package/lib/Engine.js +18 -1
  8. package/lib/Engine.js.map +1 -1
  9. package/lib/main.d.ts +1 -1
  10. package/lib/main.js.map +1 -1
  11. package/lib/oidn.d.ts +1 -1
  12. package/lib/oidnBundledWeights.cdn.d.ts +2 -2
  13. package/lib/renderer/MaterialTable.d.ts +1 -0
  14. package/lib/renderer/MaterialTable.js +10 -4
  15. package/lib/renderer/MaterialTable.js.map +1 -1
  16. package/lib/renderer/WGPUBloomPass.js +18 -18
  17. package/lib/renderer/WGPUFullQuadPass.js +6 -6
  18. package/lib/renderer/WGPUJNLMDenoiser.js +69 -69
  19. package/lib/renderer/WGPURayTraceOutput.js +14 -14
  20. package/lib/renderer/WGPURayTracePass.d.ts +2 -0
  21. package/lib/renderer/WGPURayTracePass.js +17 -9
  22. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  23. package/lib/renderer/WGPURenderingPipeline.js +15 -15
  24. package/lib/renderer/WebGLJNLMDenoiser.js +69 -69
  25. package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
  26. package/lib/renderer/WebGLRayTracePass.d.ts +1 -0
  27. package/lib/renderer/WebGLRayTracePass.js +8 -1
  28. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  29. package/lib/renderer/envMapCreation.d.ts +5 -1
  30. package/lib/renderer/envMapCreation.js +42 -5
  31. package/lib/renderer/envMapCreation.js.map +1 -1
  32. package/lib/renderer/geometryUpdates.js +1 -1
  33. package/lib/renderer/geometryUpdates.js.map +1 -1
  34. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +12 -12
  35. package/lib/renderer/glsl/chunks/envMap.glsl.js +66 -54
  36. package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -1
  37. package/lib/renderer/glsl/chunks/intersect.glsl.js +323 -315
  38. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
  39. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +154 -121
  40. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
  41. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +434 -434
  42. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js.map +1 -1
  43. package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
  44. package/lib/renderer/glsl/chunks/random.glsl.js +3 -3
  45. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +42 -41
  46. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
  47. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +69 -69
  48. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +84 -84
  49. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
  50. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +12 -12
  51. package/lib/renderer/glsl/chunks/sampling.glsl.js +75 -75
  52. package/lib/renderer/glsl/chunks/sobol.glsl.js +61 -61
  53. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
  54. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
  55. package/lib/renderer/glsl/depthQuery.frag.js +5 -5
  56. package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
  57. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +8 -8
  58. package/lib/renderer/glsl/rayTrace.frag.js +133 -133
  59. package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
  60. package/lib/renderer/glsl/shadowCatcher.frag.js +9 -9
  61. package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
  62. package/lib/renderer/glsl/webglPipeline.frag.js +52 -52
  63. package/lib/renderer/lightsUtil.js +6 -4
  64. package/lib/renderer/lightsUtil.js.map +1 -1
  65. package/lib/renderer/materialChanges.js +1 -1
  66. package/lib/renderer/materialChanges.js.map +1 -1
  67. package/lib/renderer/materialComparison.generated.js +36 -18
  68. package/lib/renderer/materialComparison.generated.js.map +1 -1
  69. package/lib/renderer/prepareMeshBVH.js +2 -2
  70. package/lib/renderer/prepareMeshBVH.js.map +1 -1
  71. package/lib/renderer/sceneChangeDetector.js +4 -1
  72. package/lib/renderer/sceneChangeDetector.js.map +1 -1
  73. package/lib/renderer/sceneLightChanges.js +3 -2
  74. package/lib/renderer/sceneLightChanges.js.map +1 -1
  75. package/lib/renderer/scratchSampling.js +18 -18
  76. package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
  77. package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +1 -1
  78. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +39 -31
  79. package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -1
  80. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +476 -470
  81. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  82. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +8 -8
  83. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +95 -60
  84. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
  85. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +469 -469
  86. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.d.ts +1 -1
  87. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +117 -120
  88. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js.map +1 -1
  89. package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
  90. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +25 -22
  91. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
  92. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +127 -127
  93. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +136 -136
  94. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +6 -6
  95. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +73 -73
  96. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +62 -62
  97. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
  98. package/lib/renderer/wgsl/compose.frag.wgsl.js +105 -105
  99. package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
  100. package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +1 -1
  101. package/lib/renderer/wgsl/depthQuery.wgsl.js +5 -5
  102. package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
  103. package/lib/renderer/wgsl/offlineAdaptive.compute.js +28 -28
  104. package/lib/renderer/wgsl/rayTrace.compute.js +251 -248
  105. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
  106. package/lib/scene/EnvironmentLight.d.ts +9 -3
  107. package/lib/scene/EnvironmentLight.js +9 -2
  108. package/lib/scene/EnvironmentLight.js.map +1 -1
  109. package/lib/scene/OpenPBRMaterial.d.ts +1 -1
  110. package/lib/scene/OpenPBRMaterial.js +1 -1
  111. package/lib/scene/OpenPBRMaterial.js.map +1 -1
  112. package/lib/scene/Scene.d.ts +4 -0
  113. package/lib/scene/Scene.js.map +1 -1
  114. package/lib/scene/SpotLight.d.ts +2 -2
  115. package/lib/scene/SpotLight.js +1 -1
  116. package/lib/scene/SpotLight.js.map +1 -1
  117. package/lib/scene/Texture.d.ts +17 -6
  118. package/lib/scene/Texture.js +13 -4
  119. package/lib/scene/Texture.js.map +1 -1
  120. package/lib/util/fromTHREE.js +151 -29
  121. package/lib/util/fromTHREE.js.map +1 -1
  122. package/lib/version.d.ts +1 -1
  123. package/lib/version.js +1 -1
  124. package/lib/version.js.map +1 -1
  125. package/package.json +1 -1
@@ -52,7 +52,7 @@ ${cameraRayGlsl}
52
52
 
53
53
 
54
54
 
55
- vec4 mn(inout Ray ray, out vec4 background) {
55
+ vec4 mx(inout Ray ray, out vec4 background) {
56
56
  background = vec4(0.0);
57
57
  Path aa;
58
58
  aa.ray = ray;
@@ -65,7 +65,7 @@ aa.abort = false;
65
65
 
66
66
  ad si;
67
67
 
68
- cY(aa.ray, si, false);
68
+ cZ(aa.ray, si, false);
69
69
  if (!si.hit) {
70
70
 
71
71
 
@@ -74,7 +74,7 @@ return vec4(0.0, 0.0, 0.0, 1.0);
74
74
  }
75
75
 
76
76
  J mat;
77
- eT(mat, si.materialIndex, si.uv, si.uv1, si.instanceIndex);
77
+ eX(mat, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
78
78
  if (mat.materialType != SHADOW_CATCHER) {
79
79
 
80
80
 
@@ -90,13 +90,13 @@ return vec4(1.0, bg.a, bg.a >= 0.01 ? 1.0 : 0.0, aa.alpha);
90
90
  }
91
91
 
92
92
  void main() {
93
- sk();
94
- ka(v_Texcoord * viewportSize, int(uint(sampleCount) ^ eg(uint(sequenceSeed))));
93
+ su();
94
+ kh(v_Texcoord * viewportSize, int(uint(sampleCount) ^ eg(uint(sequenceSeed))));
95
95
 
96
96
  if (dispersionWavelengths == 1 && wavelength > 0.0) { dz(CAMERA_WAVELENGTH); }
97
- Ray cam = nC();
97
+ Ray cam = nM();
98
98
  vec4 background;
99
- vec4 aF = mn(cam, background);
99
+ vec4 aF = mx(cam, background);
100
100
 
101
101
  if (!(aF.x < INF && aF.x > -EPS)) {
102
102
  aF = vec4(0, 0, 0, 1);
@@ -107,11 +107,11 @@ out_catcherBackground = background;
107
107
 
108
108
 
109
109
 
110
- float jl = aF.a * (background.a >= 0.01
110
+ float jq = aF.a * (background.a >= 0.01
111
111
  ? dot(background.rgb / background.a, vec3(0.2126, 0.7152, 0.0722))
112
112
  : 1.0);
113
113
  out_catcherMoments = aF.r > 0.0
114
- ? vec4(jl, jl * jl, 1.0, 0.0)
114
+ ? vec4(jq, jq * jq, 1.0, 0.0)
115
115
  : vec4(0.0);
116
116
 
117
117
  }`
@@ -1 +1 @@
1
- {"version":3,"file":"shadowCatcher.frag.js","sourceRoot":"","sources":["../../../src/renderer/glsl/shadowCatcher.frag.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,OAAO,aAAa,MAAM,4BAA4B,CAAC;AACvD,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,YAAY,MAAM,+BAA+B,CAAC;AACzD,OAAO,aAAa,MAAM,gCAAgC,CAAC;AAC3D,OAAO,kBAAkB,MAAM,iCAAiC,CAAC;AACjE,OAAO,SAAS,MAAM,4BAA4B,CAAC;AACnD,OAAO,QAAQ,MAAM,uBAAuB,CAAC;AAC7C,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,mBAAmB,MAAM,sCAAsC,CAAC;AACvE,OAAO,WAAW,MAAM,8BAA8B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,YAAY,MAAM,2BAA2B,CAAC;AACrD,OAAO,gBAAgB,MAAM,+BAA+B,CAAC;AAE7D,eAAe,IAAI,cAAc,CAAC;IAChC,IAAI,EAAE,eAAe;IACrB,OAAO,EAAE,CAAC,eAAe,EAAE,mBAAmB,EAAE,gBAAgB,CAAC;IACjE,OAAO,EAAE;QACP,OAAO,EAAE,CAAC;KACX;IACD,QAAQ,EAAE;QACR,qBAAqB,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/C,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QACtC,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QACpC,iBAAiB,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QACzC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QAC/B,oBAAoB,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAChD,mBAAmB,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;KACjD;IACD,QAAQ,EAAE,CAAC,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC;IACvE,IAAI,EAAE,IAAI,CAAA;EACV,MAAM;EACN,QAAQ;EACR,MAAM,CAAC,IAAI;;EAEX,aAAa;;EAEb,YAAY,CAAC,IAAI;EACjB,gBAAgB;;EAEhB,kBAAkB,CAAC,IAAI;EACvB,SAAS,CAAC,IAAI;EACd,MAAM,CAAC,IAAI;;EAEX,YAAY;EACZ,WAAW;EACX,mBAAmB;EACnB,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkEb;CACD,CAAC,CAAC","sourcesContent":["// 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 cameraRayGlsl from './chunks/cameraRay.glsl.js';\nimport common from './chunks/common.glsl.js';\nimport rayTraceCore from './chunks/rayTraceCore.glsl.js';\nimport textureLinear from './chunks/textureLinear.glsl.js';\nimport materialBufferGlsl from './chunks/materialBuffer.glsl.js';\nimport intersect from './chunks/intersect.glsl.js';\nimport randGlsl from './chunks/rand.glsl.js';\nimport random from './chunks/random.glsl.js';\nimport envMap from './chunks/envMap.glsl.js';\nimport sampleShadowCatcher from './chunks/sampleShadowCatcher.glsl.js';\nimport sampleLight from './chunks/sampleLight.glsl.js';\nimport { FragmentShader, glsl, Shader } from '../shader.js';\nimport samplingGlsl from './chunks/sampling.glsl.js';\nimport uvProjectionGlsl from './chunks/uvProjection.glsl.js';\n\nexport default new FragmentShader({\n name: 'shadowCatcher',\n outputs: ['shadowCatcher', 'catcherBackground', 'catcherMoments'],\n defines: {\n BOUNCES: 2\n },\n uniforms: {\n dispersionWavelengths: Shader.uniform('int', 3),\n wavelength: Shader.uniform('float', 0),\n viewportSize: Shader.uniform('vec2'),\n viewProjectionInv: Shader.uniform('mat4'),\n viewInv: Shader.uniform('mat4'),\n cameraApertureRadius: Shader.uniform('float', 0),\n cameraFocusDistance: Shader.uniform('float', 10)\n },\n includes: [rayTraceCore, materialBufferGlsl, intersect, random, envMap],\n main: glsl`\n${common}\n${randGlsl}\n${random.main}\n\n${textureLinear}\n\n${rayTraceCore.main}\n${uvProjectionGlsl}\n\n${materialBufferGlsl.main}\n${intersect.main}\n${envMap.main}\n\n${samplingGlsl}\n${sampleLight}\n${sampleShadowCatcher}\n${cameraRayGlsl}\n\n// Path tracing integrator as described in\n// http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Path_Tracing.html#\nvec4 integrator(inout Ray ray, out vec4 background) {\n background = vec4(0.0);\n Path path;\n path.ray = ray;\n path.li = vec3(0);\n path.alpha = 1.0;\n path.beta = vec3(1.0);\n path.fromEye = true;\n path.scatteringPdf = 0.0;\n path.abort = false;\n\n SurfaceInteraction si;\n\n intersectScene(path.ray, si, false);\n if (!si.hit) {\n // Red stores catcher coverage. Keep it zero for pixels where the primary\n // ray did not hit the catcher so denoised shadows cannot bleed onto the\n // model silhouette during composition.\n return vec4(0.0, 0.0, 0.0, 1.0);\n }\n\n OpenPbrResolvedMaterial mat;\n getMaterial(mat, si.materialIndex, si.uv, si.uv1, si.instanceIndex);\n if (mat.materialType != SHADOW_CATCHER) {\n // The main path tracer already renders regular geometry. Only evaluate\n // shadow opacity when the primary ray actually hits the catcher.\n return vec4(0.0, 0.0, 0.0, 1.0);\n }\n\n vec4 bg = sampleBackgroundFromRay(ray.o, ray.d);\n background = vec4(bg.rgb * bg.a, bg.a);\n if (!path.abort) {\n sampleShadowCatcher(si, 0, path);\n }\n return vec4(1.0, bg.a, bg.a >= 0.01 ? 1.0 : 0.0, path.alpha);\n}\n\nvoid main() {\n initRandom();\n rng_initialize(v_Texcoord * viewportSize, int(uint(sampleCount) ^ sampleHash(uint(sequenceSeed))));\n // Match the beauty pass's random stream in hero-wavelength previews.\n if (dispersionWavelengths == 1 && wavelength > 0.0) { sample1D(CAMERA_WAVELENGTH); }\n Ray cam = primaryCameraRay();\n vec4 background;\n vec4 liAndAlpha = integrator(cam, background);\n\n if (!(liAndAlpha.x < INF && liAndAlpha.x > -EPS)) {\n liAndAlpha = vec4(0, 0, 0, 1);\n }\n\n out_shadowCatcher = liAndAlpha;\n out_catcherBackground = background;\n // The composed catcher is the background darkened by the shadow (its\n // visibility in alpha). Over a transparent background the shadow is only\n // its opacity.\n float guideValue = liAndAlpha.a * (background.a >= 0.01\n ? dot(background.rgb / background.a, vec3(0.2126, 0.7152, 0.0722))\n : 1.0);\n out_catcherMoments = liAndAlpha.r > 0.0\n ? vec4(guideValue, guideValue * guideValue, 1.0, 0.0)\n : vec4(0.0);\n\n}`\n});\n"]}
1
+ {"version":3,"file":"shadowCatcher.frag.js","sourceRoot":"","sources":["../../../src/renderer/glsl/shadowCatcher.frag.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,OAAO,aAAa,MAAM,4BAA4B,CAAC;AACvD,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,YAAY,MAAM,+BAA+B,CAAC;AACzD,OAAO,aAAa,MAAM,gCAAgC,CAAC;AAC3D,OAAO,kBAAkB,MAAM,iCAAiC,CAAC;AACjE,OAAO,SAAS,MAAM,4BAA4B,CAAC;AACnD,OAAO,QAAQ,MAAM,uBAAuB,CAAC;AAC7C,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,mBAAmB,MAAM,sCAAsC,CAAC;AACvE,OAAO,WAAW,MAAM,8BAA8B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,YAAY,MAAM,2BAA2B,CAAC;AACrD,OAAO,gBAAgB,MAAM,+BAA+B,CAAC;AAE7D,eAAe,IAAI,cAAc,CAAC;IAChC,IAAI,EAAE,eAAe;IACrB,OAAO,EAAE,CAAC,eAAe,EAAE,mBAAmB,EAAE,gBAAgB,CAAC;IACjE,OAAO,EAAE;QACP,OAAO,EAAE,CAAC;KACX;IACD,QAAQ,EAAE;QACR,qBAAqB,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/C,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QACtC,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QACpC,iBAAiB,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QACzC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QAC/B,oBAAoB,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAChD,mBAAmB,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;KACjD;IACD,QAAQ,EAAE,CAAC,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC;IACvE,IAAI,EAAE,IAAI,CAAA;EACV,MAAM;EACN,QAAQ;EACR,MAAM,CAAC,IAAI;;EAEX,aAAa;;EAEb,YAAY,CAAC,IAAI;EACjB,gBAAgB;;EAEhB,kBAAkB,CAAC,IAAI;EACvB,SAAS,CAAC,IAAI;EACd,MAAM,CAAC,IAAI;;EAEX,YAAY;EACZ,WAAW;EACX,mBAAmB;EACnB,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkEb;CACD,CAAC,CAAC","sourcesContent":["// 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 cameraRayGlsl from './chunks/cameraRay.glsl.js';\nimport common from './chunks/common.glsl.js';\nimport rayTraceCore from './chunks/rayTraceCore.glsl.js';\nimport textureLinear from './chunks/textureLinear.glsl.js';\nimport materialBufferGlsl from './chunks/materialBuffer.glsl.js';\nimport intersect from './chunks/intersect.glsl.js';\nimport randGlsl from './chunks/rand.glsl.js';\nimport random from './chunks/random.glsl.js';\nimport envMap from './chunks/envMap.glsl.js';\nimport sampleShadowCatcher from './chunks/sampleShadowCatcher.glsl.js';\nimport sampleLight from './chunks/sampleLight.glsl.js';\nimport { FragmentShader, glsl, Shader } from '../shader.js';\nimport samplingGlsl from './chunks/sampling.glsl.js';\nimport uvProjectionGlsl from './chunks/uvProjection.glsl.js';\n\nexport default new FragmentShader({\n name: 'shadowCatcher',\n outputs: ['shadowCatcher', 'catcherBackground', 'catcherMoments'],\n defines: {\n BOUNCES: 2\n },\n uniforms: {\n dispersionWavelengths: Shader.uniform('int', 3),\n wavelength: Shader.uniform('float', 0),\n viewportSize: Shader.uniform('vec2'),\n viewProjectionInv: Shader.uniform('mat4'),\n viewInv: Shader.uniform('mat4'),\n cameraApertureRadius: Shader.uniform('float', 0),\n cameraFocusDistance: Shader.uniform('float', 10)\n },\n includes: [rayTraceCore, materialBufferGlsl, intersect, random, envMap],\n main: glsl`\n${common}\n${randGlsl}\n${random.main}\n\n${textureLinear}\n\n${rayTraceCore.main}\n${uvProjectionGlsl}\n\n${materialBufferGlsl.main}\n${intersect.main}\n${envMap.main}\n\n${samplingGlsl}\n${sampleLight}\n${sampleShadowCatcher}\n${cameraRayGlsl}\n\n// Path tracing integrator as described in\n// http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Path_Tracing.html#\nvec4 integrator(inout Ray ray, out vec4 background) {\n background = vec4(0.0);\n Path path;\n path.ray = ray;\n path.li = vec3(0);\n path.alpha = 1.0;\n path.beta = vec3(1.0);\n path.fromEye = true;\n path.scatteringPdf = 0.0;\n path.abort = false;\n\n SurfaceInteraction si;\n\n intersectScene(path.ray, si, false);\n if (!si.hit) {\n // Red stores catcher coverage. Keep it zero for pixels where the primary\n // ray did not hit the catcher so denoised shadows cannot bleed onto the\n // model silhouette during composition.\n return vec4(0.0, 0.0, 0.0, 1.0);\n }\n\n OpenPbrResolvedMaterial mat;\n getMaterial(mat, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);\n if (mat.materialType != SHADOW_CATCHER) {\n // The main path tracer already renders regular geometry. Only evaluate\n // shadow opacity when the primary ray actually hits the catcher.\n return vec4(0.0, 0.0, 0.0, 1.0);\n }\n\n vec4 bg = sampleBackgroundFromRay(ray.o, ray.d);\n background = vec4(bg.rgb * bg.a, bg.a);\n if (!path.abort) {\n sampleShadowCatcher(si, 0, path);\n }\n return vec4(1.0, bg.a, bg.a >= 0.01 ? 1.0 : 0.0, path.alpha);\n}\n\nvoid main() {\n initRandom();\n rng_initialize(v_Texcoord * viewportSize, int(uint(sampleCount) ^ sampleHash(uint(sequenceSeed))));\n // Match the beauty pass's random stream in hero-wavelength previews.\n if (dispersionWavelengths == 1 && wavelength > 0.0) { sample1D(CAMERA_WAVELENGTH); }\n Ray cam = primaryCameraRay();\n vec4 background;\n vec4 liAndAlpha = integrator(cam, background);\n\n if (!(liAndAlpha.x < INF && liAndAlpha.x > -EPS)) {\n liAndAlpha = vec4(0, 0, 0, 1);\n }\n\n out_shadowCatcher = liAndAlpha;\n out_catcherBackground = background;\n // The composed catcher is the background darkened by the shadow (its\n // visibility in alpha). Over a transparent background the shadow is only\n // its opacity.\n float guideValue = liAndAlpha.a * (background.a >= 0.01\n ? dot(background.rgb / background.a, vec3(0.2126, 0.7152, 0.0722))\n : 1.0);\n out_catcherMoments = liAndAlpha.r > 0.0\n ? vec4(guideValue, guideValue * guideValue, 1.0, 0.0)\n : vec4(0.0);\n\n}`\n});\n"]}
@@ -7,22 +7,22 @@ export const brightFragment = new FragmentShader({
7
7
  scale: Shader.uniform('float', 1)
8
8
  },
9
9
  main: glsl `
10
- const vec3 uJ = vec3(0.2125, 0.7154, 0.0721);
11
- vec4 st(vec4 a, vec4 b, vec4 c) {
10
+ const vec3 uQ = vec3(0.2125, 0.7154, 0.0721);
11
+ vec4 sD(vec4 a, vec4 b, vec4 c) {
12
12
  return a + b + c - min(min(a, b), c) - max(max(a, b), c);
13
13
  }
14
14
  void main() {
15
15
  vec2 d = 1.0 / vec2(colorTexRegion());
16
- vec4 iX = sample_colorTex(v_Texcoord);
16
+ vec4 eA = sample_colorTex(v_Texcoord);
17
17
  vec4 s1 = sample_colorTex(v_Texcoord - vec2(d.x, 0.0));
18
18
  vec4 s2 = sample_colorTex(v_Texcoord + vec2(d.x, 0.0));
19
19
  vec4 s3 = sample_colorTex(v_Texcoord - vec2(0.0, d.y));
20
20
  vec4 s4 = sample_colorTex(v_Texcoord + vec2(0.0, d.y));
21
- iX = st(st(iX, s1, s2), s3, s4);
22
- float lum = dot(iX.rgb, uJ);
23
- out_color = lum > threshold && iX.a > 0.0
24
- ? vec4(iX.rgb * scale, iX.a)
25
- : vec4(0.0, 0.0, 0.0, iX.a);
21
+ eA = sD(sD(eA, s1, s2), s3, s4);
22
+ float lum = dot(eA.rgb, uQ);
23
+ out_color = lum > threshold && eA.a > 0.0
24
+ ? vec4(eA.rgb * scale, eA.a)
25
+ : vec4(0.0, 0.0, 0.0, eA.a);
26
26
  }`
27
27
  });
28
28
  export const composeFragment = new FragmentShader({
@@ -48,35 +48,35 @@ export const composeFragment = new FragmentShader({
48
48
  sRGBOutput: Shader.uniform('bool', 1)
49
49
  },
50
50
  main: glsl `
51
- vec3 jN(vec3 color) {
51
+ vec3 jU(vec3 color) {
52
52
  return clamp(color, 0.0, 1.0);
53
53
  }
54
- vec3 iK(vec3 color) {
54
+ vec3 iP(vec3 color) {
55
55
  return clamp(color / (vec3(1.0) + color), 0.0, 1.0);
56
56
  }
57
- vec3 jE(vec3 color) {
57
+ vec3 jJ(vec3 color) {
58
58
  color = max(vec3(0.0), color - 0.004);
59
59
  return pow((color * (6.2 * color + 0.5)) /
60
60
  (color * (6.2 * color + 1.7) + 0.06), vec3(2.2));
61
61
  }
62
- vec3 oA(vec3 value) {
63
- vec3 kF = value * (value + 0.0245786) - 0.000090537;
62
+ vec3 oI(vec3 value) {
63
+ vec3 kO = value * (value + 0.0245786) - 0.000090537;
64
64
  vec3 ap = value * (0.983729 * value + 0.4329510) + 0.238081;
65
- return kF / ap;
65
+ return kO / ap;
66
66
  }
67
- vec3 ll(vec3 color) {
68
- const mat3 pn = mat3(
67
+ vec3 lv(vec3 color) {
68
+ const mat3 pw = mat3(
69
69
  vec3(0.59719, 0.07600, 0.02840),
70
70
  vec3(0.35458, 0.90834, 0.13383),
71
71
  vec3(0.04823, 0.01566, 0.83777)
72
72
  );
73
- const mat3 ov = mat3(
73
+ const mat3 oD = mat3(
74
74
  vec3(1.60475, -0.10208, -0.00327),
75
75
  vec3(-0.53108, 1.10813, -0.07276),
76
76
  vec3(-0.07367, -0.00605, 1.07602)
77
77
  );
78
- color = pn * (color / 0.6);
79
- return clamp(ov * oA(color), 0.0, 1.0);
78
+ color = pw * (color / 0.6);
79
+ return clamp(oD * oI(color), 0.0, 1.0);
80
80
  }
81
81
  const mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(
82
82
  vec3(1.6605, -0.1246, -0.0182),
@@ -88,44 +88,44 @@ vec3(0.6274, 0.0691, 0.0164),
88
88
  vec3(0.3293, 0.9195, 0.0880),
89
89
  vec3(0.0433, 0.0113, 0.8956)
90
90
  );
91
- vec3 fP(vec3 value) {
92
- vec3 mE = value * value;
93
- vec3 qC = mE * mE;
94
- return 15.5 * qC * mE - 40.14 * qC * value
95
- + 31.96 * qC - 6.868 * mE * value
96
- + 0.4298 * mE + 0.1191 * value - 0.00232;
91
+ vec3 fU(vec3 value) {
92
+ vec3 mN = value * value;
93
+ vec3 qK = mN * mN;
94
+ return 15.5 * qK * mN - 40.14 * qK * value
95
+ + 31.96 * qK - 6.868 * mN * value
96
+ + 0.4298 * mN + 0.1191 * value - 0.00232;
97
97
  }
98
- vec3 lS(vec3 color) {
99
- const mat3 pp = mat3(
98
+ vec3 mc(vec3 color) {
99
+ const mat3 pH = mat3(
100
100
  vec3(0.856627153315983, 0.137318972929847, 0.11189821299995),
101
101
  vec3(0.0951212405381588, 0.761241990602591, 0.0767994186031903),
102
102
  vec3(0.0482516061458583, 0.101439036467562, 0.811302368396859)
103
103
  );
104
- const mat3 ow = mat3(
104
+ const mat3 oE = mat3(
105
105
  vec3(1.1271005818144368, -0.1413297634984383, -0.14132976349843826),
106
106
  vec3(-0.11060664309660323, 1.157823702216272, -0.11060664309660294),
107
107
  vec3(-0.016493938717834573, -0.016493938717834257, 1.2519364065950405)
108
108
  );
109
- color = pp * (LINEAR_SRGB_TO_LINEAR_REC2020 * color);
109
+ color = pH * (LINEAR_SRGB_TO_LINEAR_REC2020 * color);
110
110
  color = clamp((log2(max(color, 1e-10)) + 12.47393) / 16.5, 0.0, 1.0);
111
- color = ow * fP(color);
111
+ color = oE * fU(color);
112
112
  color = pow(max(color, 0.0), vec3(2.2));
113
113
  return clamp(LINEAR_REC2020_TO_LINEAR_SRGB * color, 0.0, 1.0);
114
114
  }
115
115
  vec3 cl(vec3 color) {
116
- if (toneMappingMode == 1) return ll(color);
117
- if (toneMappingMode == 2) return jE(color);
118
- if (toneMappingMode == 3) return iK(color);
119
- if (toneMappingMode == 4) return jN(color);
120
- return lS(color);
116
+ if (toneMappingMode == 1) return lv(color);
117
+ if (toneMappingMode == 2) return jJ(color);
118
+ if (toneMappingMode == 3) return iP(color);
119
+ if (toneMappingMode == 4) return jU(color);
120
+ return mc(color);
121
121
  }
122
- vec3 fX(vec3 color) {
123
- vec3 tb = vec3(
122
+ vec3 gc(vec3 color) {
123
+ vec3 tj = vec3(
124
124
  1.0 + temperature * 0.16 + tint * 0.04,
125
125
  1.0 - tint * 0.12,
126
126
  1.0 - temperature * 0.16 + tint * 0.04
127
127
  );
128
- color = max(color * tb, 0.0);
128
+ color = max(color * tj, 0.0);
129
129
  color = max((color - 0.18) * contrast + 0.18, 0.0);
130
130
  float luminance = dot(color, vec3(0.2126, 0.7152, 0.0722));
131
131
  return max(mix(vec3(luminance), color, saturation), 0.0);
@@ -141,7 +141,7 @@ return;
141
141
  vec4 color = sample_colorTex(uv);
142
142
  vec4 bloom = sample_bloomTex(uv) * bloomIntensity;
143
143
  color.rgb += bloom.rgb;
144
- color.rgb = fX(color.rgb * exposure);
144
+ color.rgb = gc(color.rgb * exposure);
145
145
  if (sRGBOutput) {
146
146
  float edge = smoothstep(0.2, 0.72, distance(uv, vec2(0.5)));
147
147
  color.rgb *= 1.0 - vignette * edge;
@@ -154,15 +154,15 @@ if (shadowCatcherEnabled > 0.5) {
154
154
  float coverage = clamp(shadow.r, 0.0, 1.0);
155
155
 
156
156
 
157
- float fO = clamp(
157
+ float fS = clamp(
158
158
  (1.0 - shadow.a) / max(coverage, 0.000001), 0.0, 1.0
159
159
  );
160
- fO = max(fO - (1.0 - shadowCatcherAlpha), 0.0);
160
+ fS = max(fS - (1.0 - shadowCatcherAlpha), 0.0);
161
161
  if (coverage > 0.0) {
162
162
  vec4 foreground = sample_foregroundTex(uv);
163
163
  vec4 background = sample_catcherBackgroundTex(uv);
164
- vec3 bK = fX((foreground.rgb + bloom.rgb) * exposure);
165
- vec3 backgroundColor = fX((background.rgb / max(background.a, 0.000001) + bloom.rgb) * exposure);
164
+ vec3 bK = gc((foreground.rgb + bloom.rgb) * exposure);
165
+ vec3 backgroundColor = gc((background.rgb / max(background.a, 0.000001) + bloom.rgb) * exposure);
166
166
  if (sRGBOutput) {
167
167
  float edge = smoothstep(0.2, 0.72, distance(uv, vec2(0.5)));
168
168
  bK *= 1.0 - vignette * edge;
@@ -171,15 +171,15 @@ bK = pow(max(cl(bK), 0.0), vec3(1.0 / 2.2));
171
171
  backgroundColor = pow(max(cl(backgroundColor), 0.0), vec3(1.0 / 2.2));
172
172
  }
173
173
 
174
- float opacity = fO;
175
- fO *= coverage;
176
- float lU = clamp(dot(bloom.rgb, vec3(0.2125, 0.7154, 0.0721)), 0.0, 1.0);
177
- float hr = max(foreground.a, lU * (1.0 - coverage));
178
- float iZ = max(background.a, lU * coverage);
179
- float alpha = hr + iZ * (1.0 - opacity) + fO;
180
- vec3 premultiplied = bK * hr
181
- + backgroundColor * iZ * (1.0 - opacity)
182
- + shadowCatcherColor * fO;
174
+ float opacity = fS;
175
+ fS *= coverage;
176
+ float mf = clamp(dot(bloom.rgb, vec3(0.2125, 0.7154, 0.0721)), 0.0, 1.0);
177
+ float hv = max(foreground.a, mf * (1.0 - coverage));
178
+ float jd = max(background.a, mf * coverage);
179
+ float alpha = hv + jd * (1.0 - opacity) + fS;
180
+ vec3 premultiplied = bK * hv
181
+ + backgroundColor * jd * (1.0 - opacity)
182
+ + shadowCatcherColor * fS;
183
183
  color = vec4(premultiplied / max(alpha, 0.000001), alpha);
184
184
  }
185
185
  }
@@ -49,7 +49,7 @@ export function packLightsToBuffer(lights, texturesIndices, selectionPmfs = [],
49
49
  packVec3(off + 2, getLightDirection(light));
50
50
  packVec3(off + 3, [
51
51
  Math.cos((light.outerAngle * Math.PI) / 180),
52
- Math.min(1, Math.max(0, 1 - light.innerAngle / light.outerAngle)),
52
+ Math.cos((Math.min(light.innerAngle, light.outerAngle) * Math.PI) / 180),
53
53
  0
54
54
  ]);
55
55
  data[(off + 3) * 4 + 3] = iesProfileTexelOffsets[i] ?? -1;
@@ -106,9 +106,11 @@ export function getSpotLightRadiance(light) {
106
106
  return light.intensity / (Math.PI * light.radius ** 2);
107
107
  }
108
108
  export function getSpotLightShapingFluxFactor(light) {
109
- const cosConeAngle = Math.cos((light.outerAngle * Math.PI) / 180);
110
- const softness = Math.min(1, Math.max(0, 1 - light.innerAngle / light.outerAngle));
111
- return (1 - cosConeAngle) * (1 - 0.5 * softness) * 0.5;
109
+ // Fraction of the full sphere covered by the cone. The smoothstep falloff
110
+ // between the inner and outer cosines integrates to half its width.
111
+ const cosOuter = Math.cos((light.outerAngle * Math.PI) / 180);
112
+ const cosInner = Math.cos((Math.min(light.innerAngle, light.outerAngle) * Math.PI) / 180);
113
+ return 0.5 * (1 - 0.5 * (cosInner + cosOuter));
112
114
  }
113
115
  const warnedLights = new WeakSet();
114
116
  /** Sanitizes invalid mutable light values at the packing boundary; notifications are nonfatal. */
@@ -1 +1 @@
1
- {"version":3,"file":"lightsUtil.js","sourceRoot":"","sources":["../../src/renderer/lightsUtil.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SceneLight, AnalyticLight } from '../scene/Scene.js';\nimport type { Vec3 } from '../types.js';\nimport DirectionalLight from '../scene/DirectionalLight.js';\nimport SphereLight from '../scene/SphereLight.js';\nimport RectLight from '../scene/RectLight.js';\nimport SpotLight from '../scene/SpotLight.js';\n\nexport const CONSTANT_DIRECTIONAL_LIGHT = 1;\nexport const CONSTANT_SPHERE_LIGHT = 2;\nexport const CONSTANT_RECT_LIGHT = 3;\nexport const CONSTANT_SPOT_LIGHT = 4;\n\nexport function packLightsToBuffer(\n lights: (DirectionalLight | RectLight | SphereLight | SpotLight)[],\n texturesIndices: number[],\n selectionPmfs: ArrayLike<number> = [],\n selectionCdfs: ArrayLike<number> = [],\n iesProfileTexelOffsets: ArrayLike<number> = []\n) {\n validateSceneLights(lights);\n const numLights = lights.length;\n const PIXELS_PER_LIGHT = 6;\n const data = new Float32Array(numLights * PIXELS_PER_LIGHT * 4);\n\n function packVec3(idx: number, v: number[] | Float32Array) {\n for (let i = 0; i < 3; i++) {\n data[i + idx * 4] = v[i];\n }\n }\n\n for (let i = 0; i < numLights; i++) {\n const light = lights[i];\n const color = light.color;\n const intensity = light.intensity;\n const off = i * PIXELS_PER_LIGHT;\n packVec3(\n off,\n light.position\n );\n data[off * 4 + 3] = selectionPmfs[i] ?? 1 / Math.max(numLights, 1);\n // emission\n const emissionScale =\n light.type === 'SpotLight' ? getSpotLightRadiance(light) : intensity;\n packVec3(off + 1, [\n color[0] * emissionScale,\n color[1] * emissionScale,\n color[2] * emissionScale\n ]);\n data[(off + 1) * 4 + 3] = selectionCdfs[i] ?? (i + 1) / numLights;\n if (light.type === 'RectLight') {\n packVec3(off + 2, getRectLightUOrV(light, 0));\n data[(off + 2) * 4 + 3] = light.spread;\n packVec3(off + 3, getRectLightUOrV(light, 1));\n data[(off + 3) * 4 + 3] = texturesIndices[i] ?? -1;\n packVec3(off + 4, [\n light.spread,\n getRectLightArea(light),\n CONSTANT_RECT_LIGHT\n ]);\n } else if (light.type === 'SphereLight') {\n packVec3(off + 4, [\n light.radius,\n getSphereLightArea(light),\n CONSTANT_SPHERE_LIGHT\n ]);\n } else if (light.type === 'SpotLight') {\n packVec3(off + 2, getLightDirection(light));\n packVec3(off + 3, [\n Math.cos((light.outerAngle * Math.PI) / 180),\n Math.min(1, Math.max(0, 1 - light.innerAngle / light.outerAngle)),\n 0\n ]);\n data[(off + 3) * 4 + 3] = iesProfileTexelOffsets[i] ?? -1;\n packVec3(off + 4, [\n light.radius,\n getSpotLightArea(light),\n CONSTANT_SPOT_LIGHT\n ]);\n } else if (light.type === 'DirectionalLight') {\n packVec3(off + 2, getLightDirection(light));\n packVec3(off + 4, [0, 0, CONSTANT_DIRECTIONAL_LIGHT]);\n }\n packVec3(off + 5, getRigidLightFrame(light).x);\n }\n\n return data;\n}\n\nexport function getRigidLightFrame(light: AnalyticLight) {\n const m = light.transform;\n const normalize = (v: Vec3, fallback: Vec3): Vec3 => {\n const length = Math.hypot(v[0], v[1], v[2]);\n return length > 1e-12 ? [v[0]/length, v[1]/length, v[2]/length] : fallback;\n };\n const z = normalize([m[8],m[9],m[10]], [0,0,1]);\n const projection = m[0]*z[0] + m[1]*z[1] + m[2]*z[2];\n let x: Vec3 = [m[0]-projection*z[0],m[1]-projection*z[1],m[2]-projection*z[2]];\n if (Math.hypot(...x) <= 1e-12) x = Math.abs(z[1]) < .99 ? [z[2],0,-z[0]] : [1,0,0];\n x = normalize(x, [1,0,0]);\n const y: Vec3 = [z[1]*x[2]-z[2]*x[1], z[2]*x[0]-z[0]*x[2], z[0]*x[1]-z[1]*x[0]];\n return { x, y, direction: [-z[0] || 0,-z[1] || 0,-z[2] || 0] as Vec3 };\n}\nexport function getLightDirection(light: AnalyticLight) { return getRigidLightFrame(light).direction; }\nexport function getRectLightUOrV(light: RectLight, uOrV: 0 | 1) {\n const frame = getRigidLightFrame(light), axis = uOrV ? frame.y : frame.x;\n const size = light.size[uOrV] * (uOrV ? -1 : 1);\n return [axis[0]*size,axis[1]*size,axis[2]*size];\n}\nexport function getRectLightPosition(light: RectLight) { return light.position; }\n\nexport function getRectLightArea(light: RectLight) {\n return light.size[0] * light.size[1];\n}\n\nexport function getSphereLightArea(light: SphereLight) {\n return 4 * Math.PI * light.radius ** 2;\n}\n\nexport function getSpotLightArea(light: SpotLight) {\n return 4 * Math.PI * light.radius ** 2;\n}\n\nexport function getSpotLightRadiance(light: SpotLight) {\n // A zero-radius spot is a point emitter. Its stored emission is luminous\n // intensity (cd), and the shader applies inverse-square attenuation.\n if (light.radius === 0) return light.intensity;\n return light.intensity / (Math.PI * light.radius ** 2);\n}\n\nexport function getSpotLightShapingFluxFactor(light: SpotLight) {\n const cosConeAngle = Math.cos((light.outerAngle * Math.PI) / 180);\n const softness = Math.min(\n 1,\n Math.max(0, 1 - light.innerAngle / light.outerAngle)\n );\n return (1 - cosConeAngle) * (1 - 0.5 * softness) * 0.5;\n}\n\nconst warnedLights = new WeakSet<SceneLight>();\n/** Sanitizes invalid mutable light values at the packing boundary; notifications are nonfatal. */\nexport function validateSceneLights(lights: readonly SceneLight[], onError?: (error: Error) => void) {\n for (const light of lights) {\n if (light.type === 'EnvironmentLight') continue;\n let invalid = false;\n const clamp = (value: number, min: number, max: number, fallback: number) => {\n const normalized = Math.min(max,Math.max(min,Number.isFinite(value) ? value : fallback));\n invalid ||= !Object.is(normalized,value);\n return normalized;\n };\n light.intensity = clamp(light.intensity,0,Number.MAX_VALUE,1);\n for(let i=0;i<3;i++)light.color[i] = clamp(light.color[i],0,Number.MAX_VALUE,1);\n if (light.type !== 'AmbientLight') {\n for(let i=0;i<16;i++) if (!Number.isFinite(light.transform[i])) {\n light.transform[i] = i % 5 === 0 ? 1 : 0; invalid = true;\n }\n }\n if (light.type === 'RectLight') {\n for(let i=0;i<2;i++)light.size[i] = clamp(light.size[i],0,Number.MAX_VALUE,1);\n light.spread = clamp(light.spread,0,1,1);\n }\n if (light.type === 'SphereLight' || light.type === 'SpotLight') light.radius = clamp(light.radius,0,Number.MAX_VALUE,light.type === 'SpotLight' ? .01 : 1);\n if (light.type === 'SpotLight') {\n light.outerAngle = clamp(light.outerAngle,Number.EPSILON,180,45);\n light.innerAngle = clamp(light.innerAngle,0,light.outerAngle,30);\n }\n if (invalid && !warnedLights.has(light)) {\n warnedLights.add(light);\n const error = new Error(`Invalid ${light.type} values were clamped.`);\n console.warn(error.message);\n onError?.(error);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"lightsUtil.js","sourceRoot":"","sources":["../../src/renderer/lightsUtil.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SceneLight, AnalyticLight } from '../scene/Scene.js';\nimport type { Vec3 } from '../types.js';\nimport DirectionalLight from '../scene/DirectionalLight.js';\nimport SphereLight from '../scene/SphereLight.js';\nimport RectLight from '../scene/RectLight.js';\nimport SpotLight from '../scene/SpotLight.js';\n\nexport const CONSTANT_DIRECTIONAL_LIGHT = 1;\nexport const CONSTANT_SPHERE_LIGHT = 2;\nexport const CONSTANT_RECT_LIGHT = 3;\nexport const CONSTANT_SPOT_LIGHT = 4;\n\nexport function packLightsToBuffer(\n lights: (DirectionalLight | RectLight | SphereLight | SpotLight)[],\n texturesIndices: number[],\n selectionPmfs: ArrayLike<number> = [],\n selectionCdfs: ArrayLike<number> = [],\n iesProfileTexelOffsets: ArrayLike<number> = []\n) {\n validateSceneLights(lights);\n const numLights = lights.length;\n const PIXELS_PER_LIGHT = 6;\n const data = new Float32Array(numLights * PIXELS_PER_LIGHT * 4);\n\n function packVec3(idx: number, v: number[] | Float32Array) {\n for (let i = 0; i < 3; i++) {\n data[i + idx * 4] = v[i];\n }\n }\n\n for (let i = 0; i < numLights; i++) {\n const light = lights[i];\n const color = light.color;\n const intensity = light.intensity;\n const off = i * PIXELS_PER_LIGHT;\n packVec3(\n off,\n light.position\n );\n data[off * 4 + 3] = selectionPmfs[i] ?? 1 / Math.max(numLights, 1);\n // emission\n const emissionScale =\n light.type === 'SpotLight' ? getSpotLightRadiance(light) : intensity;\n packVec3(off + 1, [\n color[0] * emissionScale,\n color[1] * emissionScale,\n color[2] * emissionScale\n ]);\n data[(off + 1) * 4 + 3] = selectionCdfs[i] ?? (i + 1) / numLights;\n if (light.type === 'RectLight') {\n packVec3(off + 2, getRectLightUOrV(light, 0));\n data[(off + 2) * 4 + 3] = light.spread;\n packVec3(off + 3, getRectLightUOrV(light, 1));\n data[(off + 3) * 4 + 3] = texturesIndices[i] ?? -1;\n packVec3(off + 4, [\n light.spread,\n getRectLightArea(light),\n CONSTANT_RECT_LIGHT\n ]);\n } else if (light.type === 'SphereLight') {\n packVec3(off + 4, [\n light.radius,\n getSphereLightArea(light),\n CONSTANT_SPHERE_LIGHT\n ]);\n } else if (light.type === 'SpotLight') {\n packVec3(off + 2, getLightDirection(light));\n packVec3(off + 3, [\n Math.cos((light.outerAngle * Math.PI) / 180),\n Math.cos((Math.min(light.innerAngle, light.outerAngle) * Math.PI) / 180),\n 0\n ]);\n data[(off + 3) * 4 + 3] = iesProfileTexelOffsets[i] ?? -1;\n packVec3(off + 4, [\n light.radius,\n getSpotLightArea(light),\n CONSTANT_SPOT_LIGHT\n ]);\n } else if (light.type === 'DirectionalLight') {\n packVec3(off + 2, getLightDirection(light));\n packVec3(off + 4, [0, 0, CONSTANT_DIRECTIONAL_LIGHT]);\n }\n packVec3(off + 5, getRigidLightFrame(light).x);\n }\n\n return data;\n}\n\nexport function getRigidLightFrame(light: AnalyticLight) {\n const m = light.transform;\n const normalize = (v: Vec3, fallback: Vec3): Vec3 => {\n const length = Math.hypot(v[0], v[1], v[2]);\n return length > 1e-12 ? [v[0]/length, v[1]/length, v[2]/length] : fallback;\n };\n const z = normalize([m[8],m[9],m[10]], [0,0,1]);\n const projection = m[0]*z[0] + m[1]*z[1] + m[2]*z[2];\n let x: Vec3 = [m[0]-projection*z[0],m[1]-projection*z[1],m[2]-projection*z[2]];\n if (Math.hypot(...x) <= 1e-12) x = Math.abs(z[1]) < .99 ? [z[2],0,-z[0]] : [1,0,0];\n x = normalize(x, [1,0,0]);\n const y: Vec3 = [z[1]*x[2]-z[2]*x[1], z[2]*x[0]-z[0]*x[2], z[0]*x[1]-z[1]*x[0]];\n return { x, y, direction: [-z[0] || 0,-z[1] || 0,-z[2] || 0] as Vec3 };\n}\nexport function getLightDirection(light: AnalyticLight) { return getRigidLightFrame(light).direction; }\nexport function getRectLightUOrV(light: RectLight, uOrV: 0 | 1) {\n const frame = getRigidLightFrame(light), axis = uOrV ? frame.y : frame.x;\n const size = light.size[uOrV] * (uOrV ? -1 : 1);\n return [axis[0]*size,axis[1]*size,axis[2]*size];\n}\nexport function getRectLightPosition(light: RectLight) { return light.position; }\n\nexport function getRectLightArea(light: RectLight) {\n return light.size[0] * light.size[1];\n}\n\nexport function getSphereLightArea(light: SphereLight) {\n return 4 * Math.PI * light.radius ** 2;\n}\n\nexport function getSpotLightArea(light: SpotLight) {\n return 4 * Math.PI * light.radius ** 2;\n}\n\nexport function getSpotLightRadiance(light: SpotLight) {\n // A zero-radius spot is a point emitter. Its stored emission is luminous\n // intensity (cd), and the shader applies inverse-square attenuation.\n if (light.radius === 0) return light.intensity;\n return light.intensity / (Math.PI * light.radius ** 2);\n}\n\nexport function getSpotLightShapingFluxFactor(light: SpotLight) {\n // Fraction of the full sphere covered by the cone. The smoothstep falloff\n // between the inner and outer cosines integrates to half its width.\n const cosOuter = Math.cos((light.outerAngle * Math.PI) / 180);\n const cosInner = Math.cos((Math.min(light.innerAngle, light.outerAngle) * Math.PI) / 180);\n return 0.5 * (1 - 0.5 * (cosInner + cosOuter));\n}\n\nconst warnedLights = new WeakSet<SceneLight>();\n/** Sanitizes invalid mutable light values at the packing boundary; notifications are nonfatal. */\nexport function validateSceneLights(lights: readonly SceneLight[], onError?: (error: Error) => void) {\n for (const light of lights) {\n if (light.type === 'EnvironmentLight') continue;\n let invalid = false;\n const clamp = (value: number, min: number, max: number, fallback: number) => {\n const normalized = Math.min(max,Math.max(min,Number.isFinite(value) ? value : fallback));\n invalid ||= !Object.is(normalized,value);\n return normalized;\n };\n light.intensity = clamp(light.intensity,0,Number.MAX_VALUE,1);\n for(let i=0;i<3;i++)light.color[i] = clamp(light.color[i],0,Number.MAX_VALUE,1);\n if (light.type !== 'AmbientLight') {\n for(let i=0;i<16;i++) if (!Number.isFinite(light.transform[i])) {\n light.transform[i] = i % 5 === 0 ? 1 : 0; invalid = true;\n }\n }\n if (light.type === 'RectLight') {\n for(let i=0;i<2;i++)light.size[i] = clamp(light.size[i],0,Number.MAX_VALUE,1);\n light.spread = clamp(light.spread,0,1,1);\n }\n if (light.type === 'SphereLight' || light.type === 'SpotLight') light.radius = clamp(light.radius,0,Number.MAX_VALUE,light.type === 'SpotLight' ? .01 : 1);\n if (light.type === 'SpotLight') {\n light.outerAngle = clamp(light.outerAngle,Number.EPSILON,180,45);\n light.innerAngle = clamp(light.innerAngle,0,light.outerAngle,30);\n }\n if (invalid && !warnedLights.has(light)) {\n warnedLights.add(light);\n const error = new Error(`Invalid ${light.type} values were clamped.`);\n console.warn(error.message);\n onError?.(error);\n }\n }\n}\n"]}
@@ -11,7 +11,7 @@ function textureKey(texture) {
11
11
  if (!textureIds.has(texture.image))
12
12
  textureIds.set(texture.image, nextTextureId++);
13
13
  return [textureIds.get(texture), textureIds.get(texture.image), texture.version, texture.uvScale.join(','),
14
- texture.uvOffset.join(','), texture.uvChannel, texture.flipY].join(':');
14
+ texture.uvOffset.join(','), texture.uvChannel, texture.flipY, texture.wrapS, texture.wrapT, texture.colorSpace].join(':');
15
15
  }
16
16
  function key(material, keys) {
17
17
  return JSON.stringify(keys.map(k => material[k]));
@@ -1 +1 @@
1
- {"version":3,"file":"materialChanges.js","sourceRoot":"","sources":["../../src/renderer/materialChanges.ts"],"names":[],"mappings":"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","sourcesContent":["import OpenPBRMaterial, { materialGeometryKeys, materialParamKeys, materialTextureKeys } from '../scene/OpenPBRMaterial.js';\nimport Texture from '../scene/Texture.js';\nimport { colorLuminance } from './lightSampling.js';\nimport { materialEmission } from './materialEmission.js';\n\nexport type MaterialUpdateLevel = 'params' | 'emission' | 'textures' | 'geometry';\ninterface MaterialSnapshot {\n paramKey: string;\n textureKey: string;\n geometryKey: string;\n emissive: string;\n emissiveMap: string;\n}\nconst textureIds = new WeakMap<object, number>();\nlet nextTextureId = 1;\nfunction textureKey(texture: Texture | undefined) {\n if (!texture) return '-';\n if (!textureIds.has(texture)) textureIds.set(texture, nextTextureId++);\n if (!textureIds.has(texture.image)) textureIds.set(texture.image, nextTextureId++);\n return [textureIds.get(texture), textureIds.get(texture.image), texture.version, texture.uvScale.join(','),\n texture.uvOffset.join(','), texture.uvChannel, texture.flipY].join(':');\n}\nfunction key(material: OpenPBRMaterial, keys: readonly (keyof OpenPBRMaterial)[]) {\n return JSON.stringify(keys.map(k => material[k]));\n}\nfunction snapshot(material: OpenPBRMaterial): MaterialSnapshot {\n return {\n paramKey: key(material, materialParamKeys),\n textureKey: materialTextureKeys.map(k => { const value = material[k]; return typeof value === 'number' ? String(value) : textureKey(value); }).join('|'),\n // Height maps affect projective BLAS bounds.\n geometryKey: key(material, materialGeometryKeys) + '|' + textureKey(material.displacementMap),\n emissive: key(material, ['emissionColor', 'emissionLuminance', 'coatWeight', 'coatColor', 'unlit', 'shadowCatcher']) + '|' + textureKey(material.coatWeightMap),\n emissiveMap: textureKey(material.emissiveMap)\n };\n}\nexport function materialIsEmissive(material: OpenPBRMaterial) {\n return !material.unlit && !material.shadowCatcher &&\n colorLuminance(materialEmission(material)) > 1e-8;\n}\n\n/** Expensive field keys are computed only when receiving changed materials. */\nexport class MaterialChangeTracker {\n private _snapshots = new WeakMap<OpenPBRMaterial, MaterialSnapshot>();\n capture(materials: readonly OpenPBRMaterial[]) {\n for (const material of materials) this._snapshots.set(material, snapshot(material));\n }\n classify(materials: readonly OpenPBRMaterial[]): { level: MaterialUpdateLevel; emission: boolean; emissiveMap: boolean } {\n let level: MaterialUpdateLevel = 'params';\n let emission = false;\n let emissiveMap = false;\n const ranks = { params: 0, emission: 1, textures: 2, geometry: 3 };\n for (const material of materials) {\n const previous = this._snapshots.get(material);\n const next = snapshot(material);\n const emissionChanged = !previous || previous.emissive !== next.emissive;\n emission ||= emissionChanged;\n emissiveMap ||= !previous || previous.emissiveMap !== next.emissiveMap;\n const candidate: MaterialUpdateLevel = !previous || next.geometryKey !== previous.geometryKey\n ? 'geometry' : next.textureKey !== previous.textureKey ? 'textures' : emissionChanged ? 'emission' : 'params';\n if (ranks[candidate] > ranks[level]) level = candidate;\n }\n return { level, emission, emissiveMap };\n }\n}\n"]}
1
+ {"version":3,"file":"materialChanges.js","sourceRoot":"","sources":["../../src/renderer/materialChanges.ts"],"names":[],"mappings":"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","sourcesContent":["import OpenPBRMaterial, { materialGeometryKeys, materialParamKeys, materialTextureKeys } from '../scene/OpenPBRMaterial.js';\nimport Texture from '../scene/Texture.js';\nimport { colorLuminance } from './lightSampling.js';\nimport { materialEmission } from './materialEmission.js';\n\nexport type MaterialUpdateLevel = 'params' | 'emission' | 'textures' | 'geometry';\ninterface MaterialSnapshot {\n paramKey: string;\n textureKey: string;\n geometryKey: string;\n emissive: string;\n emissiveMap: string;\n}\nconst textureIds = new WeakMap<object, number>();\nlet nextTextureId = 1;\nfunction textureKey(texture: Texture | undefined) {\n if (!texture) return '-';\n if (!textureIds.has(texture)) textureIds.set(texture, nextTextureId++);\n if (!textureIds.has(texture.image)) textureIds.set(texture.image, nextTextureId++);\n return [textureIds.get(texture), textureIds.get(texture.image), texture.version, texture.uvScale.join(','),\n texture.uvOffset.join(','), texture.uvChannel, texture.flipY, texture.wrapS, texture.wrapT, texture.colorSpace].join(':');\n}\nfunction key(material: OpenPBRMaterial, keys: readonly (keyof OpenPBRMaterial)[]) {\n return JSON.stringify(keys.map(k => material[k]));\n}\nfunction snapshot(material: OpenPBRMaterial): MaterialSnapshot {\n return {\n paramKey: key(material, materialParamKeys),\n textureKey: materialTextureKeys.map(k => { const value = material[k]; return typeof value === 'number' ? String(value) : textureKey(value); }).join('|'),\n // Height maps affect projective BLAS bounds.\n geometryKey: key(material, materialGeometryKeys) + '|' + textureKey(material.displacementMap),\n emissive: key(material, ['emissionColor', 'emissionLuminance', 'coatWeight', 'coatColor', 'unlit', 'shadowCatcher']) + '|' + textureKey(material.coatWeightMap),\n emissiveMap: textureKey(material.emissiveMap)\n };\n}\nexport function materialIsEmissive(material: OpenPBRMaterial) {\n return !material.unlit && !material.shadowCatcher &&\n colorLuminance(materialEmission(material)) > 1e-8;\n}\n\n/** Expensive field keys are computed only when receiving changed materials. */\nexport class MaterialChangeTracker {\n private _snapshots = new WeakMap<OpenPBRMaterial, MaterialSnapshot>();\n capture(materials: readonly OpenPBRMaterial[]) {\n for (const material of materials) this._snapshots.set(material, snapshot(material));\n }\n classify(materials: readonly OpenPBRMaterial[]): { level: MaterialUpdateLevel; emission: boolean; emissiveMap: boolean } {\n let level: MaterialUpdateLevel = 'params';\n let emission = false;\n let emissiveMap = false;\n const ranks = { params: 0, emission: 1, textures: 2, geometry: 3 };\n for (const material of materials) {\n const previous = this._snapshots.get(material);\n const next = snapshot(material);\n const emissionChanged = !previous || previous.emissive !== next.emissive;\n emission ||= emissionChanged;\n emissiveMap ||= !previous || previous.emissiveMap !== next.emissiveMap;\n const candidate: MaterialUpdateLevel = !previous || next.geometryKey !== previous.geometryKey\n ? 'geometry' : next.textureKey !== previous.textureKey ? 'textures' : emissionChanged ? 'emission' : 'params';\n if (ranks[candidate] > ranks[level]) level = candidate;\n }\n return { level, emission, emissiveMap };\n }\n}\n"]}
@@ -413,7 +413,8 @@ export function materialTexturesChanged(material, previous) {
413
413
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
414
414
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
415
415
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
416
- previous[i++] !== texture.uvChannel)
416
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
417
+ previous[i++] !== texture.colorSpace)
417
418
  return true;
418
419
  }
419
420
  }
@@ -427,7 +428,8 @@ export function materialTexturesChanged(material, previous) {
427
428
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
428
429
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
429
430
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
430
- previous[i++] !== texture.uvChannel)
431
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
432
+ previous[i++] !== texture.colorSpace)
431
433
  return true;
432
434
  }
433
435
  }
@@ -441,7 +443,8 @@ export function materialTexturesChanged(material, previous) {
441
443
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
442
444
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
443
445
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
444
- previous[i++] !== texture.uvChannel)
446
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
447
+ previous[i++] !== texture.colorSpace)
445
448
  return true;
446
449
  }
447
450
  }
@@ -455,7 +458,8 @@ export function materialTexturesChanged(material, previous) {
455
458
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
456
459
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
457
460
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
458
- previous[i++] !== texture.uvChannel)
461
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
462
+ previous[i++] !== texture.colorSpace)
459
463
  return true;
460
464
  }
461
465
  }
@@ -469,7 +473,8 @@ export function materialTexturesChanged(material, previous) {
469
473
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
470
474
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
471
475
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
472
- previous[i++] !== texture.uvChannel)
476
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
477
+ previous[i++] !== texture.colorSpace)
473
478
  return true;
474
479
  }
475
480
  }
@@ -483,7 +488,8 @@ export function materialTexturesChanged(material, previous) {
483
488
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
484
489
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
485
490
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
486
- previous[i++] !== texture.uvChannel)
491
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
492
+ previous[i++] !== texture.colorSpace)
487
493
  return true;
488
494
  }
489
495
  }
@@ -497,7 +503,8 @@ export function materialTexturesChanged(material, previous) {
497
503
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
498
504
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
499
505
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
500
- previous[i++] !== texture.uvChannel)
506
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
507
+ previous[i++] !== texture.colorSpace)
501
508
  return true;
502
509
  }
503
510
  }
@@ -511,7 +518,8 @@ export function materialTexturesChanged(material, previous) {
511
518
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
512
519
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
513
520
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
514
- previous[i++] !== texture.uvChannel)
521
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
522
+ previous[i++] !== texture.colorSpace)
515
523
  return true;
516
524
  }
517
525
  }
@@ -525,7 +533,8 @@ export function materialTexturesChanged(material, previous) {
525
533
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
526
534
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
527
535
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
528
- previous[i++] !== texture.uvChannel)
536
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
537
+ previous[i++] !== texture.colorSpace)
529
538
  return true;
530
539
  }
531
540
  }
@@ -539,7 +548,8 @@ export function materialTexturesChanged(material, previous) {
539
548
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
540
549
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
541
550
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
542
- previous[i++] !== texture.uvChannel)
551
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
552
+ previous[i++] !== texture.colorSpace)
543
553
  return true;
544
554
  }
545
555
  }
@@ -553,7 +563,8 @@ export function materialTexturesChanged(material, previous) {
553
563
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
554
564
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
555
565
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
556
- previous[i++] !== texture.uvChannel)
566
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
567
+ previous[i++] !== texture.colorSpace)
557
568
  return true;
558
569
  }
559
570
  }
@@ -567,7 +578,8 @@ export function materialTexturesChanged(material, previous) {
567
578
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
568
579
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
569
580
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
570
- previous[i++] !== texture.uvChannel)
581
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
582
+ previous[i++] !== texture.colorSpace)
571
583
  return true;
572
584
  }
573
585
  }
@@ -581,7 +593,8 @@ export function materialTexturesChanged(material, previous) {
581
593
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
582
594
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
583
595
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
584
- previous[i++] !== texture.uvChannel)
596
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
597
+ previous[i++] !== texture.colorSpace)
585
598
  return true;
586
599
  }
587
600
  }
@@ -595,7 +608,8 @@ export function materialTexturesChanged(material, previous) {
595
608
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
596
609
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
597
610
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
598
- previous[i++] !== texture.uvChannel)
611
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
612
+ previous[i++] !== texture.colorSpace)
599
613
  return true;
600
614
  }
601
615
  }
@@ -609,7 +623,8 @@ export function materialTexturesChanged(material, previous) {
609
623
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
610
624
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
611
625
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
612
- previous[i++] !== texture.uvChannel)
626
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
627
+ previous[i++] !== texture.colorSpace)
613
628
  return true;
614
629
  }
615
630
  }
@@ -623,7 +638,8 @@ export function materialTexturesChanged(material, previous) {
623
638
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
624
639
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
625
640
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
626
- previous[i++] !== texture.uvChannel)
641
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
642
+ previous[i++] !== texture.colorSpace)
627
643
  return true;
628
644
  }
629
645
  }
@@ -637,7 +653,8 @@ export function materialTexturesChanged(material, previous) {
637
653
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
638
654
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
639
655
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
640
- previous[i++] !== texture.uvChannel)
656
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
657
+ previous[i++] !== texture.colorSpace)
641
658
  return true;
642
659
  }
643
660
  }
@@ -651,7 +668,8 @@ export function materialTexturesChanged(material, previous) {
651
668
  else if (previous[i++] !== texture || previous[i++] !== texture.version ||
652
669
  previous[i++] !== texture.image || previous[i++] !== texture.flipY ||
653
670
  previous[i++] !== texture.uvScale || previous[i++] !== texture.uvOffset ||
654
- previous[i++] !== texture.uvChannel)
671
+ previous[i++] !== texture.uvChannel || previous[i++] !== texture.wrapS || previous[i++] !== texture.wrapT ||
672
+ previous[i++] !== texture.colorSpace)
655
673
  return true;
656
674
  }
657
675
  }