@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
@@ -4,18 +4,18 @@ export function scratchWGSLFunctions(textures, samplers, scratch = false) {
4
4
  fn ${name}Region() -> vec2u {
5
5
  return ${scratch ? `imageRegions[${index}].xy` : `textureDimensions(${name})`};
6
6
  }
7
- fn load_${name}(fM: vec2i, level: i32) -> vec4f {
8
- ${scratch ? `if (any(fM < vec2i(0)) || any(fM >= vec2i(${name}Region()))) { return vec4f(0.0); }` : ''}
9
- return textureLoad(${name}, fM, level);
7
+ fn load_${name}(fQ: vec2i, level: i32) -> vec4f {
8
+ ${scratch ? `if (any(fQ < vec2i(0)) || any(fQ >= vec2i(${name}Region()))) { return vec4f(0.0); }` : ''}
9
+ return textureLoad(${name}, fQ, level);
10
10
  }
11
11
  ${samplers.map(sampler => /* wgsl */ `
12
- fn sample_${name}_${sampler}(fD: vec2f) -> vec4f {
12
+ fn sample_${name}_${sampler}(fH: vec2f) -> vec4f {
13
13
  ${scratch ? /* wgsl */ `
14
- let jV = textureDimensions(${name});
15
- if (all(jV == ${name}Region())) { return textureSampleLevel(${name}, ${sampler}, fD, 0.0); }
16
- let fM = clamp(fD * vec2f(${name}Region()), vec2f(0.5), vec2f(${name}Region()) - vec2f(0.5));
17
- return textureSampleLevel(${name}, ${sampler}, fM / vec2f(jV), 0.0);`
18
- : `return textureSample(${name}, ${sampler}, fD);`}
14
+ let kc = textureDimensions(${name});
15
+ if (all(kc == ${name}Region())) { return textureSampleLevel(${name}, ${sampler}, fH, 0.0); }
16
+ let fQ = clamp(fH * vec2f(${name}Region()), vec2f(0.5), vec2f(${name}Region()) - vec2f(0.5));
17
+ return textureSampleLevel(${name}, ${sampler}, fQ / vec2f(kc), 0.0);`
18
+ : `return textureSample(${name}, ${sampler}, fH);`}
19
19
  }`).join('')}`).join('');
20
20
  }
21
21
  export function scratchGLSLFunctions(textures, scratch = false) {
@@ -23,17 +23,17 @@ export function scratchGLSLFunctions(textures, scratch = false) {
23
23
  ivec2 ${name}Region() {
24
24
  return ${scratch ? `${name}RegionSize` : `textureSize(${name}, 0)`};
25
25
  }
26
- vec4 load_${name}(ivec2 fM, int level) {
27
- ${scratch ? `if (any(lessThan(fM, ivec2(0))) || any(greaterThanEqual(fM, ${name}Region()))) return vec4(0.0);` : ''}
28
- return texelFetch(${name}, fM, level);
26
+ vec4 load_${name}(ivec2 fQ, int level) {
27
+ ${scratch ? `if (any(lessThan(fQ, ivec2(0))) || any(greaterThanEqual(fQ, ${name}Region()))) return vec4(0.0);` : ''}
28
+ return texelFetch(${name}, fQ, level);
29
29
  }
30
- vec4 sample_${name}(vec2 fD) {
30
+ vec4 sample_${name}(vec2 fH) {
31
31
  ${scratch ? /* glsl */ `
32
- ivec2 jV = textureSize(${name}, 0);
33
- if (all(equal(jV, ${name}Region()))) return texture(${name}, fD);
34
- vec2 fM = clamp(fD * vec2(${name}Region()), vec2(0.5), vec2(${name}Region()) - vec2(0.5));
35
- return texture(${name}, fM / vec2(jV));`
36
- : `return texture(${name}, fD);`}
32
+ ivec2 kc = textureSize(${name}, 0);
33
+ if (all(equal(kc, ${name}Region()))) return texture(${name}, fH);
34
+ vec2 fQ = clamp(fH * vec2(${name}Region()), vec2(0.5), vec2(${name}Region()) - vec2(0.5));
35
+ return texture(${name}, fQ / vec2(kc));`
36
+ : `return texture(${name}, fH);`}
37
37
  }`).join('');
38
38
  }
39
39
  //# sourceMappingURL=scratchSampling.js.map
@@ -11,12 +11,12 @@ const ROUGHNESS_MIN = 0.001;
11
11
 
12
12
 
13
13
 
14
- fn rI(position: vec3f, geometricNormal: vec3f, direction: vec3f) -> vec3f {
14
+ fn rQ(position: vec3f, geometricNormal: vec3f, direction: vec3f) -> vec3f {
15
15
  let normal = select(-geometricNormal, geometricNormal, dot(geometricNormal, direction) >= 0.0);
16
- let qc = vec3i(256.0 * normal);
16
+ let qk = vec3i(256.0 * normal);
17
17
  let bits = bitcast<vec3i>(position);
18
- let vH = bitcast<vec3f>(bits + select(qc, -qc, position < vec3f(0.0)));
19
- return select(vH, position + normal / 65536.0, abs(position) < vec3f(1.0 / 32.0));
18
+ let vO = bitcast<vec3f>(bits + select(qk, -qk, position < vec3f(0.0)));
19
+ return select(vO, position + normal / 65536.0, abs(position) < vec3f(1.0 / 32.0));
20
20
  }
21
21
 
22
22
  `;
@@ -1,2 +1,2 @@
1
- declare const _default: "\n\nfn textureLinear(tex: texture_2d<f32>, _uv: vec2f) -> vec4f {\n // #ifdef OES_texture_float_linear\n // return texture(map, uv);\n // #else\n let size = vec2f(textureDimensions(tex, 0));\n\n let uv2f = _uv * size - vec2f(0.5);\n let uvFloor = floor(uv2f);\n let f = fract(uv2f);\n let uv2i = vec2i(uvFloor);\n let maximum = vec2i(size) - vec2i(1);\n\n // TODO use textureGather\n let s1 = textureLoad(tex, clamp(uv2i + vec2i(0, 0), vec2i(0), maximum), 0);\n let s2 = textureLoad(tex, clamp(uv2i + vec2i(1, 0), vec2i(0), maximum), 0);\n let s3 = textureLoad(tex, clamp(uv2i + vec2i(0, 1), vec2i(0), maximum), 0);\n let s4 = textureLoad(tex, clamp(uv2i + vec2i(1, 1), vec2i(0), maximum), 0);\n\n return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y);\n // #endif\n}\n\nfn cartesianToEquirect(pointOnSphere: vec3f) -> vec2f {\n var phi = atan2(-pointOnSphere.z, -pointOnSphere.x);\n if (phi < 0.0) {\n phi += TWOPI;\n }\n let theta = acos(pointOnSphere.y);\n return vec2f(phi * 0.5 * INVPI, theta * INVPI);\n}\n\nfn getEnvmapV(u: f32, vOffset: ptr<function, i32>, pdf: ptr<function, vec2f>) -> f32 {\n let size = vec2i(textureDimensions(envMap, 0));\n\n var left = 0;\n var right = size.y + 1; // cdf length is the length of the env map + 1\n while (left < right) {\n let mid = (left + right) >> 1;\n let s = textureLoad(envMapDistribution, vec2i(0, mid), 0).x;\n if (s <= u) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n *vOffset = left - 1;\n\n // x channel is cumulative distribution of env map luminance\n // y channel is partial probability density of env map luminance\n let s0 = textureLoad(envMapDistribution, vec2i(0, *vOffset), 0).xy;\n let s1 = textureLoad(envMapDistribution, vec2i(0, *vOffset + 1), 0).xy;\n\n (*pdf).y = s0.y;\n\n return (f32(*vOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.y);\n}\n\nfn getEnvmapU(u: f32, vOffset: i32, pdf: ptr<function, vec2f>) -> f32 {\n let size = vec2i(textureDimensions(envMap, 0));\n\n var left = 0;\n var right = size.x + 1; // cdf length is the length of the env map + 1\n while (left < right) {\n let mid = (left + right) >> 1;\n let s = textureLoad(envMapDistribution, vec2i(1 + mid, vOffset), 0).x;\n if (s <= u) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n let uOffset = left - 1;\n\n // x channel is cumulative distribution of env map luminance\n // y channel is partial probability density of env map luminance\n let s0 = textureLoad(envMapDistribution, vec2i(1 + uOffset, vOffset), 0).xy;\n let s1 = textureLoad(envMapDistribution, vec2i(1 + uOffset + 1, vOffset), 0).xy;\n\n (*pdf).x = s0.y;\n\n return (f32(uOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.x);\n}\n\n// Perform two binary searches to find light direction.\nfn sampleEnvmap(random: vec2f, uv: ptr<function, vec2f>, pdf: ptr<function, f32>) -> vec3f {\n var partialPdf: vec2f;\n var vOffset: i32;\n\n (*uv).y = getEnvmapV(random.x, &vOffset, &partialPdf);\n (*uv).x = getEnvmapU(random.y, vOffset, &partialPdf);\n\n let phi = (*uv).x * TWOPI;\n let theta = (*uv).y * PI;\n let cosTheta = cos(theta);\n let sinTheta = sin(theta);\n let cosPhi = cos(phi);\n let sinPhi = sin(phi);\n\n let dir = vec3f(-sinTheta * cosPhi, cosTheta, -sinTheta * sinPhi);\n\n *pdf = partialPdf.x * partialPdf.y * INVPI2 / (2.0 * sinTheta);\n\n return dir;\n}\n\nfn envMapPdf(_uv: vec2f) -> f32 {\n let size = vec2f(textureDimensions(envMap, 0));\n\n let sinTheta = sin(_uv.y * PI);\n\n let _uv2 = vec2i(_uv * size);\n\n let partialX = textureLoad(envMapDistribution, vec2i(1 + _uv2.x, _uv2.y), 0).y;\n let partialY = textureLoad(envMapDistribution, vec2i(0, _uv2.y), 0).y;\n\n return partialX * partialY * INVPI2 / (2.0 * sinTheta);\n}\n\n\n";
1
+ declare const _default: "\n\nfn textureLinear(tex: texture_2d<f32>, _uv: vec2f) -> vec4f {\n // #ifdef OES_texture_float_linear\n // return texture(map, uv);\n // #else\n let size = vec2f(textureDimensions(tex, 0));\n\n let uv2f = _uv * size - vec2f(0.5);\n let uvFloor = floor(uv2f);\n let f = fract(uv2f);\n let uv2i = vec2i(uvFloor);\n let maximum = vec2i(size) - vec2i(1);\n\n // TODO use textureGather\n let s1 = textureLoad(tex, clamp(uv2i + vec2i(0, 0), vec2i(0), maximum), 0);\n let s2 = textureLoad(tex, clamp(uv2i + vec2i(1, 0), vec2i(0), maximum), 0);\n let s3 = textureLoad(tex, clamp(uv2i + vec2i(0, 1), vec2i(0), maximum), 0);\n let s4 = textureLoad(tex, clamp(uv2i + vec2i(1, 1), vec2i(0), maximum), 0);\n\n return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y);\n // #endif\n}\n\nfn cartesianToEquirect(pointOnSphere: vec3f) -> vec2f {\n var phi = atan2(-pointOnSphere.z, -pointOnSphere.x);\n if (phi < 0.0) {\n phi += TWOPI;\n }\n let theta = acos(clamp(pointOnSphere.y, -1.0, 1.0));\n return vec2f(phi * 0.5 * INVPI, theta * INVPI);\n}\n\nfn environmentOrientation() -> mat3x3f {\n return mat3x3f(rtUniform.environmentRotation[0].xyz, rtUniform.environmentRotation[1].xyz, rtUniform.environmentRotation[2].xyz);\n}\n\nfn environmentUv(worldDirection: vec3f) -> vec2f {\n return cartesianToEquirect(transpose(environmentOrientation()) * worldDirection);\n}\n\nfn getEnvmapV(u: f32, vOffset: ptr<function, i32>, pdf: ptr<function, vec2f>) -> f32 {\n let size = vec2i(textureDimensions(envMap, 0));\n\n var left = 0;\n var right = size.y + 1; // cdf length is the length of the env map + 1\n while (left < right) {\n let mid = (left + right) >> 1;\n let s = textureLoad(envMapDistribution, vec2i(0, mid), 0).x;\n if (s <= u) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n *vOffset = left - 1;\n\n // x channel is cumulative distribution of env map luminance\n // y channel is partial probability density of env map luminance\n let s0 = textureLoad(envMapDistribution, vec2i(0, *vOffset), 0).xy;\n let s1 = textureLoad(envMapDistribution, vec2i(0, *vOffset + 1), 0).xy;\n\n (*pdf).y = s0.y;\n\n return (f32(*vOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.y);\n}\n\nfn getEnvmapU(u: f32, vOffset: i32, pdf: ptr<function, vec2f>) -> f32 {\n let size = vec2i(textureDimensions(envMap, 0));\n\n var left = 0;\n var right = size.x + 1; // cdf length is the length of the env map + 1\n while (left < right) {\n let mid = (left + right) >> 1;\n let s = textureLoad(envMapDistribution, vec2i(1 + mid, vOffset), 0).x;\n if (s <= u) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n let uOffset = left - 1;\n\n // x channel is cumulative distribution of env map luminance\n // y channel is partial probability density of env map luminance\n let s0 = textureLoad(envMapDistribution, vec2i(1 + uOffset, vOffset), 0).xy;\n let s1 = textureLoad(envMapDistribution, vec2i(1 + uOffset + 1, vOffset), 0).xy;\n\n (*pdf).x = s0.y;\n\n return (f32(uOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.x);\n}\n\n// Perform two binary searches to find light direction.\nfn sampleEnvmap(random: vec2f, uv: ptr<function, vec2f>, pdf: ptr<function, f32>) -> vec3f {\n var partialPdf: vec2f;\n var vOffset: i32;\n\n (*uv).y = getEnvmapV(random.x, &vOffset, &partialPdf);\n (*uv).x = getEnvmapU(random.y, vOffset, &partialPdf);\n\n let phi = (*uv).x * TWOPI;\n let theta = (*uv).y * PI;\n let cosTheta = cos(theta);\n let sinTheta = sin(theta);\n let cosPhi = cos(phi);\n let sinPhi = sin(phi);\n\n let dir = vec3f(-sinTheta * cosPhi, cosTheta, -sinTheta * sinPhi);\n\n *pdf = partialPdf.x * partialPdf.y * INVPI2 / (2.0 * sinTheta);\n\n return environmentOrientation() * dir;\n}\n\nfn envMapPdf(_uv: vec2f) -> f32 {\n let size = vec2f(textureDimensions(envMap, 0));\n\n let sinTheta = sin(_uv.y * PI);\n\n let _uv2 = vec2i(_uv * size);\n\n let partialX = textureLoad(envMapDistribution, vec2i(1 + _uv2.x, _uv2.y), 0).y;\n let partialY = textureLoad(envMapDistribution, vec2i(0, _uv2.y), 0).y;\n\n return partialX * partialY * INVPI2 / (2.0 * sinTheta);\n}\n\n\n";
2
2
  export default _default;
@@ -11,32 +11,40 @@ fn textureLinear(tex: texture_2d<f32>, _uv: vec2f) -> vec4f {
11
11
 
12
12
  let size = vec2f(textureDimensions(tex, 0));
13
13
 
14
- let wF = _uv * size - vec2f(0.5);
15
- let vM = floor(wF);
16
- let f = fract(wF);
17
- let vL = vec2i(vM);
14
+ let wN = _uv * size - vec2f(0.5);
15
+ let vT = floor(wN);
16
+ let f = fract(wN);
17
+ let vS = vec2i(vT);
18
18
  let maximum = vec2i(size) - vec2i(1);
19
19
 
20
20
 
21
- let s1 = textureLoad(tex, clamp(vL + vec2i(0, 0), vec2i(0), maximum), 0);
22
- let s2 = textureLoad(tex, clamp(vL + vec2i(1, 0), vec2i(0), maximum), 0);
23
- let s3 = textureLoad(tex, clamp(vL + vec2i(0, 1), vec2i(0), maximum), 0);
24
- let s4 = textureLoad(tex, clamp(vL + vec2i(1, 1), vec2i(0), maximum), 0);
21
+ let s1 = textureLoad(tex, clamp(vS + vec2i(0, 0), vec2i(0), maximum), 0);
22
+ let s2 = textureLoad(tex, clamp(vS + vec2i(1, 0), vec2i(0), maximum), 0);
23
+ let s3 = textureLoad(tex, clamp(vS + vec2i(0, 1), vec2i(0), maximum), 0);
24
+ let s4 = textureLoad(tex, clamp(vS + vec2i(1, 1), vec2i(0), maximum), 0);
25
25
 
26
26
  return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y);
27
27
 
28
28
  }
29
29
 
30
- fn aS(gc: vec3f) -> vec2f {
31
- var phi = atan2(-gc.z, -gc.x);
30
+ fn eL(gh: vec3f) -> vec2f {
31
+ var phi = atan2(-gh.z, -gh.x);
32
32
  if (phi < 0.0) {
33
33
  phi += TWOPI;
34
34
  }
35
- let theta = acos(gc.y);
35
+ let theta = acos(clamp(gh.y, -1.0, 1.0));
36
36
  return vec2f(phi * 0.5 * INVPI, theta * INVPI);
37
37
  }
38
38
 
39
- fn qt(u: f32, vOffset: ptr<function, i32>, pdf: ptr<function, vec2f>) -> f32 {
39
+ fn jN() -> mat3x3f {
40
+ return mat3x3f(rtUniform.environmentRotation[0].xyz, rtUniform.environmentRotation[1].xyz, rtUniform.environmentRotation[2].xyz);
41
+ }
42
+
43
+ fn cY(mP: vec3f) -> vec2f {
44
+ return eL(transpose(jN()) * mP);
45
+ }
46
+
47
+ fn qB(u: f32, vOffset: ptr<function, i32>, pdf: ptr<function, vec2f>) -> f32 {
40
48
  let size = vec2i(textureDimensions(envMap, 0));
41
49
 
42
50
  var left = 0;
@@ -62,7 +70,7 @@ let s1 = textureLoad(envMapDistribution, vec2i(0, *vOffset + 1), 0).xy;
62
70
  return (f32(*vOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.y);
63
71
  }
64
72
 
65
- fn qs(u: f32, vOffset: i32, pdf: ptr<function, vec2f>) -> f32 {
73
+ fn qA(u: f32, vOffset: i32, pdf: ptr<function, vec2f>) -> f32 {
66
74
  let size = vec2i(textureDimensions(envMap, 0));
67
75
 
68
76
  var left = 0;
@@ -76,51 +84,51 @@ left = mid + 1;
76
84
  right = mid;
77
85
  }
78
86
  }
79
- let oJ = left - 1;
87
+ let oR = left - 1;
80
88
 
81
89
 
82
90
 
83
- let s0 = textureLoad(envMapDistribution, vec2i(1 + oJ, vOffset), 0).xy;
84
- let s1 = textureLoad(envMapDistribution, vec2i(1 + oJ + 1, vOffset), 0).xy;
91
+ let s0 = textureLoad(envMapDistribution, vec2i(1 + oR, vOffset), 0).xy;
92
+ let s1 = textureLoad(envMapDistribution, vec2i(1 + oR + 1, vOffset), 0).xy;
85
93
 
86
94
  (*pdf).x = s0.y;
87
95
 
88
- return (f32(oJ) + (u - s0.x) / (s1.x - s0.x)) / f32(size.x);
96
+ return (f32(oR) + (u - s0.x) / (s1.x - s0.x)) / f32(size.x);
89
97
  }
90
98
 
91
99
 
92
- fn oD(random: vec2f, uv: ptr<function, vec2f>, pdf: ptr<function, f32>) -> vec3f {
93
- var gZ: vec2f;
100
+ fn oL(random: vec2f, uv: ptr<function, vec2f>, pdf: ptr<function, f32>) -> vec3f {
101
+ var he: vec2f;
94
102
  var vOffset: i32;
95
103
 
96
- (*uv).y = qt(random.x, &vOffset, &gZ);
97
- (*uv).x = qs(random.y, vOffset, &gZ);
104
+ (*uv).y = qB(random.x, &vOffset, &he);
105
+ (*uv).x = qA(random.y, vOffset, &he);
98
106
 
99
107
  let phi = (*uv).x * TWOPI;
100
108
  let theta = (*uv).y * PI;
101
109
  let cc = cos(theta);
102
110
  let sinTheta = sin(theta);
103
- let ue = cos(phi);
104
- let um = sin(phi);
111
+ let ul = cos(phi);
112
+ let uw = sin(phi);
105
113
 
106
- let dir = vec3f(-sinTheta * ue, cc, -sinTheta * um);
114
+ let dir = vec3f(-sinTheta * ul, cc, -sinTheta * uw);
107
115
 
108
- *pdf = gZ.x * gZ.y * INVPI2 / (2.0 * sinTheta);
116
+ *pdf = he.x * he.y * INVPI2 / (2.0 * sinTheta);
109
117
 
110
- return dir;
118
+ return jN() * dir;
111
119
  }
112
120
 
113
- fn iv(_uv: vec2f) -> f32 {
121
+ fn iB(_uv: vec2f) -> f32 {
114
122
  let size = vec2f(textureDimensions(envMap, 0));
115
123
 
116
124
  let sinTheta = sin(_uv.y * PI);
117
125
 
118
- let vQ = vec2i(_uv * size);
126
+ let vX = vec2i(_uv * size);
119
127
 
120
- let sD = textureLoad(envMapDistribution, vec2i(1 + vQ.x, vQ.y), 0).y;
121
- let sE = textureLoad(envMapDistribution, vec2i(0, vQ.y), 0).y;
128
+ let sL = textureLoad(envMapDistribution, vec2i(1 + vX.x, vX.y), 0).y;
129
+ let sM = textureLoad(envMapDistribution, vec2i(0, vX.y), 0).y;
122
130
 
123
- return sD * sE * INVPI2 / (2.0 * sinTheta);
131
+ return sL * sM * INVPI2 / (2.0 * sinTheta);
124
132
  }
125
133
 
126
134
 
@@ -1 +1 @@
1
- {"version":3,"file":"envMap.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/envMap.wgsl.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,sFAAsF;AACtF,uHAAuH;AAEvH,eAAe,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyHzB,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\n// Sample the environment map using a cumulative distribution function as described in\n// http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Sampling_Light_Sources.html#InfiniteAreaLights\n\nexport default /* wgsl */ `\n\nfn textureLinear(tex: texture_2d<f32>, _uv: vec2f) -> vec4f {\n // #ifdef OES_texture_float_linear\n // return texture(map, uv);\n // #else\n let size = vec2f(textureDimensions(tex, 0));\n\n let uv2f = _uv * size - vec2f(0.5);\n let uvFloor = floor(uv2f);\n let f = fract(uv2f);\n let uv2i = vec2i(uvFloor);\n let maximum = vec2i(size) - vec2i(1);\n\n // TODO use textureGather\n let s1 = textureLoad(tex, clamp(uv2i + vec2i(0, 0), vec2i(0), maximum), 0);\n let s2 = textureLoad(tex, clamp(uv2i + vec2i(1, 0), vec2i(0), maximum), 0);\n let s3 = textureLoad(tex, clamp(uv2i + vec2i(0, 1), vec2i(0), maximum), 0);\n let s4 = textureLoad(tex, clamp(uv2i + vec2i(1, 1), vec2i(0), maximum), 0);\n\n return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y);\n // #endif\n}\n\nfn cartesianToEquirect(pointOnSphere: vec3f) -> vec2f {\n var phi = atan2(-pointOnSphere.z, -pointOnSphere.x);\n if (phi < 0.0) {\n phi += TWOPI;\n }\n let theta = acos(pointOnSphere.y);\n return vec2f(phi * 0.5 * INVPI, theta * INVPI);\n}\n\nfn getEnvmapV(u: f32, vOffset: ptr<function, i32>, pdf: ptr<function, vec2f>) -> f32 {\n let size = vec2i(textureDimensions(envMap, 0));\n\n var left = 0;\n var right = size.y + 1; // cdf length is the length of the env map + 1\n while (left < right) {\n let mid = (left + right) >> 1;\n let s = textureLoad(envMapDistribution, vec2i(0, mid), 0).x;\n if (s <= u) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n *vOffset = left - 1;\n\n // x channel is cumulative distribution of env map luminance\n // y channel is partial probability density of env map luminance\n let s0 = textureLoad(envMapDistribution, vec2i(0, *vOffset), 0).xy;\n let s1 = textureLoad(envMapDistribution, vec2i(0, *vOffset + 1), 0).xy;\n\n (*pdf).y = s0.y;\n\n return (f32(*vOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.y);\n}\n\nfn getEnvmapU(u: f32, vOffset: i32, pdf: ptr<function, vec2f>) -> f32 {\n let size = vec2i(textureDimensions(envMap, 0));\n\n var left = 0;\n var right = size.x + 1; // cdf length is the length of the env map + 1\n while (left < right) {\n let mid = (left + right) >> 1;\n let s = textureLoad(envMapDistribution, vec2i(1 + mid, vOffset), 0).x;\n if (s <= u) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n let uOffset = left - 1;\n\n // x channel is cumulative distribution of env map luminance\n // y channel is partial probability density of env map luminance\n let s0 = textureLoad(envMapDistribution, vec2i(1 + uOffset, vOffset), 0).xy;\n let s1 = textureLoad(envMapDistribution, vec2i(1 + uOffset + 1, vOffset), 0).xy;\n\n (*pdf).x = s0.y;\n\n return (f32(uOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.x);\n}\n\n// Perform two binary searches to find light direction.\nfn sampleEnvmap(random: vec2f, uv: ptr<function, vec2f>, pdf: ptr<function, f32>) -> vec3f {\n var partialPdf: vec2f;\n var vOffset: i32;\n\n (*uv).y = getEnvmapV(random.x, &vOffset, &partialPdf);\n (*uv).x = getEnvmapU(random.y, vOffset, &partialPdf);\n\n let phi = (*uv).x * TWOPI;\n let theta = (*uv).y * PI;\n let cosTheta = cos(theta);\n let sinTheta = sin(theta);\n let cosPhi = cos(phi);\n let sinPhi = sin(phi);\n\n let dir = vec3f(-sinTheta * cosPhi, cosTheta, -sinTheta * sinPhi);\n\n *pdf = partialPdf.x * partialPdf.y * INVPI2 / (2.0 * sinTheta);\n\n return dir;\n}\n\nfn envMapPdf(_uv: vec2f) -> f32 {\n let size = vec2f(textureDimensions(envMap, 0));\n\n let sinTheta = sin(_uv.y * PI);\n\n let _uv2 = vec2i(_uv * size);\n\n let partialX = textureLoad(envMapDistribution, vec2i(1 + _uv2.x, _uv2.y), 0).y;\n let partialY = textureLoad(envMapDistribution, vec2i(0, _uv2.y), 0).y;\n\n return partialX * partialY * INVPI2 / (2.0 * sinTheta);\n}\n\n\n`;\n"]}
1
+ {"version":3,"file":"envMap.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/envMap.wgsl.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,sFAAsF;AACtF,uHAAuH;AAEvH,eAAe,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiIzB,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\n// Sample the environment map using a cumulative distribution function as described in\n// http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Sampling_Light_Sources.html#InfiniteAreaLights\n\nexport default /* wgsl */ `\n\nfn textureLinear(tex: texture_2d<f32>, _uv: vec2f) -> vec4f {\n // #ifdef OES_texture_float_linear\n // return texture(map, uv);\n // #else\n let size = vec2f(textureDimensions(tex, 0));\n\n let uv2f = _uv * size - vec2f(0.5);\n let uvFloor = floor(uv2f);\n let f = fract(uv2f);\n let uv2i = vec2i(uvFloor);\n let maximum = vec2i(size) - vec2i(1);\n\n // TODO use textureGather\n let s1 = textureLoad(tex, clamp(uv2i + vec2i(0, 0), vec2i(0), maximum), 0);\n let s2 = textureLoad(tex, clamp(uv2i + vec2i(1, 0), vec2i(0), maximum), 0);\n let s3 = textureLoad(tex, clamp(uv2i + vec2i(0, 1), vec2i(0), maximum), 0);\n let s4 = textureLoad(tex, clamp(uv2i + vec2i(1, 1), vec2i(0), maximum), 0);\n\n return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y);\n // #endif\n}\n\nfn cartesianToEquirect(pointOnSphere: vec3f) -> vec2f {\n var phi = atan2(-pointOnSphere.z, -pointOnSphere.x);\n if (phi < 0.0) {\n phi += TWOPI;\n }\n let theta = acos(clamp(pointOnSphere.y, -1.0, 1.0));\n return vec2f(phi * 0.5 * INVPI, theta * INVPI);\n}\n\nfn environmentOrientation() -> mat3x3f {\n return mat3x3f(rtUniform.environmentRotation[0].xyz, rtUniform.environmentRotation[1].xyz, rtUniform.environmentRotation[2].xyz);\n}\n\nfn environmentUv(worldDirection: vec3f) -> vec2f {\n return cartesianToEquirect(transpose(environmentOrientation()) * worldDirection);\n}\n\nfn getEnvmapV(u: f32, vOffset: ptr<function, i32>, pdf: ptr<function, vec2f>) -> f32 {\n let size = vec2i(textureDimensions(envMap, 0));\n\n var left = 0;\n var right = size.y + 1; // cdf length is the length of the env map + 1\n while (left < right) {\n let mid = (left + right) >> 1;\n let s = textureLoad(envMapDistribution, vec2i(0, mid), 0).x;\n if (s <= u) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n *vOffset = left - 1;\n\n // x channel is cumulative distribution of env map luminance\n // y channel is partial probability density of env map luminance\n let s0 = textureLoad(envMapDistribution, vec2i(0, *vOffset), 0).xy;\n let s1 = textureLoad(envMapDistribution, vec2i(0, *vOffset + 1), 0).xy;\n\n (*pdf).y = s0.y;\n\n return (f32(*vOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.y);\n}\n\nfn getEnvmapU(u: f32, vOffset: i32, pdf: ptr<function, vec2f>) -> f32 {\n let size = vec2i(textureDimensions(envMap, 0));\n\n var left = 0;\n var right = size.x + 1; // cdf length is the length of the env map + 1\n while (left < right) {\n let mid = (left + right) >> 1;\n let s = textureLoad(envMapDistribution, vec2i(1 + mid, vOffset), 0).x;\n if (s <= u) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n let uOffset = left - 1;\n\n // x channel is cumulative distribution of env map luminance\n // y channel is partial probability density of env map luminance\n let s0 = textureLoad(envMapDistribution, vec2i(1 + uOffset, vOffset), 0).xy;\n let s1 = textureLoad(envMapDistribution, vec2i(1 + uOffset + 1, vOffset), 0).xy;\n\n (*pdf).x = s0.y;\n\n return (f32(uOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.x);\n}\n\n// Perform two binary searches to find light direction.\nfn sampleEnvmap(random: vec2f, uv: ptr<function, vec2f>, pdf: ptr<function, f32>) -> vec3f {\n var partialPdf: vec2f;\n var vOffset: i32;\n\n (*uv).y = getEnvmapV(random.x, &vOffset, &partialPdf);\n (*uv).x = getEnvmapU(random.y, vOffset, &partialPdf);\n\n let phi = (*uv).x * TWOPI;\n let theta = (*uv).y * PI;\n let cosTheta = cos(theta);\n let sinTheta = sin(theta);\n let cosPhi = cos(phi);\n let sinPhi = sin(phi);\n\n let dir = vec3f(-sinTheta * cosPhi, cosTheta, -sinTheta * sinPhi);\n\n *pdf = partialPdf.x * partialPdf.y * INVPI2 / (2.0 * sinTheta);\n\n return environmentOrientation() * dir;\n}\n\nfn envMapPdf(_uv: vec2f) -> f32 {\n let size = vec2f(textureDimensions(envMap, 0));\n\n let sinTheta = sin(_uv.y * PI);\n\n let _uv2 = vec2i(_uv * size);\n\n let partialX = textureLoad(envMapDistribution, vec2i(1 + _uv2.x, _uv2.y), 0).y;\n let partialY = textureLoad(envMapDistribution, vec2i(0, _uv2.y), 0).y;\n\n return partialX * partialY * INVPI2 / (2.0 * sinTheta);\n}\n\n\n`;\n"]}