@meimu/mutracer 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/README.md +3 -0
  2. package/dist/assets/bvh.worker.js +1 -1
  3. package/dist/mutracer.umd.js +8949 -7915
  4. package/docs/api.md +42 -21
  5. package/docs/caustics.md +80 -0
  6. package/docs/materials.md +5 -4
  7. package/docs/progressive-rendering.md +50 -9
  8. package/docs/technical/continuous-spectrum.md +93 -0
  9. package/docs/updates.md +3 -1
  10. package/docs/viewer-checklist.md +65 -0
  11. package/docs/viewer.md +7 -5
  12. package/lib/Display.js +1 -1
  13. package/lib/Display.js.map +1 -1
  14. package/lib/Engine.d.ts +2 -0
  15. package/lib/Engine.js +47 -12
  16. package/lib/Engine.js.map +1 -1
  17. package/lib/Render.d.ts +61 -13
  18. package/lib/Render.js +169 -19
  19. package/lib/Render.js.map +1 -1
  20. package/lib/RenderLoop.d.ts +7 -3
  21. package/lib/RenderLoop.js +68 -44
  22. package/lib/RenderLoop.js.map +1 -1
  23. package/lib/main.d.ts +1 -1
  24. package/lib/main.js.map +1 -1
  25. package/lib/oidn.d.ts +1 -1
  26. package/lib/oidnBundledWeights.cdn.d.ts +2 -2
  27. package/lib/renderer/GPUTraceQueue.d.ts +2 -1
  28. package/lib/renderer/GPUTraceQueue.js +3 -1
  29. package/lib/renderer/GPUTraceQueue.js.map +1 -1
  30. package/lib/renderer/RenderingPipeline.d.ts +4 -0
  31. package/lib/renderer/RenderingPipeline.js.map +1 -1
  32. package/lib/renderer/WGPUCausticLightPass.d.ts +48 -0
  33. package/lib/renderer/WGPUCausticLightPass.js +217 -0
  34. package/lib/renderer/WGPUCausticLightPass.js.map +1 -0
  35. package/lib/renderer/WGPUEnvMapDistribution.js +18 -18
  36. package/lib/renderer/WGPUFullQuadPass.js +3 -3
  37. package/lib/renderer/WGPUPhotonMap.d.ts +37 -0
  38. package/lib/renderer/WGPUPhotonMap.js +191 -0
  39. package/lib/renderer/WGPUPhotonMap.js.map +1 -0
  40. package/lib/renderer/WGPURayTraceOutput.d.ts +13 -1
  41. package/lib/renderer/WGPURayTraceOutput.js +122 -28
  42. package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
  43. package/lib/renderer/WGPURayTracePass.d.ts +48 -17
  44. package/lib/renderer/WGPURayTracePass.js +538 -340
  45. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  46. package/lib/renderer/WGPURenderingPipeline.js +83 -47
  47. package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
  48. package/lib/renderer/WebGLFullQuadPass.d.ts +2 -1
  49. package/lib/renderer/WebGLFullQuadPass.js +4 -0
  50. package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
  51. package/lib/renderer/WebGLJNLMDenoiser.js +66 -66
  52. package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
  53. package/lib/renderer/WebGLRayTracePass.d.ts +6 -1
  54. package/lib/renderer/WebGLRayTracePass.js +43 -6
  55. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  56. package/lib/renderer/WebGLRenderingPipeline.js +10 -14
  57. package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
  58. package/lib/renderer/WebGLSkyBaker.js +60 -60
  59. package/lib/renderer/accumulationTarget.d.ts +2 -1
  60. package/lib/renderer/accumulationTarget.js.map +1 -1
  61. package/lib/renderer/causticDiagnostics.d.ts +31 -0
  62. package/lib/renderer/causticDiagnostics.js +5 -0
  63. package/lib/renderer/causticDiagnostics.js.map +1 -0
  64. package/lib/renderer/causticEmission.d.ts +10 -0
  65. package/lib/renderer/causticEmission.js +40 -0
  66. package/lib/renderer/causticEmission.js.map +1 -0
  67. package/lib/renderer/causticUniform.d.ts +12 -0
  68. package/lib/renderer/causticUniform.js +22 -0
  69. package/lib/renderer/causticUniform.js.map +1 -0
  70. package/lib/renderer/caustics.d.ts +16 -0
  71. package/lib/renderer/caustics.js +93 -0
  72. package/lib/renderer/caustics.js.map +1 -0
  73. package/lib/renderer/glsl/aovDisplay.frag.js +5 -5
  74. package/lib/renderer/glsl/aovReflectance.glsl.js +53 -53
  75. package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
  76. package/lib/renderer/glsl/aovTrace.frag.js +33 -33
  77. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -9
  78. package/lib/renderer/glsl/chunks/emissiveLight.glsl.d.ts +2 -0
  79. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +35 -0
  80. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js.map +1 -0
  81. package/lib/renderer/glsl/chunks/envMap.glsl.js +73 -73
  82. package/lib/renderer/glsl/chunks/intersect.glsl.js +426 -428
  83. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
  84. package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +1 -0
  85. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +156 -153
  86. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
  87. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +771 -771
  88. package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
  89. package/lib/renderer/glsl/chunks/random.glsl.js +6 -6
  90. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +1 -0
  91. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +68 -63
  92. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
  93. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +94 -76
  94. package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
  95. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -0
  96. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +140 -117
  97. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
  98. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +14 -14
  99. package/lib/renderer/glsl/chunks/sampling.glsl.js +89 -92
  100. package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -1
  101. package/lib/renderer/glsl/chunks/sobol.glsl.js +79 -79
  102. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
  103. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
  104. package/lib/renderer/glsl/depthQuery.frag.js +2 -2
  105. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +10 -10
  106. package/lib/renderer/glsl/rayTrace.frag.d.ts +1 -1
  107. package/lib/renderer/glsl/rayTrace.frag.js +260 -237
  108. package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
  109. package/lib/renderer/glsl/shadowCatcher.frag.js +26 -26
  110. package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
  111. package/lib/renderer/glsl/webglPipeline.frag.js +59 -59
  112. package/lib/renderer/lightSampling.d.ts +3 -2
  113. package/lib/renderer/lightSampling.js +14 -8
  114. package/lib/renderer/lightSampling.js.map +1 -1
  115. package/lib/renderer/progressiveScheduler.js +4 -3
  116. package/lib/renderer/progressiveScheduler.js.map +1 -1
  117. package/lib/renderer/renderPipeline.d.ts +1 -0
  118. package/lib/renderer/renderPipeline.js.map +1 -1
  119. package/lib/renderer/researchTransport.d.ts +31 -0
  120. package/lib/renderer/researchTransport.js +5 -0
  121. package/lib/renderer/researchTransport.js.map +1 -0
  122. package/lib/renderer/sceneLayoutSchema.d.ts +1 -0
  123. package/lib/renderer/sceneLayoutSchema.js +2 -2
  124. package/lib/renderer/sceneLayoutSchema.js.map +1 -1
  125. package/lib/renderer/scratchSampling.js +6 -6
  126. package/lib/renderer/spectrum.d.ts +21 -0
  127. package/lib/renderer/spectrum.js +154 -0
  128. package/lib/renderer/spectrum.js.map +1 -0
  129. package/lib/renderer/webglLightSampling.d.ts +39 -0
  130. package/lib/renderer/webglLightSampling.js +15 -0
  131. package/lib/renderer/webglLightSampling.js.map +1 -0
  132. package/lib/renderer/wgpuBindlessSource.js +3 -3
  133. package/lib/renderer/wgpuShaderSource.d.ts +7 -0
  134. package/lib/renderer/wgpuShaderSource.js +2 -0
  135. package/lib/renderer/wgpuShaderSource.js.map +1 -1
  136. package/lib/renderer/wgsl/aovDisplay.wgsl.js +9 -9
  137. package/lib/renderer/wgsl/aovReflectance.wgsl.js +55 -55
  138. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +1 -1
  139. package/lib/renderer/wgsl/aovResolve.wgsl.js +2 -2
  140. package/lib/renderer/wgsl/aovSnapshot.wgsl.js +1 -1
  141. package/lib/renderer/wgsl/aovTrace.wgsl.js +33 -33
  142. package/lib/renderer/wgsl/bloom.wgsl.js +18 -18
  143. package/lib/renderer/wgsl/causticLight.compute.d.ts +6 -0
  144. package/lib/renderer/wgsl/causticLight.compute.js +537 -0
  145. package/lib/renderer/wgsl/causticLight.compute.js.map +1 -0
  146. package/lib/renderer/wgsl/chunks/background.wgsl.d.ts +2 -0
  147. package/lib/renderer/wgsl/chunks/background.wgsl.js +102 -0
  148. package/lib/renderer/wgsl/chunks/background.wgsl.js.map +1 -0
  149. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.d.ts +2 -0
  150. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +12 -0
  151. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js.map +1 -0
  152. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.d.ts +2 -0
  153. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +16 -0
  154. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js.map +1 -0
  155. package/lib/renderer/wgsl/chunks/caustics.wgsl.d.ts +1 -0
  156. package/lib/renderer/wgsl/chunks/caustics.wgsl.js +62 -0
  157. package/lib/renderer/wgsl/chunks/caustics.wgsl.js.map +1 -0
  158. package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
  159. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +37 -37
  160. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +598 -592
  161. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  162. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +14 -14
  163. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +2 -1
  164. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +75 -73
  165. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
  166. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +794 -794
  167. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +139 -139
  168. package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
  169. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +2 -1
  170. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +35 -25
  171. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
  172. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +1 -1
  173. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +142 -138
  174. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
  175. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
  176. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +204 -187
  177. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
  178. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +1 -1
  179. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +11 -11
  180. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
  181. package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +1 -1
  182. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +89 -93
  183. package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -1
  184. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +83 -83
  185. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
  186. package/lib/renderer/wgsl/compose.frag.wgsl.js +98 -98
  187. package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
  188. package/lib/renderer/wgsl/depthQuery.wgsl.js +2 -2
  189. package/lib/renderer/wgsl/jnlm.compute.js +74 -74
  190. package/lib/renderer/wgsl/offlineAdaptive.compute.js +25 -25
  191. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +3 -3
  192. package/lib/renderer/wgsl/photonMap.compute.d.ts +29 -0
  193. package/lib/renderer/wgsl/photonMap.compute.js +352 -0
  194. package/lib/renderer/wgsl/photonMap.compute.js.map +1 -0
  195. package/lib/renderer/wgsl/proceduralSky.compute.js +64 -64
  196. package/lib/renderer/wgsl/rayTrace.compute.d.ts +9 -1
  197. package/lib/renderer/wgsl/rayTrace.compute.js +448 -522
  198. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
  199. package/lib/scene/MaterialState.d.ts +2 -2
  200. package/lib/scene/MaterialState.js +2 -2
  201. package/lib/scene/MaterialState.js.map +1 -1
  202. package/lib/settings/render.d.ts +11 -0
  203. package/lib/settings/render.js +1 -0
  204. package/lib/settings/render.js.map +1 -1
  205. package/lib/util/fromTHREE.js +2 -2
  206. package/lib/util/fromTHREE.js.map +1 -1
  207. package/lib/version.d.ts +1 -1
  208. package/lib/version.js +1 -1
  209. package/lib/version.js.map +1 -1
  210. package/llms.txt +2 -1
  211. package/package.json +3 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"causticEmission.js","sourceRoot":"","sources":["../../src/renderer/causticEmission.ts"],"names":[],"mappings":"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","sourcesContent":["import type {AnalyticLightState} from '../scene/lightState.js';\nimport {buildLightAliasTable,colorLuminance,estimateAnalyticLightPower,type EmissiveTriangle} from './lightSampling.js';\nimport {getSpotLightArea,getSpotLightRadiance} from './lightsData.js';\n\n/** Emitted flux, independent of the NEE selection heuristic. */\nexport function causticEmissionPower(light:AnalyticLightState,radius=1) {\n if(light.type==='DirectionalLight')return colorLuminance(light.color)*light.intensity*Math.PI*radius*radius;\n if(light.type==='RectLight')return estimateAnalyticLightPower(light)*(light.spread<=.001?1/Math.PI:Math.sin(Math.PI*.5*light.spread)**2);\n if(light.type!=='SpotLight')return estimateAnalyticLightPower(light);\n const outer=Math.cos(light.outerAngle*Math.PI/180),inner=Math.cos(Math.min(light.innerAngle,light.outerAngle)*Math.PI/180);\n const rows=128,columns=128;let integral=0;\n for(let y=0;y<rows;y++)for(let x=0;x<columns;x++){\n const cosine=1-(1-outer)*(y+.5)/rows;\n const t=inner>outer?Math.min(1,Math.max(0,(cosine-outer)/(inner-outer))):1;\n const ies=light.iesProfile?.sampleBaked(Math.acos(cosine),2*Math.PI*(x+.5)/columns-Math.PI)??1;\n integral+=t*t*(3-2*t)*ies;\n }\n integral*=2*Math.PI*(1-outer)/(rows*columns);\n // A sphere projects to one quarter of its surface area in any direction.\n const intensity=colorLuminance(light.color)*(light.radius===0?light.intensity:getSpotLightRadiance(light)*getSpotLightArea(light)/4);\n return intensity*integral;\n}\n/** Two texels per alias choice: probability/alias/type/index, then its PMF. */\nexport function causticEmissionTable(lights:readonly AnalyticLightState[],triangles:readonly EmissiveTriangle[],radius=1,environmentPower=0) {\n const entries=lights.map((light,sourceIndex)=>({sourceType:2,sourceIndex,weight:causticEmissionPower(light,radius)}));\n triangles.forEach((triangle,sourceIndex)=>entries.push({sourceType:3,sourceIndex,weight:Math.PI*triangle.area*triangle.samplingLuminance}));\n if(environmentPower>0)entries.push({sourceType:1,sourceIndex:0,weight:environmentPower*Math.PI*radius*radius});\n const distribution=buildLightAliasTable(entries),count=distribution.pmfs.length;\n const data=new Float32Array(count*8),words=new Uint32Array(data.buffer);\n for(let i=0;i<count;i++){words.set(distribution.choices.subarray(i*4,i*4+4),i*8);data[i*8+4]=distribution.pmfs[i];}\n return {data,count,totalPower:distribution.totalWeight};\n}\n"]}
@@ -0,0 +1,12 @@
1
+ export interface CausticLightUniformOptions {
2
+ casterSphere: readonly number[];
3
+ viewProjection: Float32Array | Float64Array | number[];
4
+ photons: number;
5
+ batch: number;
6
+ cameraScale: number;
7
+ casterCount?: number;
8
+ choiceCount?: number;
9
+ orthographic?: boolean;
10
+ experiments?: number;
11
+ }
12
+ export declare function packCausticLightUniform(options: CausticLightUniformOptions): ArrayBuffer;
@@ -0,0 +1,22 @@
1
+ import { researchTransport } from './researchTransport.js';
2
+ import { matrixStorage } from '../math/storage.js';
3
+ import { CAUSTIC_UNIFORM_BYTES } from './wgsl/causticLight.compute.js';
4
+ export function packCausticLightUniform(options) {
5
+ const data = new ArrayBuffer(CAUSTIC_UNIFORM_BYTES), f = new Float32Array(data), u = new Uint32Array(data);
6
+ const matrix = matrixStorage(options.viewProjection);
7
+ for (let i = 0; i < 4; i++)
8
+ f[i] = options.casterSphere[i];
9
+ for (let i = 0; i < 16; i++)
10
+ f[i + 4] = matrix[i];
11
+ u[20] = options.photons;
12
+ u[21] = options.batch;
13
+ u[22] = 0;
14
+ f[23] = options.cameraScale;
15
+ u[24] = options.casterCount ?? 0;
16
+ u[25] = options.choiceCount ?? 0;
17
+ u[26] = +!!options.orthographic;
18
+ u[27] = options.experiments ?? 0;
19
+ researchTransport()?.packUniform(data, options);
20
+ return data;
21
+ }
22
+ //# sourceMappingURL=causticUniform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"causticUniform.js","sourceRoot":"","sources":["../../src/renderer/causticUniform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAC,qBAAqB,EAAC,MAAM,gCAAgC,CAAC;AAErE,MAAM,UAAU,uBAAuB,CAAC,OAAkC;IACxE,MAAM,IAAI,GAAC,IAAI,WAAW,CAAC,qBAAqB,CAAC,EAAC,CAAC,GAAC,IAAI,YAAY,CAAC,IAAI,CAAC,EAAC,CAAC,GAAC,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IACnG,MAAM,MAAM,GAAC,aAAa,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAAA,KAAI,IAAI,CAAC,GAAC,CAAC,EAAC,CAAC,GAAC,CAAC,EAAC,CAAC,EAAE;QAAC,CAAC,CAAC,CAAC,CAAC,GAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAAA,KAAI,IAAI,CAAC,GAAC,CAAC,EAAC,CAAC,GAAC,EAAE,EAAC,CAAC,EAAE;QAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,GAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1I,CAAC,CAAC,EAAE,CAAC,GAAC,OAAO,CAAC,OAAO,CAAC;IAAA,CAAC,CAAC,EAAE,CAAC,GAAC,OAAO,CAAC,KAAK,CAAC;IAAA,CAAC,CAAC,EAAE,CAAC,GAAC,CAAC,CAAC;IAAA,CAAC,CAAC,EAAE,CAAC,GAAC,OAAO,CAAC,WAAW,CAAC;IAAA,CAAC,CAAC,EAAE,CAAC,GAAC,OAAO,CAAC,WAAW,IAAE,CAAC,CAAC;IAAA,CAAC,CAAC,EAAE,CAAC,GAAC,OAAO,CAAC,WAAW,IAAE,CAAC,CAAC;IAAA,CAAC,CAAC,EAAE,CAAC,GAAC,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;IACpK,CAAC,CAAC,EAAE,CAAC,GAAC,OAAO,CAAC,WAAW,IAAE,CAAC,CAAC;IAC7B,iBAAiB,EAAE,EAAE,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAChD,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import {researchTransport} from './researchTransport.js';\nimport {matrixStorage} from '../math/storage.js';\nimport {CAUSTIC_UNIFORM_BYTES} from './wgsl/causticLight.compute.js';\nexport interface CausticLightUniformOptions {casterSphere:readonly number[];viewProjection:Float32Array|Float64Array|number[];photons:number;batch:number;cameraScale:number;casterCount?:number;choiceCount?:number;orthographic?:boolean;experiments?:number}\nexport function packCausticLightUniform(options:CausticLightUniformOptions) {\n const data=new ArrayBuffer(CAUSTIC_UNIFORM_BYTES),f=new Float32Array(data),u=new Uint32Array(data);\n const matrix=matrixStorage(options.viewProjection);for(let i=0;i<4;i++)f[i]=options.casterSphere[i];for(let i=0;i<16;i++)f[i+4]=matrix[i];\n u[20]=options.photons;u[21]=options.batch;u[22]=0;f[23]=options.cameraScale;u[24]=options.casterCount??0;u[25]=options.choiceCount??0;u[26]=+!!options.orthographic;\n u[27]=options.experiments??0;\n researchTransport()?.packUniform(data, options);\n return data;\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import type Mesh from '../scene/MeshState.js';
2
+ import type OpenPBRMaterial from '../scene/MaterialState.js';
3
+ export declare const CAUSTIC_ROUGHNESS_MAX = 0.1;
4
+ /** Material-only classification, shared by caster collection and GPU estimators. */
5
+ export declare function isCausticSpecular(m: Pick<OpenPBRMaterial, 'baseWeight' | 'baseMetalness' | 'transmissionWeight' | 'subsurfaceWeight' | 'fuzzWeight' | 'coatWeight' | 'specularRoughness'>): boolean;
6
+ export type CasterSphere = [number, number, number, number];
7
+ /** One conservative world-space sphere per smooth mesh instance. */
8
+ export declare function causticCasterSpheres(meshes: readonly Mesh[]): CasterSphere[];
9
+ /** Conservative sphere enclosing the caster mixture. */
10
+ export declare function causticCasterSphere(meshes: readonly Mesh[]): CasterSphere;
11
+ /** CPU reference for the solid-angle mixture, including overlapping cones. */
12
+ export declare function casterDirectionPdf(origin: readonly number[], direction: readonly number[], spheres: readonly CasterSphere[], weights?: readonly number[]): number;
13
+ /** Stochastic smooth coverage currently disagrees with PT energy.
14
+ * Keep those scenes on PT until transport and endpoint weights are verified.
15
+ */
16
+ export declare function hasStochasticCausticCaster(meshes: readonly Mesh[]): boolean;
@@ -0,0 +1,93 @@
1
+ import { computeGeometryBounds } from './geometryBvhBounds.js';
2
+ import { matrixStorage } from '../math/storage.js';
3
+ import { read, write } from '../math/access.js';
4
+ import { meshInstanceCount, meshInstanceTransform } from './meshInstances.js';
5
+ import { mat4, vec3 } from '../math.js';
6
+ import { resolveMaterialAlphaMode } from '../scene/MaterialState.js';
7
+ export const CAUSTIC_ROUGHNESS_MAX = 0.1;
8
+ /** Material-only classification, shared by caster collection and GPU estimators. */
9
+ export function isCausticSpecular(m) {
10
+ return m.baseWeight * (1 - m.baseMetalness) * (1 - m.transmissionWeight) <= 1e-6 &&
11
+ m.subsurfaceWeight <= 0 && m.fuzzWeight <= 0 && m.coatWeight <= 0 && m.specularRoughness <= CAUSTIC_ROUGHNESS_MAX;
12
+ }
13
+ const casterBounds = new WeakMap();
14
+ function localCasterBounds(geometry) {
15
+ const cached = casterBounds.get(geometry), positions = geometry.position.array;
16
+ if (cached && cached.version === geometry.version && cached.positions === positions)
17
+ return cached.bounds;
18
+ const value = computeGeometryBounds(geometry), bounds = [matrixStorage(value[0]), matrixStorage(value[1])];
19
+ casterBounds.set(geometry, { version: geometry.version, positions, bounds });
20
+ return bounds;
21
+ }
22
+ /** One conservative world-space sphere per smooth mesh instance. */
23
+ export function causticCasterSpheres(meshes) {
24
+ const spheres = [];
25
+ const matrix = mat4.create(), point = vec3.create();
26
+ for (const mesh of meshes) {
27
+ if (!mesh.materials.some(isCausticSpecular))
28
+ continue;
29
+ // Geometry.boundingBox is optional caller metadata and starts at zero.
30
+ // Caster collection must also work for a raw public Geometry descriptor.
31
+ const bounds = localCasterBounds(mesh.geometry), minCorner = bounds[0], maxCorner = bounds[1];
32
+ if (!Number.isFinite(minCorner[0]) || !Number.isFinite(maxCorner[0]))
33
+ continue;
34
+ let expansion = 0;
35
+ for (const material of mesh.materials)
36
+ if (isCausticSpecular(material))
37
+ expansion = Math.max(expansion, Math.abs(material.displacementBias) + (material.displacementMap ? Math.abs(material.displacementScale) : 0));
38
+ for (let instance = 0; instance < meshInstanceCount(mesh); instance++) {
39
+ const min = [Infinity, Infinity, Infinity], max = [-Infinity, -Infinity, -Infinity];
40
+ meshInstanceTransform(mesh, instance, matrix);
41
+ for (let corner = 0; corner < 8; corner++) {
42
+ for (let axis = 0; axis < 3; axis++)
43
+ write(point, axis, ((corner & (1 << axis)) ? maxCorner[axis] + expansion : minCorner[axis] - expansion));
44
+ vec3.transformMat4(point, point, matrix);
45
+ for (let axis = 0; axis < 3; axis++) {
46
+ min[axis] = Math.min(min[axis], read(point, axis));
47
+ max[axis] = Math.max(max[axis], read(point, axis));
48
+ }
49
+ }
50
+ spheres.push([(min[0] + max[0]) * .5, (min[1] + max[1]) * .5, (min[2] + max[2]) * .5, Math.hypot(max[0] - min[0], max[1] - min[1], max[2] - min[2]) * .501]);
51
+ }
52
+ }
53
+ return spheres;
54
+ }
55
+ /** Conservative sphere enclosing the caster mixture. */
56
+ export function causticCasterSphere(meshes) {
57
+ const spheres = causticCasterSpheres(meshes);
58
+ if (!spheres.length)
59
+ return [0, 0, 0, 0];
60
+ const min = [Infinity, Infinity, Infinity], max = [-Infinity, -Infinity, -Infinity];
61
+ for (const s of spheres) {
62
+ const components = [s[0], s[1], s[2]];
63
+ for (let i = 0; i < 3; i++) {
64
+ min[i] = Math.min(min[i], components[i] - s[3]);
65
+ max[i] = Math.max(max[i], components[i] + s[3]);
66
+ }
67
+ }
68
+ const center = min.map((v, i) => (v + max[i]) * .5);
69
+ let radius = 0;
70
+ for (const s of spheres)
71
+ radius = Math.max(radius, Math.hypot(s[0] - center[0], s[1] - center[1], s[2] - center[2]) + s[3]);
72
+ return [center[0], center[1], center[2], radius];
73
+ }
74
+ /** CPU reference for the solid-angle mixture, including overlapping cones. */
75
+ export function casterDirectionPdf(origin, direction, spheres, weights = []) {
76
+ let total = 0, overlaps = 0;
77
+ for (const [index, s] of spheres.entries()) {
78
+ const weight = weights[index] ?? 1;
79
+ const d = Math.hypot(s[0] - origin[0], s[1] - origin[1], s[2] - origin[2]);
80
+ const cosine = d > s[3] ? Math.sqrt(Math.max(0, 1 - (s[3] / d) ** 2)) : -1;
81
+ total += 2 * Math.PI * (1 - cosine) * weight;
82
+ if (d <= s[3] || ((s[0] - origin[0]) * direction[0] + (s[1] - origin[1]) * direction[1] + (s[2] - origin[2]) * direction[2]) / d >= cosine)
83
+ overlaps += weight;
84
+ }
85
+ return total > 0 ? overlaps / total : 0;
86
+ }
87
+ /** Stochastic smooth coverage currently disagrees with PT energy.
88
+ * Keep those scenes on PT until transport and endpoint weights are verified.
89
+ */
90
+ export function hasStochasticCausticCaster(meshes) {
91
+ return meshes.some(mesh => mesh.materials.some(m => isCausticSpecular(m) && resolveMaterialAlphaMode(m) === 'blend'));
92
+ }
93
+ //# sourceMappingURL=caustics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caustics.js","sourceRoot":"","sources":["../../src/renderer/caustics.ts"],"names":[],"mappings":"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","sourcesContent":["import {computeGeometryBounds} from './geometryBvhBounds.js';\nimport type Geometry from '../scene/Geometry.js';\nimport {matrixStorage} from '../math/storage.js';\nimport {read,write} from '../math/access.js';\nimport type Mesh from '../scene/MeshState.js';\nimport {meshInstanceCount,meshInstanceTransform} from './meshInstances.js';\nimport {mat4,vec3} from '../math.js';\nimport type OpenPBRMaterial from '../scene/MaterialState.js';\nimport {resolveMaterialAlphaMode} from '../scene/MaterialState.js';\n\nexport const CAUSTIC_ROUGHNESS_MAX = 0.1;\n/** Material-only classification, shared by caster collection and GPU estimators. */\nexport function isCausticSpecular(m: Pick<OpenPBRMaterial, 'baseWeight' | 'baseMetalness' | 'transmissionWeight' | 'subsurfaceWeight' | 'fuzzWeight' | 'coatWeight' | 'specularRoughness'>) {\n return m.baseWeight * (1 - m.baseMetalness) * (1 - m.transmissionWeight) <= 1e-6 &&\n m.subsurfaceWeight <= 0 && m.fuzzWeight <= 0 && m.coatWeight <= 0 && m.specularRoughness <= CAUSTIC_ROUGHNESS_MAX;\n}\n\nexport type CasterSphere = [number,number,number,number];\nconst casterBounds=new WeakMap<Geometry,{version:number;positions:Float32Array;bounds:[Float64Array,Float64Array]}>();\nfunction localCasterBounds(geometry:Geometry){\n const cached=casterBounds.get(geometry),positions=geometry.position.array;\n if(cached&&cached.version===geometry.version&&cached.positions===positions)return cached.bounds;\n const value=computeGeometryBounds(geometry),bounds:[Float64Array,Float64Array]=[matrixStorage(value[0]),matrixStorage(value[1])];\n casterBounds.set(geometry,{version:geometry.version,positions,bounds});return bounds;\n}\n/** One conservative world-space sphere per smooth mesh instance. */\nexport function causticCasterSpheres(meshes: readonly Mesh[]): CasterSphere[] {\n const spheres:CasterSphere[]=[];\n const matrix=mat4.create(),point=vec3.create();\n for(const mesh of meshes) {\n if(!mesh.materials.some(isCausticSpecular))continue;\n // Geometry.boundingBox is optional caller metadata and starts at zero.\n // Caster collection must also work for a raw public Geometry descriptor.\n const bounds=localCasterBounds(mesh.geometry),minCorner=bounds[0],maxCorner=bounds[1];\n if(!Number.isFinite(minCorner[0])||!Number.isFinite(maxCorner[0]))continue;\n let expansion=0;\n for(const material of mesh.materials)if(isCausticSpecular(material))expansion=Math.max(expansion,\n Math.abs(material.displacementBias)+(material.displacementMap?Math.abs(material.displacementScale):0));\n for(let instance=0;instance<meshInstanceCount(mesh);instance++) {\n const min=[Infinity,Infinity,Infinity],max=[-Infinity,-Infinity,-Infinity];\n meshInstanceTransform(mesh,instance,matrix);\n for(let corner=0;corner<8;corner++) {\n for(let axis=0;axis<3;axis++)write(point,axis,((corner&(1<<axis))?maxCorner[axis]+expansion:minCorner[axis]-expansion));\n vec3.transformMat4(point,point,matrix);\n for(let axis=0;axis<3;axis++){min[axis]=Math.min(min[axis],read(point,axis));max[axis]=Math.max(max[axis],read(point,axis));}\n }\n spheres.push([(min[0]+max[0])*.5,(min[1]+max[1])*.5,(min[2]+max[2])*.5,Math.hypot(max[0]-min[0],max[1]-min[1],max[2]-min[2])*.501]);\n }\n }\n return spheres;\n}\n/** Conservative sphere enclosing the caster mixture. */\nexport function causticCasterSphere(meshes:readonly Mesh[]):CasterSphere {\n const spheres=causticCasterSpheres(meshes);if(!spheres.length)return [0,0,0,0];\n const min=[Infinity,Infinity,Infinity],max=[-Infinity,-Infinity,-Infinity];\n for(const s of spheres){const components:number[]=[s[0],s[1],s[2]];for(let i=0;i<3;i++){min[i]=Math.min(min[i],components[i]-s[3]);max[i]=Math.max(max[i],components[i]+s[3]);}}\n const center=min.map((v,i)=>(v+max[i])*.5);\n let radius=0;for(const s of spheres)radius=Math.max(radius,Math.hypot(s[0]-center[0],s[1]-center[1],s[2]-center[2])+s[3]);\n return [center[0],center[1],center[2],radius];\n}\n/** CPU reference for the solid-angle mixture, including overlapping cones. */\nexport function casterDirectionPdf(origin:readonly number[],direction:readonly number[],spheres:readonly CasterSphere[],weights:readonly number[]=[]) {\n let total=0,overlaps=0;\n for(const [index,s] of spheres.entries()){const weight=weights[index]??1;const d=Math.hypot(s[0]-origin[0],s[1]-origin[1],s[2]-origin[2]);\n const cosine=d>s[3]?Math.sqrt(Math.max(0,1-(s[3]/d)**2)):-1;\n total+=2*Math.PI*(1-cosine)*weight;\n if(d<=s[3]||((s[0]-origin[0])*direction[0]+(s[1]-origin[1])*direction[1]+(s[2]-origin[2])*direction[2])/d>=cosine)overlaps+=weight;\n }\n return total>0?overlaps/total:0;\n}\n\n/** Stochastic smooth coverage currently disagrees with PT energy.\n * Keep those scenes on PT until transport and endpoint weights are verified.\n */\nexport function hasStochasticCausticCaster(meshes:readonly Mesh[]){\n return meshes.some(mesh=>mesh.materials.some(m=>isCausticSpecular(m)&&resolveMaterialAlphaMode(m)==='blend'));\n}\n"]}
@@ -9,7 +9,7 @@ export default new FragmentShader({
9
9
  mapping: Shader.uniform('vec4'), idComponent: Shader.uniform('int')
10
10
  },
11
11
  main: /* glsl */ `
12
- uint vn(uint v) {
12
+ uint vB(uint v) {
13
13
  v = (v ^ (v >> 16u)) * 0x7feb352du;
14
14
  v = (v ^ (v >> 15u)) * 0x846ca68bu;
15
15
  return v ^ (v >> 16u);
@@ -36,16 +36,16 @@ color = srgb(clamp(r.xyz / max(r.w, 1.0), 0.0, 1.0));
36
36
  } else if (kind == 5) {
37
37
  uvec4 ids = texelFetch(identity, p, 0);
38
38
  alpha = ids.x == 0xffffffffu ? 0.0 : 1.0;
39
- uint h = vn(ids[idComponent]);
39
+ uint h = vB(ids[idComponent]);
40
40
  color = .2 + .8 * vec3(float(h & 255u), float((h >> 8u) & 255u),
41
41
  float((h >> 16u) & 255u)) / 255.0;
42
42
  } else {
43
43
  vec4 m = texelFetch(motion, p, 0);
44
44
  alpha = m.w == 3.0 ? 1.0 : 0.0;
45
- float gR = length(m.xy), hue = 0.0;
46
- if (gR > 0.0) hue = fract(atan(m.y, m.x) / 6.28318530718 + 1.0);
45
+ float gz = length(m.xy), hue = 0.0;
46
+ if (gz > 0.0) hue = fract(atan(m.y, m.x) / 6.28318530718 + 1.0);
47
47
  vec3 v = abs(fract(vec3(hue) + vec3(0.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - 3.0);
48
- color = clamp(v - 1.0, 0.0, 1.0) * clamp(gR / mapping.w, 0.0, 1.0);
48
+ color = clamp(v - 1.0, 0.0, 1.0) * clamp(gz / mapping.w, 0.0, 1.0);
49
49
  }
50
50
  if (alpha <= 0.0) color = vec3(0.0);
51
51
  out_color = vec4(color, clamp(alpha, 0.0, 1.0));
@@ -1,82 +1,82 @@
1
1
  import proposals from './aovReflectanceSamples.glsl.js';
2
2
  // GLSL mirror of the shared 256-proposal, fused OpenPBR reflection quadrature.
3
3
  export default proposals + /* glsl */ `
4
- void aovReflectance(ag prepared, bool qQ, bool kY, out vec3 diffuse, out vec3 specular) {
4
+ void aovReflectance(OpenPbrPreparedBsdf prepared, bool qH, bool kE, out vec3 diffuse, out vec3 specular) {
5
5
  diffuse=vec3(0.0); specular=vec3(0.0);
6
6
  vec3 view = prepared.viewLocal;
7
7
  if (view.z <= 1e-6) { return; }
8
8
  OpenPbrResolvedMaterial material = prepared.material;
9
9
  vec2 alpha = vec2(material.alphaX, material.alphaY);
10
- float mg = aF(view, alpha);
11
- float jl = prepared.weights[OPENPBR_LOBE_DIFFUSE];
12
- float gb = prepared.weights[OPENPBR_LOBE_METAL];
10
+ float lN = aD(view, alpha);
11
+ float iR = prepared.weights[OPENPBR_LOBE_DIFFUSE];
12
+ float fN = prepared.weights[OPENPBR_LOBE_METAL];
13
13
  float specularWeight = prepared.weights[OPENPBR_LOBE_SPECULAR];
14
- float ei = 1.0;
15
- if (kY && prepared.dielectricMsProbability > 0.0) {
16
- ei = max(bf(prepared.refractionEtaTOverEtaI, prepared.specularAlpha), 1e-12);
14
+ float dS = 1.0;
15
+ if (kE && prepared.dielectricMsProbability > 0.0) {
16
+ dS = max(aY(prepared.refractionEtaTOverEtaI, prepared.specularAlpha), 1e-12);
17
17
  }
18
- vec3 cr = normalize(vec3(alpha, 1.0) * view);
19
- float qP = min(cr.z, 1.0);
20
- float kh = 1.0 + qP;
18
+ vec3 ce = normalize(vec3(alpha, 1.0) * view);
19
+ float qG = min(ce.z, 1.0);
20
+ float jN = 1.0 + qG;
21
21
  uint count = 256u;
22
22
  for (uint i = 0u; i < uint(NO_UNROLL(256)); i++) {
23
- uint vV = i / 2u;
24
- vec2 u = vec2((float(vV) + 0.5) / float(count / 2u),
25
- fract(float(reverseBits(vV)) * 2.3283064365386963e-10 + 0.37));
26
- vec4 kK = hp[vV];
23
+ uint wn = i / 2u;
24
+ vec2 u = vec2((float(wn) + 0.5) / float(count / 2u),
25
+ fract(float(reverseBits(wn)) * 2.3283064365386963e-10 + 0.37));
26
+ vec4 proposal = gV[wn];
27
27
 
28
- bool hO = prepared.specularAlpha < 0.001;
29
- vec3 light = vec3(kK.xy, sqrt(max(0.0, 1.0 - dot(kK.xy, kK.xy))));
30
- if (hO) { light = aO(u); }
28
+ bool hv = prepared.specularAlpha < 0.001;
29
+ vec3 light = vec3(proposal.xy, sqrt(max(0.0, 1.0 - dot(proposal.xy, proposal.xy))));
30
+ if (hv) { light = aM(u); }
31
31
  if ((i & 1u) != 0u) {
32
- float kC = (1.0 - u.y) * kh;
33
- float ex = sqrt(max(0.0, (kC + (1.0 - qP)) * (u.y * kh)));
34
- vec3 ad = normalize(vec3(alpha, 1.0) * vec3(cr.xy + ex * kK.zw, kC));
35
- if (hO) { ad = aD(view, alpha, u); }
36
- light = reflect(-view, ad);
32
+ float kf = (1.0 - u.y) * jN;
33
+ float dr = sqrt(max(0.0, (kf + (1.0 - qG)) * (u.y * jN)));
34
+ vec3 aa = normalize(vec3(alpha, 1.0) * vec3(ce.xy + dr * proposal.zw, kf));
35
+ if (hv) { aa = aA(view, alpha, u); }
36
+ light = reflect(-view, aa);
37
37
  }
38
38
 
39
39
  if (light.z <= 0.0) { continue; }
40
- vec3 ad = normalize(view + light);
41
- float qH = mg * cW(ad, alpha) / (4.0 * view.z);
42
- float pdf = 0.5 * (light.z * INVPI + qH);
40
+ vec3 aa = normalize(view + light);
41
+ float specularPdf = lN * sampling_ggx_ndf(aa, alpha) / (4.0 * view.z);
42
+ float pdf = 0.5 * (light.z * INVPI + specularPdf);
43
43
 
44
44
 
45
- vec3 aA = openpbr_to_local(prepared.basis, openpbr_to_world(prepared.basis, light));
46
- if (aA.z <= 0.0) { continue; }
47
- float scale = abs(aA.z) / (pdf * float(count));
48
- if (qQ && jl > 0.0) {
49
- float compensation = prepared.diffuseSpecularEnergyCompensation * aw(
50
- prepared.specularEtaTOverEtaI, prepared.specularAlpha, abs(aA.z));
51
- float sZ = 0.0;
52
- diffuse += jl * bJ(material, prepared.diffuseColor,
53
- view, aA, compensation, sZ) * scale;
45
+ vec3 au = openpbr_to_local(prepared.basis, openpbr_to_world(prepared.basis, light));
46
+ if (au.z <= 0.0) { continue; }
47
+ float scale = abs(au.z) / (pdf * float(count));
48
+ if (qH && iR > 0.0) {
49
+ float compensation = prepared.diffuseSpecularEnergyCompensation * ar(
50
+ prepared.specularEtaTOverEtaI, prepared.specularAlpha, abs(au.z));
51
+ float unusedPdf = 0.0;
52
+ diffuse += iR * bw(material, prepared.diffuseColor,
53
+ view, au, compensation, unusedPdf) * scale;
54
54
  }
55
- if (kY) {
56
- vec3 jn = normalize(view + aA);
57
- float bm = abs(dot(view, jn));
58
- vec3 bG = vec3(0.0);
55
+ if (kE) {
56
+ vec3 evaluatedHalf = normalize(view + au);
57
+ float viewHalf = abs(dot(view, evaluatedHalf));
58
+ vec3 fresnel = vec3(0.0);
59
59
  if (specularWeight > 0.0) {
60
- vec3 dielectric = vec3(af(bm, material.relativeIor));
61
- if (material.thinWalled) { dielectric = av(dielectric, material.transmissionWeight); }
62
- bG += specularWeight * material.specularColor * dielectric;
60
+ vec3 dielectric = vec3(ae(viewHalf, material.relativeIor));
61
+ if (material.thinWalled) { dielectric = aq(dielectric, material.transmissionWeight); }
62
+ fresnel += specularWeight * material.specularColor * dielectric;
63
63
  }
64
- if (gb > 0.0) {
65
- bG += gb * material.specularWeight * cw(bm,
64
+ if (fN > 0.0) {
65
+ fresnel += fN * material.specularWeight * openpbr_metal_fresnel(viewHalf,
66
66
  material.baseWeight * material.baseColor, material.specularColor);
67
67
  }
68
- float rJ = cW(jn, alpha) * mg
69
- * aF(aA, alpha) / (4.0 * max(aA.z * view.z, 1e-8));
70
- vec3 reflection = bG * rJ;
71
- if (gb > 0.0 && prepared.metalMsFactor > 0.0) {
72
- float cL = min(prepared.metalMsFactor * aV(prepared.specularAlpha, aA.z), 1.0 / max(aA.z, 1e-8));
73
- reflection += gb * prepared.metalMsScale * cL * INVPI;
68
+ float rE = sampling_ggx_ndf(evaluatedHalf, alpha) * lN
69
+ * aD(au, alpha) / (4.0 * max(au.z * view.z, 1e-8));
70
+ vec3 reflection = fresnel * rE;
71
+ if (fN > 0.0 && prepared.metalMsFactor > 0.0) {
72
+ float cv = min(prepared.metalMsFactor * aR(prepared.specularAlpha, au.z), 1.0 / max(au.z, 1e-8));
73
+ reflection += fN * prepared.metalMsScale * cv * INVPI;
74
74
  }
75
75
  if (prepared.dielectricMsProbability > 0.0) {
76
- float oZ = prepared.dielectricMsViewLoss * bb(
77
- prepared.refractionEtaTOverEtaI, prepared.specularAlpha, abs(aA.z)) / ei;
78
- float cL = min(oZ * prepared.dielectricMsReflectionRatio, 1.0 / abs(aA.z));
79
- reflection += prepared.dielectricMsReflectionScale * cL * INVPI;
76
+ float oP = prepared.dielectricMsViewLoss * aV(
77
+ prepared.refractionEtaTOverEtaI, prepared.specularAlpha, abs(au.z)) / dS;
78
+ float cv = min(oP * prepared.dielectricMsReflectionRatio, 1.0 / abs(au.z));
79
+ reflection += prepared.dielectricMsReflectionScale * cv * INVPI;
80
80
  }
81
81
  specular += reflection * scale;
82
82
  }
@@ -1,7 +1,7 @@
1
1
  // Generated by scripts/generate-aov-reflectance-samples.mjs; do not edit.
2
2
  // xy: concentric cosine disk; zw: spherical-cap azimuth cosine/sine.
3
3
  export default /* glsl */ `
4
- const vec4 hp[128] = vec4[128](
4
+ const vec4 gV[128] = vec4[128](
5
5
  vec4(-0.971247852, -0.202764958, 0.999698818, 0.0245412290),
6
6
  vec4(-0.808660269, 0.547487736, 0.997290432, 0.0735645667),
7
7
  vec4(-0.942509234, 0.187289074, 0.992479563, 0.122410677),
@@ -11,19 +11,19 @@ import random from './chunks/random.glsl.js';
11
11
  import cameraRay from './chunks/cameraRay.glsl.js';
12
12
  import rand from './chunks/rand.glsl.js';
13
13
  const surface = /* glsl */ `
14
- uint ke(int index) { ivec2 size = textureSize(aovScene,0); uvec4 v = texelFetch(aovScene, ivec2((index/4)%size.x, (index/4)/size.x),0); return v[index%4]; }
15
- vec3 iN(int offset){return vec3(uintBitsToFloat(ke(offset)),uintBitsToFloat(ke(offset+1)),uintBitsToFloat(ke(offset+2)));}
16
- mat4 ow(int offset) { mat4 m; for (int i=0;i<4;i++) for(int j=0;j<4;j++) m[i][j]=uintBitsToFloat(ke(offset+i*4+j)); return m; }
17
- Ray wJ(vec2 uv) {
14
+ uint jK(int index) { ivec2 size = textureSize(aovScene,0); uvec4 v = texelFetch(aovScene, ivec2((index/4)%size.x, (index/4)/size.x),0); return v[index%4]; }
15
+ vec3 iu(int offset){return vec3(uintBitsToFloat(jK(offset)),uintBitsToFloat(jK(offset+1)),uintBitsToFloat(jK(offset+2)));}
16
+ mat4 oi(int offset) { mat4 m; for (int i=0;i<4;i++) for(int j=0;j<4;j++) m[i][j]=uintBitsToFloat(jK(offset+i*4+j)); return m; }
17
+ Ray xj(vec2 uv) {
18
18
  vec4 origin = viewProjectionInv*vec4(uv*2.0-1.0,-1.0,1.0);
19
19
  vec4 target = viewProjectionInv*vec4(uv*2.0-1.0,1.0,1.0);
20
- Ray ray; gC(ray, origin.xyz/origin.w, normalize(target.xyz*origin.w-origin.xyz*target.w)); return ray;
20
+ Ray ray; initRay(ray, origin.xyz/origin.w, normalize(target.xyz*origin.w-origin.xyz*target.w)); return ray;
21
21
  }
22
- bool mQ(Ray wX, out SurfaceInteraction si, out OpenPbrResolvedMaterial material) {
23
- Ray ray=wX; si.triangleIndex=-1;
22
+ bool mC(Ray xA, out SurfaceInteraction si, out OpenPbrResolvedMaterial material) {
23
+ Ray ray=xA; si.triangleIndex=-1;
24
24
  for(int layer=0;layer<32;layer++) {
25
25
  intersectScene(ray,si,false); if(!si.hit) return false;
26
- dg(material,si.materialIndex,si.uv,si.uv1,si.instanceIndex,si.vertexColor);
26
+ getMaterial(material,si.materialIndex,si.uv,si.uv1,si.instanceIndex,si.vertexColor);
27
27
  if(material.materialType!=SHADOW_CATCHER && material.alpha>=0.5) return true;
28
28
  ray.o=si.position+ray.d*(EPS*0.02);
29
29
  }
@@ -57,56 +57,56 @@ ${surface}
57
57
  void main() {
58
58
  ${center ? /* glsl */ `
59
59
  out_id=uvec4(0xffffffffu); out_motion=vec4(0.0);
60
- Ray ray=wJ((floor(gl_FragCoord.xy)+0.5)/viewportSize);
60
+ Ray ray=xj((floor(gl_FragCoord.xy)+0.5)/viewportSize);
61
61
  SurfaceInteraction si; OpenPbrResolvedMaterial material;
62
- if(!mQ(ray,si,material)) return;
62
+ if(!mC(ray,si,material)) return;
63
63
  int offset=52+si.instanceIndex*24;
64
- out_id=uvec4(ke(offset),ke(offset+1),ke(int(ke(16))+si.materialIndex),ke(int(ke(17))+si.triangleIndex));
65
- out_motion.z=dot(si.position-iN(36),iN(40));
66
- if(ke(offset+2)==0u)return;
67
- vec4 qA=ow(offset+4)*vec4(si.position,1.0);
68
- vec4 ps=ow(0)*qA;
69
- if(ps.w<=0.0)return;
70
- vec3 tX=ps.xyz/ps.w;vec2 iz=(tX.xy*0.5+0.5)*viewportSize;
71
- if(any(lessThan(iz,vec2(0.0)))||any(greaterThanEqual(iz,viewportSize))||abs(tX.z)>1.0)return;
72
- uvec4 identity=texelFetch(previousId,ivec2(iz),0);float qz=texelFetch(previousMotion,ivec2(iz),0).z;
73
- if(any(notEqual(identity.xy,out_id.xy))||abs(qz-dot(qA.xyz-iN(44),iN(48)))>max(1e-4,abs(qz)*1e-3))return;
74
- out_motion=vec4((iz-gl_FragCoord.xy)*vec2(1.0,-1.0),out_motion.z,3.0);
64
+ out_id=uvec4(jK(offset),jK(offset+1),jK(int(jK(16))+si.materialIndex),jK(int(jK(17))+si.triangleIndex));
65
+ out_motion.z=dot(si.position-iu(36),iu(40));
66
+ if(jK(offset+2)==0u)return;
67
+ vec4 qs=oi(offset+4)*vec4(si.position,1.0);
68
+ vec4 pg=oi(0)*qs;
69
+ if(pg.w<=0.0)return;
70
+ vec3 ua=pg.xyz/pg.w;vec2 hU=(ua.xy*0.5+0.5)*viewportSize;
71
+ if(any(lessThan(hU,vec2(0.0)))||any(greaterThanEqual(hU,viewportSize))||abs(ua.z)>1.0)return;
72
+ uvec4 identity=texelFetch(previousId,ivec2(hU),0);float qr=texelFetch(previousMotion,ivec2(hU),0).z;
73
+ if(any(notEqual(identity.xy,out_id.xy))||abs(qr-dot(qs.xyz-iu(44),iu(48)))>max(1e-4,abs(qr)*1e-3))return;
74
+ out_motion=vec4((hU-gl_FragCoord.xy)*vec2(1.0,-1.0),out_motion.z,3.0);
75
75
  ` : /* glsl */ `
76
76
  ivec2 coord=ivec2(gl_FragCoord.xy);
77
77
  out_geometry=aovSample==0 ? vec4(0.0) : texelFetch(previousGeometry,coord,0);
78
78
  out_position=aovSample==0 ? vec4(0.0) : texelFetch(previousPosition,coord,0);
79
79
  out_diffuse=aovSample==0 ? vec4(0.0) : texelFetch(previousDiffuse,coord,0);
80
80
  out_specular=aovSample==0 ? vec4(0.0) : texelFetch(previousSpecular,coord,0);
81
- rG(); aZ=uvec2(floor(gl_FragCoord.xy));
82
- gW(floor(gl_FragCoord.xy),int(aQ ^ dG(uint(sequenceSeed))));
83
- Ray ray=wJ((floor(gl_FragCoord.xy)+dZ(CAMERA_PIXEL))/viewportSize);
81
+ rA(); aI=uvec2(floor(gl_FragCoord.xy));
82
+ fi(floor(gl_FragCoord.xy),int(aC ^ cB(uint(sequenceSeed))));
83
+ Ray ray=xj((floor(gl_FragCoord.xy)+sample2D(CAMERA_PIXEL))/viewportSize);
84
84
  if(cameraApertureRadius>0.0) {
85
85
  vec3 eye=viewInv[3].xyz, forward=-normalize(viewInv[2].xyz);
86
- vec3 jN=eye+ray.d*(cameraFocusDistance/dot(ray.d,forward));
87
- vec2 xU=cameraApertureRadius*kN(dZ(CAMERA_LENS));
88
- vec3 origin=(viewInv*vec4(xU,0.0,1.0)).xyz;
89
- gC(ray,origin,normalize(jN-origin));
86
+ vec3 ju=eye+ray.d*(cameraFocusDistance/dot(ray.d,forward));
87
+ vec2 uV=cameraApertureRadius*kq(sample2D(CAMERA_LENS));
88
+ vec3 origin=(viewInv*vec4(uV,0.0,1.0)).xyz;
89
+ initRay(ray,origin,normalize(ju-origin));
90
90
  }
91
91
  SurfaceInteraction si; OpenPbrResolvedMaterial material;
92
- if(!mQ(ray,si,material)) return;
92
+ if(!mC(ray,si,material)) return;
93
93
  float depth=max(dot(si.position-viewInv[3].xyz,-normalize(viewInv[2].xyz)),0.0);
94
94
  bool unsupported=material.materialType!=STANDARD || material.alpha<1.0 || material.coatWeight>0.0 || material.fuzzWeight>0.0 || material.specularAnisotropy>0.0 || material.subsurfaceWeight>0.0 || dot(material.mediumScattering,material.mediumScattering)>0.0 || material.bevel>0.0 || material.thinFilmWeight>0.0 || material.transmissionDispersionScale>0.0;
95
95
  out_geometry+=vec4(depth,material.specularRoughness,material.baseMetalness,unsupported?1.0:0.0);
96
96
  #ifdef AOV_REFLECTANCE
97
97
  if((aovMask&24)!=0 && !unsupported){
98
- vec3 normal=si.normal,face=si.faceNormal;float cosine=-dot(normal,ray.d),fu=-dot(face,ray.d);
98
+ vec3 normal=si.normal,face=si.faceNormal;float cosine=-dot(normal,ray.d),fa=-dot(face,ray.d);
99
99
  if(material.thinWalled&&(material.transmissionWeight>0.0||material.subsurfaceWeight>0.0)){
100
- if(cosine<0.0){normal=-normal;cosine=-cosine;}if(fu<0.0){face=-face;fu=-fu;}
100
+ if(cosine<0.0){normal=-normal;cosine=-cosine;}if(fa<0.0){face=-face;fa=-fa;}
101
101
  }
102
- if(fu>=0.0&&cosine<0.0){normal=face;cosine=fu;}
102
+ if(fa>=0.0&&cosine<0.0){normal=face;cosine=fa;}
103
103
  if(cosine<0.0)normal=-normal;
104
104
  material.inside=cosine<=0.0&&!material.thinWalled;material.relativeIor=cosine>0.0?1.0/material.specularIor:material.specularIor;
105
105
  vec3 tangent=vec3(0.0);
106
106
  #ifdef USE_TANGENT
107
107
  tangent=si.tangent;
108
108
  #endif
109
- ag prepared=ds(tangent,material,-ray.d,normal);
109
+ OpenPbrPreparedBsdf prepared=bV(tangent,material,-ray.d,normal);
110
110
  vec3 diffuse,specular;aovReflectance(prepared,(aovMask&8)!=0,(aovMask&16)!=0,diffuse,specular);
111
111
  out_diffuse+=vec4(diffuse,1.0);out_specular+=vec4(specular,1.0);
112
112
  }
@@ -3,16 +3,16 @@
3
3
  // Copyright (c) 2019 HOVER, MIT license; see LICENSES/RayTracingRenderer-MIT.txt.
4
4
  // Shared primary-ray construction keeps beauty and catcher coverage aligned.
5
5
  export default /* glsl */ `
6
- Ray fj(vec2 coord) {
6
+ Ray eT(vec2 coord) {
7
7
  vec4 origin = viewProjectionInv * vec4(coord * 2.0 - 1.0, -1.0, 1.0);
8
8
  vec4 target = viewProjectionInv * vec4(coord * 2.0 - 1.0, 1.0, 1.0);
9
9
  Ray cam;
10
- gC(cam, origin.xyz / origin.w, normalize(target.xyz * origin.w - origin.xyz * target.w));
10
+ initRay(cam, origin.xyz / origin.w, normalize(target.xyz * origin.w - origin.xyz * target.w));
11
11
 
12
12
  return cam;
13
13
  }
14
14
 
15
- vec2 kN(vec2 p) {
15
+ vec2 kq(vec2 p) {
16
16
  p = 2.0 * p - 1.0;
17
17
  bool greater = abs(p.x) > abs(p.y);
18
18
  float r = greater ? p.x : p.y;
@@ -20,16 +20,16 @@ float theta = greater ? 0.25 * PI * p.y / p.x : PI * (0.5 - 0.25 * p.x / p.y);
20
20
  return r * vec2(cos(theta), sin(theta));
21
21
  }
22
22
 
23
- Ray oG() {
24
- Ray cam = fj(v_Texcoord + tg());
23
+ Ray ow() {
24
+ Ray cam = eT(v_Texcoord + te());
25
25
  if (cameraApertureRadius > 0.0) {
26
26
 
27
27
  vec3 eye = viewInv[3].xyz;
28
28
  vec3 forward = -normalize(viewInv[2].xyz);
29
- vec3 jN = eye + cam.d * (cameraFocusDistance / dot(cam.d, forward));
30
- vec2 sK = cameraApertureRadius * kN(dZ(CAMERA_LENS));
31
- vec3 origin = vec3(viewInv * vec4(sK, 0.0, 1.0));
32
- gC(cam, origin, normalize(jN - origin));
29
+ vec3 ju = eye + cam.d * (cameraFocusDistance / dot(cam.d, forward));
30
+ vec2 sH = cameraApertureRadius * kq(sample2D(CAMERA_LENS));
31
+ vec3 origin = vec3(viewInv * vec4(sH, 0.0, 1.0));
32
+ initRay(cam, origin, normalize(ju - origin));
33
33
  }
34
34
  return cam;
35
35
  }
@@ -0,0 +1,2 @@
1
+ declare const _default: "\nvec4 emissiveTexel(int i) { return fetchData(emissiveLightData,i,emissiveLightColumns); }\nvoid sampleEmissiveSceneLight(vec3 x, vec3 rnd, inout LightSampleRec ls) {\n ls.pdf=0.0;ls.isDelta=false;ls.sourceType=0;ls.sourceIndex=-1;\n if(emissiveChoiceCount<=0) return;\n float scaled=rnd.z*float(emissiveChoiceCount);int column=min(int(scaled),emissiveChoiceCount-1);\n vec4 first=emissiveTexel(emissiveChoiceOffset+column);\n int chosen=fract(scaled)<first.x?column:floatBitsToInt(first.y);\n vec4 choice=emissiveTexel(emissiveChoiceOffset+chosen);int kind=floatBitsToInt(choice.z),index=floatBitsToInt(choice.w);\n float pmf=emissiveTexel(emissivePmfOffset+chosen).x;\n if(kind==1) {\n#ifdef USE_ENVMAP\n sampleEnvLight(rnd.xy,ls);ls.pdf*=pmf;\n#endif\n } else if(kind==2) {\n#ifdef NUM_LIGHTS\n Light light=fetchLight(index);\n \n ls.sourceType=2;ls.sourceIndex=index;\n sampleAnalyticLight(light,x,rnd.xy,ls);ls.pdf*=pmf;\n#endif\n } else if(kind==3) {\n vec4 a=emissiveTexel(index*6),b=emissiveTexel(index*6+1),c=emissiveTexel(index*6+2);\n vec4 d=emissiveTexel(index*6+3),e=emissiveTexel(index*6+4),f=emissiveTexel(index*6+5);\n float u=sqrt(rnd.x);vec3 bary=vec3(1.0-u,u*(1.0-rnd.y),u*rnd.y);\n vec3 p=a.xyz*bary.x+b.xyz*bary.y+c.xyz*bary.z;\n ls.normal=normalize(cross(b.xyz-a.xyz,c.xyz-a.xyz));ls.direction=normalize(p-x);ls.dist=distance(x,p);\n float cosine=dot(ls.normal,-ls.direction);if(cosine<=0.0) return;\n OpenPbrResolvedMaterial m;\n getMaterial(m,int(c.w),bary.x*d.xy+bary.y*d.zw+bary.z*e.xy,bary.x*e.zw+bary.y*f.xy+bary.z*f.zw,0,vec3(1.0));\n ls.emission=m.emission;ls.pdf=pmf*ls.dist*ls.dist/max(b.w*cosine,1e-8);ls.sourceType=1;ls.sourceIndex=index;\n }\n}\n";
2
+ export default _default;
@@ -0,0 +1,35 @@
1
+ export default /* glsl */ `
2
+ vec4 ei(int i) { return fetchData(emissiveLightData,i,emissiveLightColumns); }
3
+ void jb(vec3 x, vec3 rnd, inout LightSampleRec ls) {
4
+ ls.pdf=0.0;ls.isDelta=false;ls.sourceType=0;ls.sourceIndex=-1;
5
+ if(emissiveChoiceCount<=0) return;
6
+ float scaled=rnd.z*float(emissiveChoiceCount);int column=min(int(scaled),emissiveChoiceCount-1);
7
+ vec4 first=ei(emissiveChoiceOffset+column);
8
+ int chosen=fract(scaled)<first.x?column:floatBitsToInt(first.y);
9
+ vec4 choice=ei(emissiveChoiceOffset+chosen);int kind=floatBitsToInt(choice.z),index=floatBitsToInt(choice.w);
10
+ float pmf=ei(emissivePmfOffset+chosen).x;
11
+ if(kind==1) {
12
+ #ifdef USE_ENVMAP
13
+ ig(rnd.xy,ls);ls.pdf*=pmf;
14
+ #endif
15
+ } else if(kind==2) {
16
+ #ifdef NUM_LIGHTS
17
+ Light light=fetchLight(index);
18
+
19
+ ls.sourceType=2;ls.sourceIndex=index;
20
+ sampleAnalyticLight(light,x,rnd.xy,ls);ls.pdf*=pmf;
21
+ #endif
22
+ } else if(kind==3) {
23
+ vec4 a=ei(index*6),b=ei(index*6+1),c=ei(index*6+2);
24
+ vec4 d=ei(index*6+3),e=ei(index*6+4),f=ei(index*6+5);
25
+ float u=sqrt(rnd.x);vec3 bary=vec3(1.0-u,u*(1.0-rnd.y),u*rnd.y);
26
+ vec3 p=a.xyz*bary.x+b.xyz*bary.y+c.xyz*bary.z;
27
+ ls.normal=normalize(cross(b.xyz-a.xyz,c.xyz-a.xyz));ls.direction=normalize(p-x);ls.dist=distance(x,p);
28
+ float cosine=dot(ls.normal,-ls.direction);if(cosine<=0.0) return;
29
+ OpenPbrResolvedMaterial m;
30
+ getMaterial(m,int(c.w),bary.x*d.xy+bary.y*d.zw+bary.z*e.xy,bary.x*e.zw+bary.y*f.xy+bary.z*f.zw,0,vec3(1.0));
31
+ ls.emission=m.emission;ls.pdf=pmf*ls.dist*ls.dist/max(b.w*cosine,1e-8);ls.sourceType=1;ls.sourceIndex=index;
32
+ }
33
+ }
34
+ `;
35
+ //# sourceMappingURL=emissiveLight.glsl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emissiveLight.glsl.js","sourceRoot":"","sources":["../../../../src/renderer/glsl/chunks/emissiveLight.glsl.ts"],"names":[],"mappings":"AAAA,eAAe,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCzB,CAAC","sourcesContent":["export default /* glsl */ `\nvec4 emissiveTexel(int i) { return fetchData(emissiveLightData,i,emissiveLightColumns); }\nvoid sampleEmissiveSceneLight(vec3 x, vec3 rnd, inout LightSampleRec ls) {\n ls.pdf=0.0;ls.isDelta=false;ls.sourceType=0;ls.sourceIndex=-1;\n if(emissiveChoiceCount<=0) return;\n float scaled=rnd.z*float(emissiveChoiceCount);int column=min(int(scaled),emissiveChoiceCount-1);\n vec4 first=emissiveTexel(emissiveChoiceOffset+column);\n int chosen=fract(scaled)<first.x?column:floatBitsToInt(first.y);\n vec4 choice=emissiveTexel(emissiveChoiceOffset+chosen);int kind=floatBitsToInt(choice.z),index=floatBitsToInt(choice.w);\n float pmf=emissiveTexel(emissivePmfOffset+chosen).x;\n if(kind==1) {\n#ifdef USE_ENVMAP\n sampleEnvLight(rnd.xy,ls);ls.pdf*=pmf;\n#endif\n } else if(kind==2) {\n#ifdef NUM_LIGHTS\n Light light=fetchLight(index);\n \n ls.sourceType=2;ls.sourceIndex=index;\n sampleAnalyticLight(light,x,rnd.xy,ls);ls.pdf*=pmf;\n#endif\n } else if(kind==3) {\n vec4 a=emissiveTexel(index*6),b=emissiveTexel(index*6+1),c=emissiveTexel(index*6+2);\n vec4 d=emissiveTexel(index*6+3),e=emissiveTexel(index*6+4),f=emissiveTexel(index*6+5);\n float u=sqrt(rnd.x);vec3 bary=vec3(1.0-u,u*(1.0-rnd.y),u*rnd.y);\n vec3 p=a.xyz*bary.x+b.xyz*bary.y+c.xyz*bary.z;\n ls.normal=normalize(cross(b.xyz-a.xyz,c.xyz-a.xyz));ls.direction=normalize(p-x);ls.dist=distance(x,p);\n float cosine=dot(ls.normal,-ls.direction);if(cosine<=0.0) return;\n OpenPbrResolvedMaterial m;\n getMaterial(m,int(c.w),bary.x*d.xy+bary.y*d.zw+bary.z*e.xy,bary.x*e.zw+bary.y*f.xy+bary.z*f.zw,0,vec3(1.0));\n ls.emission=m.emission;ls.pdf=pmf*ls.dist*ls.dist/max(b.w*cosine,1e-8);ls.sourceType=1;ls.sourceIndex=index;\n }\n}\n`;\n"]}