@meimu/mutracer 0.1.1 → 0.1.2

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 (69) hide show
  1. package/dist/assets/bvh.worker.js +1 -1
  2. package/dist/mutracer.umd.js +522 -520
  3. package/docs/materials.md +27 -7
  4. package/docs/threejs.md +13 -2
  5. package/docs/viewer.md +53 -0
  6. package/lib/oidn.d.ts +1 -1
  7. package/lib/oidnBundledWeights.cdn.d.ts +2 -2
  8. package/lib/renderer/MaterialTable.d.ts +1 -0
  9. package/lib/renderer/MaterialTable.js +2 -1
  10. package/lib/renderer/MaterialTable.js.map +1 -1
  11. package/lib/renderer/WGPUBloomPass.js +8 -8
  12. package/lib/renderer/WGPUJNLMDenoiser.js +2 -2
  13. package/lib/renderer/WGPURayTraceOutput.js +5 -5
  14. package/lib/renderer/WGPURayTracePass.js +1 -1
  15. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  16. package/lib/renderer/WGPURenderingPipeline.js +4 -4
  17. package/lib/renderer/WebGLJNLMDenoiser.js +2 -2
  18. package/lib/renderer/WebGLRayTracePass.js +3 -1
  19. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  20. package/lib/renderer/glsl/chunks/envMap.glsl.js +5 -5
  21. package/lib/renderer/glsl/chunks/intersect.glsl.js +32 -32
  22. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +9 -9
  23. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +30 -30
  24. package/lib/renderer/glsl/chunks/rand.glsl.js +2 -2
  25. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +4 -4
  26. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +3 -3
  27. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +4 -4
  28. package/lib/renderer/glsl/chunks/sampling.glsl.js +3 -3
  29. package/lib/renderer/glsl/chunks/sobol.glsl.js +3 -3
  30. package/lib/renderer/glsl/rayTrace.frag.js +3 -3
  31. package/lib/renderer/glsl/webglPipeline.frag.js +2 -2
  32. package/lib/renderer/materialComparison.generated.js +5 -0
  33. package/lib/renderer/materialComparison.generated.js.map +1 -1
  34. package/lib/renderer/materialLayout.js +2 -1
  35. package/lib/renderer/materialLayout.js.map +1 -1
  36. package/lib/renderer/prepareMeshBVH.d.ts +4 -2
  37. package/lib/renderer/prepareMeshBVH.js +44 -20
  38. package/lib/renderer/prepareMeshBVH.js.map +1 -1
  39. package/lib/renderer/wgsl/chunks/common.wgsl.js +2 -2
  40. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +14 -14
  41. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +85 -88
  42. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  43. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +34 -34
  44. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.d.ts +1 -1
  45. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +51 -46
  46. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js.map +1 -1
  47. package/lib/renderer/wgsl/chunks/rand.wgsl.js +2 -2
  48. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +3 -3
  49. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +4 -4
  50. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +4 -4
  51. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +3 -3
  52. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +3 -3
  53. package/lib/renderer/wgsl/compose.frag.wgsl.js +2 -2
  54. package/lib/renderer/wgsl/customDenoise.wgsl.js +4 -4
  55. package/lib/renderer/wgsl/offlineAdaptive.compute.js +10 -10
  56. package/lib/renderer/wgsl/rayTrace.compute.js +7 -7
  57. package/lib/scene/OpenPBRMaterial.d.ts +4 -2
  58. package/lib/scene/OpenPBRMaterial.js +4 -2
  59. package/lib/scene/OpenPBRMaterial.js.map +1 -1
  60. package/lib/scene/openPbrSchema.d.ts +7 -2
  61. package/lib/scene/openPbrSchema.js +2 -1
  62. package/lib/scene/openPbrSchema.js.map +1 -1
  63. package/lib/util/fromTHREE.d.ts +1 -0
  64. package/lib/util/fromTHREE.js +24 -6
  65. package/lib/util/fromTHREE.js.map +1 -1
  66. package/lib/version.d.ts +1 -1
  67. package/lib/version.js +1 -1
  68. package/lib/version.js.map +1 -1
  69. package/package.json +1 -1
@@ -122,18 +122,18 @@ let cp = bA - f32(dP);
122
122
  let cy = aG - f32(aM);
123
123
  let ku = bt - f32(cI);
124
124
 
125
- let uk = F(cI, dP * 32 + aM);
126
- let ul = F(eO, dP * 32 + aM);
127
- let um = F(cI, dP * 32 + cn);
128
- let un = F(eO, dP * 32 + cn);
129
- let uo = F(cI, hB * 32 + aM);
130
- let uq = F(eO, hB * 32 + aM);
131
- let ur = F(cI, hB * 32 + cn);
132
- let us = F(eO, hB * 32 + cn);
133
- let v00 = mix(uk, uo, cp);
134
- let v01 = mix(ul, uq, cp);
135
- let v10 = mix(um, ur, cp);
136
- let v11 = mix(un, us, cp);
125
+ let ul = F(cI, dP * 32 + aM);
126
+ let um = F(eO, dP * 32 + aM);
127
+ let un = F(cI, dP * 32 + cn);
128
+ let uo = F(eO, dP * 32 + cn);
129
+ let uq = F(cI, hB * 32 + aM);
130
+ let ur = F(eO, hB * 32 + aM);
131
+ let us = F(cI, hB * 32 + cn);
132
+ let ut = F(eO, hB * 32 + cn);
133
+ let v00 = mix(ul, uq, cp);
134
+ let v01 = mix(um, ur, cp);
135
+ let v10 = mix(un, us, cp);
136
+ let v11 = mix(uo, ut, cp);
137
137
  return mix(
138
138
  mix(v00, v10, cy),
139
139
  mix(v01, v11, cy),
@@ -181,18 +181,18 @@ let cp = bA - f32(dP);
181
181
  let cy = aG - f32(aM);
182
182
  let ku = bt - f32(cI);
183
183
 
184
- let uk = F(cI, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + dP * 32 + aM);
185
- let ul = F(eO, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + dP * 32 + aM);
186
- let um = F(cI, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + dP * 32 + cn);
187
- let un = F(eO, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + dP * 32 + cn);
188
- let uo = F(cI, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + hB * 32 + aM);
189
- let uq = F(eO, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + hB * 32 + aM);
190
- let ur = F(cI, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + hB * 32 + cn);
191
- let us = F(eO, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + hB * 32 + cn);
192
- let v00 = mix(uk, uo, cp);
193
- let v01 = mix(ul, uq, cp);
194
- let v10 = mix(um, ur, cp);
195
- let v11 = mix(un, us, cp);
184
+ let ul = F(cI, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + dP * 32 + aM);
185
+ let um = F(eO, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + dP * 32 + aM);
186
+ let un = F(cI, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + dP * 32 + cn);
187
+ let uo = F(eO, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + dP * 32 + cn);
188
+ let uq = F(cI, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + hB * 32 + aM);
189
+ let ur = F(eO, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + hB * 32 + aM);
190
+ let us = F(cI, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + hB * 32 + cn);
191
+ let ut = F(eO, ${OPENPBR_DIELECTRIC_ENERGY_LUT_ROW} + hB * 32 + cn);
192
+ let v00 = mix(ul, uq, cp);
193
+ let v01 = mix(um, ur, cp);
194
+ let v10 = mix(un, us, cp);
195
+ let v11 = mix(uo, ut, cp);
196
196
  return mix(
197
197
  mix(v00, v10, cy),
198
198
  mix(v01, v11, cy),
@@ -798,17 +798,17 @@ let material = prepared.material;
798
798
  let dielectric = 1.0 - material.baseMetalness;
799
799
  let opaque = dielectric * (1.0 - material.transmissionWeight) * (1.0 - material.subsurfaceWeight);
800
800
  let sss = dielectric * (1.0 - material.transmissionWeight) * material.subsurfaceWeight;
801
- let tT = dielectric * material.transmissionWeight;
801
+ let tU = dielectric * material.transmissionWeight;
802
802
  let fL = bM(prepared.specularEtaTOverEtaI);
803
803
  let kI = bM(1.0 / prepared.transmissionReflectionIor);
804
- let pw = clamp(opaque * fL + (sss + tT) * kI + material.baseMetalness, 0.0, 1.0);
804
+ let pw = clamp(opaque * fL + (sss + tU) * kI + material.baseMetalness, 0.0, 1.0);
805
805
  let ji = mix(1.0, material.specularRoughness, pw);
806
806
  let ks = bM(material.coatIor);
807
807
  let kr = 1.0 - (1.0 - ks) / (material.coatIor * material.coatIor);
808
808
  let k = mix(ks, kr, ji);
809
809
  let eb = material.baseMetalness * material.specularWeight * bP(material.baseWeight * material.baseColor, material.specularColor)
810
810
  + opaque * mix(material.baseWeight * material.baseColor, vec3f(1.0), fL)
811
- + sss * material.subsurfaceColor + vec3f(tT);
811
+ + sss * material.subsurfaceColor + vec3f(tU);
812
812
  let qH = vec3f(1.0 - k) / max(vec3f(1.0) - eb * k, vec3f(1e-6));
813
813
  return mix(vec3f(1.0), qH, material.coatWeight * material.coatDarkening);
814
814
  }
@@ -1108,7 +1108,7 @@ var response = vec3f(0.0);
1108
1108
  *pdf = 0.0;
1109
1109
  var aH = 0.0;
1110
1110
  let lQ = gI < 0;
1111
- let uz = lQ || gI == OPENPBR_LOBE_FUZZ;
1111
+ let uB = lQ || gI == OPENPBR_LOBE_FUZZ;
1112
1112
  let sQ = lQ || gI == OPENPBR_LOBE_COAT;
1113
1113
  let rT = lQ || gI == OPENPBR_LOBE_METAL;
1114
1114
  let pT = lQ || gI == OPENPBR_LOBE_SPECULAR;
@@ -1144,17 +1144,17 @@ let wavelengths = vec3f(620.0, 540.0, 450.0);
1144
1144
 
1145
1145
  for (var kH = 0u; kH < (rtUniform.loopUnrollGuard >> 1u); kH++) {
1146
1146
  if (!select(lZ, pX, kH == 1u)) { continue; }
1147
- var wb = vec3f(0.0);
1147
+ var wc = vec3f(0.0);
1148
1148
  let L = select(jg, bQ, kH == 1u);
1149
1149
  for (var channel = 0u; channel + 1u < rtUniform.loopUnrollGuard; channel++) {
1150
1150
  var ior = vec2f(prepared.thinFilmBaseIor, 0.0);
1151
1151
  if (kH == 1u) {
1152
1152
  ior = cQ(material.baseWeight * material.baseColor[channel], material.specularColor[channel]);
1153
1153
  }
1154
- wb[channel] = ar(L,
1154
+ wc[channel] = ar(L,
1155
1155
  wavelengths[channel], material.thinFilmThickness, prepared.thinFilmExteriorIor, material.thinFilmIor, ior);
1156
1156
  }
1157
- nj[kH] = mix(nj[kH], wb,
1157
+ nj[kH] = mix(nj[kH], wc,
1158
1158
  bN(material.thinFilmThickness, material.thinFilmWeight));
1159
1159
  }
1160
1160
  }
@@ -1396,7 +1396,7 @@ response *= max(
1396
1396
  vec3f(0.0),
1397
1397
  vec3f(1.0 - prepared.weights[OPENPBR_LOBE_FUZZ] * qn)
1398
1398
  );
1399
- if (uz) {
1399
+ if (uB) {
1400
1400
  response += prepared.weights[OPENPBR_LOBE_FUZZ]${hasCoatNormals ? ' * select(1.0, max(lightLocal.z, 0.0), independentCoat)' : ''} * jP(
1401
1401
  material,
1402
1402
  viewLocal,
@@ -1567,8 +1567,8 @@ else if (bm < cdf[OPENPBR_LOBE_TRANSMISSION]) {
1567
1567
  *aR = u32(OPENPBR_LOBE_TRANSMISSION);
1568
1568
 
1569
1569
 
1570
- let ue = (bm - cdf[OPENPBR_LOBE_SPECULAR]) / max(prepared.probabilities[OPENPBR_LOBE_TRANSMISSION], 1e-12);
1571
- if (prepared.dielectricMsProbability > 0.0 && ue < prepared.dielectricMsProbability) {
1570
+ let uf = (bm - cdf[OPENPBR_LOBE_SPECULAR]) / max(prepared.probabilities[OPENPBR_LOBE_TRANSMISSION], 1e-12);
1571
+ if (prepared.dielectricMsProbability > 0.0 && uf < prepared.dielectricMsProbability) {
1572
1572
  let iU = prepared.dielectricMsReflectionRatio;
1573
1573
  let lM = cx < iU;
1574
1574
  var z: f32;
@@ -1,4 +1,4 @@
1
1
  declare const displacementCommon = "\n\n\nstruct MicroTriangleIntersect {\n barycentric: vec3f,\n t: f32,\n normal: vec3f,\n\n}\n\nfn findVT(\n uu: f32,\n pARel: vec3f, pBRel: vec3f,\n eAC: vec3f, eBD: vec3f,\n rayDir: vec3f,\n distMin: f32,\n hitDist: ptr<function, f32>\n) -> bool {\n if (uu >= 0.0 && uu <= 1.0) {\n let pAB = mix(pARel, pBRel, uu);\n let pCD = mix(eAC, eBD, uu);\n var n = cross(rayDir, pCD);\n let recDet = 1.0 / dot(n, n);\n n = cross(n, pAB);\n let tt = dot(n, pCD) * recDet;\n let vv = dot(n, rayDir) * recDet;\n if (vv >= 0.0 && vv <= 1.0 && tt > distMin && tt < *hitDist) {\n *hitDist = tt;\n return true;\n }\n }\n return false;\n}\n\nfn testRayVsBilinearPatch(\n rayOrg: vec3f, rayDir: vec3f, distMin: f32, distMax: f32,\n pA: vec3f, pB: vec3f, pC: vec3f, pD: vec3f,\n hitDist: ptr<function, f32>\n) -> bool {\n let eAB = pB - pA;\n let eAC = pC - pA;\n let eBD = pD - pB;\n let eCD = pD - pC;\n let pARel = pA - rayOrg;\n let pBRel = pB - rayOrg;\n\n var u1: f32;\n var u2: f32;\n {\n let qN = cross(eAB, -eCD);\n let a = dot(qN, rayDir);\n var b = dot(cross(pBRel, rayDir), eBD);\n let c = dot(cross(pARel, rayDir), eAC);\n b -= a + c;\n\n let det = b * b - 4.0 * a * c;\n if (det < 0.0) {\n return false;\n }\n\n if (a == 0.0) {\n u1 = -c / b;\n u2 = -1.0;\n } else {\n let sqrtDet = sqrt(det);\n let temp = -0.5 * (b + sign(b) * sqrtDet);\n u1 = temp / a;\n u2 = c / temp;\n }\n }\n\n *hitDist = distMax;\n\n var hit = false;\n\n hit = findVT(u1, pARel, pBRel, eAC, eBD, rayDir, distMin, hitDist) || \n findVT(u2, pARel, pBRel, eAC, eBD, rayDir, distMin, hitDist);\n if (!hit) {\n return false;\n }\n\n return true;\n}\n\nfn intersectPrism(\n rayOrg: vec3f, rayDir: vec3f, distMin: f32, distMax: f32,\n pA: vec3f, pB: vec3f, pC: vec3f,\n pD: vec3f, pE: vec3f, pF: vec3f,\n\n hitDistMin: ptr<function, f32>,\n hitDistMax: ptr<function, f32>\n) -> bool {\n *hitDistMin = INF;\n *hitDistMax = -INF;\n\n let maxD = maxDimension(abs(rayDir));\n let shear = getShear(rayDir, maxD);\n var tt: f32;\n\n tt = intersectTriangle(\n rayOrg, rayDir,\n Triangle(pC, pB, pA), maxD, shear, INF\n ).t;\n if (tt > 0.0) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n tt = intersectTriangle(\n rayOrg, rayDir,\n Triangle(pD, pE, pF), maxD, shear, INF\n ).t;\n if (tt > 0.0) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pA, pB, pD, pE,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pB, pC, pE, pF,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pC, pA, pF, pD,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n\n *hitDistMin = max(*hitDistMin, distMin);\n *hitDistMax = min(*hitDistMax, distMax);\n\n return *hitDistMin <= *hitDistMax && *hitDistMax > 0.0;\n}\n";
2
- declare const _default: "\n\n\n\n\nstruct MicroTriangleIntersect {\n barycentric: vec3f,\n t: f32,\n normal: vec3f,\n\n}\n\nfn findVT(\n uu: f32,\n pARel: vec3f, pBRel: vec3f,\n eAC: vec3f, eBD: vec3f,\n rayDir: vec3f,\n distMin: f32,\n hitDist: ptr<function, f32>\n) -> bool {\n if (uu >= 0.0 && uu <= 1.0) {\n let pAB = mix(pARel, pBRel, uu);\n let pCD = mix(eAC, eBD, uu);\n var n = cross(rayDir, pCD);\n let recDet = 1.0 / dot(n, n);\n n = cross(n, pAB);\n let tt = dot(n, pCD) * recDet;\n let vv = dot(n, rayDir) * recDet;\n if (vv >= 0.0 && vv <= 1.0 && tt > distMin && tt < *hitDist) {\n *hitDist = tt;\n return true;\n }\n }\n return false;\n}\n\nfn testRayVsBilinearPatch(\n rayOrg: vec3f, rayDir: vec3f, distMin: f32, distMax: f32,\n pA: vec3f, pB: vec3f, pC: vec3f, pD: vec3f,\n hitDist: ptr<function, f32>\n) -> bool {\n let eAB = pB - pA;\n let eAC = pC - pA;\n let eBD = pD - pB;\n let eCD = pD - pC;\n let pARel = pA - rayOrg;\n let pBRel = pB - rayOrg;\n\n var u1: f32;\n var u2: f32;\n {\n let qN = cross(eAB, -eCD);\n let a = dot(qN, rayDir);\n var b = dot(cross(pBRel, rayDir), eBD);\n let c = dot(cross(pARel, rayDir), eAC);\n b -= a + c;\n\n let det = b * b - 4.0 * a * c;\n if (det < 0.0) {\n return false;\n }\n\n if (a == 0.0) {\n u1 = -c / b;\n u2 = -1.0;\n } else {\n let sqrtDet = sqrt(det);\n let temp = -0.5 * (b + sign(b) * sqrtDet);\n u1 = temp / a;\n u2 = c / temp;\n }\n }\n\n *hitDist = distMax;\n\n var hit = false;\n\n hit = findVT(u1, pARel, pBRel, eAC, eBD, rayDir, distMin, hitDist) || \n findVT(u2, pARel, pBRel, eAC, eBD, rayDir, distMin, hitDist);\n if (!hit) {\n return false;\n }\n\n return true;\n}\n\nfn intersectPrism(\n rayOrg: vec3f, rayDir: vec3f, distMin: f32, distMax: f32,\n pA: vec3f, pB: vec3f, pC: vec3f,\n pD: vec3f, pE: vec3f, pF: vec3f,\n\n hitDistMin: ptr<function, f32>,\n hitDistMax: ptr<function, f32>\n) -> bool {\n *hitDistMin = INF;\n *hitDistMax = -INF;\n\n let maxD = maxDimension(abs(rayDir));\n let shear = getShear(rayDir, maxD);\n var tt: f32;\n\n tt = intersectTriangle(\n rayOrg, rayDir,\n Triangle(pC, pB, pA), maxD, shear, INF\n ).t;\n if (tt > 0.0) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n tt = intersectTriangle(\n rayOrg, rayDir,\n Triangle(pD, pE, pF), maxD, shear, INF\n ).t;\n if (tt > 0.0) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pA, pB, pD, pE,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pB, pC, pE, pF,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pC, pA, pF, pD,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n\n *hitDistMin = max(*hitDistMin, distMin);\n *hitDistMax = min(*hitDistMax, distMax);\n\n return *hitDistMin <= *hitDistMax && *hitDistMax > 0.0;\n}\n\n\nfn triangleBarycentric(p: vec3f, p0: vec3f, p1: vec3f, p2: vec3f) -> vec3f {\n let v0 = p1 - p0;\n let v1 = p2 - p0;\n let v2 = p - p0;\n\n let d00 = dot(v0, v0);\n let d01 = dot(v0, v1);\n let d11 = dot(v1, v1);\n let d20 = dot(v2, v0);\n let d21 = dot(v2, v1);\n\n let invDenom = 1.0 / (d00 * d11 - d01 * d01);\n let v = clamp((d11 * d20 - d01 * d21) * invDenom, 0.0, 1.0);\n let w = clamp((d00 * d21 - d01 * d20) * invDenom, 0.0, 1.0);\n let u = 1.0 - v - w;\n\n return vec3f(u, v, w);\n}\n\nfn wrapUv(uv: vec2f) -> vec2f {\n return (uv % 1.0 + 1.0) % 1.0;\n}\n\n\nfn intersectDisplacement(\n _rayOrigin: vec3f, _rayDir: vec3f, _tMax: f32,\n _pA: vec3f, _pB: vec3f, _pC: vec3f,\n _nA: vec3f, _nB: vec3f, _nC: vec3f,\n _tcA: vec2f, _tcB: vec2f, _tcC: vec2f,\n\n heightMapIndex: i32,\n heightMapSize: vec2f,\n\n _minH: f32, _maxH: f32,\n hScale: f32,\n stepSize: f32,\n uvProjection: i32,\n uvScale: vec2f,\n isShadowHit: bool,\n isRefraction: bool\n) -> MicroTriangleIntersect {\n\n let DT = stepSize;\n let dt = DT / length(_rayDir);\n let dbx = 0.001;\n let dby = 0.001;\n\n var result: MicroTriangleIntersect;\n result.t = INF;\n\n var hitDistMin = INF;\n var hitDistMax = -INF;\n\n let hSign = sign(hScale);\n let hScaleAbs = abs(hScale);\n // Face normal.\n let faceN = hSign * normalize(cross(_pB - _pA, _pC - _pA));\n\n // dA, dB, dC are negative if hScale is negative\n let dA = dot(_nA, faceN);\n let dB = dot(_nB, faceN);\n let dC = dot(_nC, faceN);\n\n var minH = _minH * hScale * min(min(dA, dB), dC);\n var maxH = _maxH * hScale * max(max(dA, dB), dC);\n\n // Add gap\n // 1. Avoid too small height cause ray marching miss.\n // 2. Make sure the ray start beyond the displaced surface when surface height is same with prism height.\n let prismHeight = abs(maxH) - abs(minH);\n minH = sign(minH) * max(abs(minH) - dt * 2.0, 0.0);\n if (prismHeight < dt * 2.0) {\n maxH = sign(maxH) * min(abs(maxH) + dt * 2.0, abs(hScale));\n }\n\n let pA = _pA + _nA * minH / dA;\n let pB = _pB + _nB * minH / dB;\n let pC = _pC + _nC * minH / dC;\n\n let pD = _pA + _nA * maxH / dA;\n let pE = _pB + _nB * maxH / dB;\n let pF = _pC + _nC * maxH / dC;\n\n if (!intersectPrism(\n _rayOrigin, _rayDir, 0.0, INF,\n pA, pB, pC,\n pD, pE, pF,\n \n &hitDistMin, &hitDistMax\n )) {\n return result;\n }\n\n var testFlag = false;\n // Ray is inside the prism\n if (hitDistMax == hitDistMin) {\n hitDistMin = 0.0;\n }\n\n var t = hitDistMin + dt * hashedSample(2u);\n var s = _rayOrigin + _rayDir * t;\n var hRay = dot(s - _pA, faceN);\n var hSurf = select(0.0, INF, hSign < 0.0);\n // initial scanning triangle\n var c0 = _pA + _nA * hRay / dA;\n var c1 = _pB + _nB * hRay / dB;\n var c2 = _pC + _nC * hRay / dC;\n\n var projPos: vec3f;\n\n hRay = abs(hRay);\n\n var hDiff = hRay - hSurf;\n var hDiffPrev = hDiff;\n var step = 0;\n\n while (true) {\n // TODO Avoid too long loop\n let b = triangleBarycentric(s, c0, c1, c2);\n // Projected point on base triangle\n projPos = _pA * b.x + _pB * b.y + _pC * b.z;\n // Height at projected point\n hRay = distance(projPos, s);\n // Update scanning point\n var uv: vec2f;\n if (uvProjection > 0) {\n let n = normalize(_nA * b.x + _nB * b.y + _nC * b.z);\n uv = wrapUv(projectUV(uvProjection, projPos, n) * uvScale);\n }\n else {\n uv = wrapUv(_tcA * b.x + _tcB * b.y + _tcC * b.z);\n }\n let h = sampleMap(heightMapIndex, uv).x;\n // height < dt will be ignored in ray marching\n hSurf = max(hScaleAbs * h, dt);\n\n // Advance scanning triangle\n let dh = dot(faceN, s - c0);\n c0 = c0 + _nA * dh / dA;\n c1 = c1 + _nB * dh / dB;\n c2 = c2 + _nC * dh / dC;\n\n hDiffPrev = hDiff;\n hDiff = hRay - hSurf;\n\n if (!(select(hDiff * hSign, hDiff * hDiffPrev, isRefraction) > 0.0\n && t < hitDistMax + dt) \n // Ignore first step\n && step > 0) {\n break;\n }\n\n step++;\n t = t + dt;\n s = s + _rayDir * dt;\n }\n\n if (select(hDiff * hSign, hDiff * hDiffPrev, isRefraction) <= 0.0) {\n let dtt = dt * (abs(hDiff) / (abs(hDiffPrev) + abs(hDiff) + EPS));\n t = t - dtt;\n // t = interpolateCrossing(_rayOrigin, _rayDir, projPos, t, dt, hSurf);\n let pHit = _rayOrigin + _rayDir * t;\n let b = triangleBarycentric(pHit, c0, c1, c2);\n\n let N = normalize(_nA * b.x + _nB * b.y + _nC * b.z);\n\n let p_a = _pA * b.x + _pB * b.y + _pC * b.z;\n let p_b = _pA * (b.x + dbx) + _pB * b.y + _pC * (b.z - dbx);\n let p_c = _pA * b.x + _pB * (b.y + dby) + _pC * (b.z - dby);\n\n var uv_a: vec2f;\n var uv_b: vec2f;\n var uv_c: vec2f;\n\n if (uvProjection > 0) {\n let NA = normalize(_nA * b.x + _nB * b.y + _nC * b.z);\n let NB = normalize(_nA * (b.x + dbx) + _nB * b.y + _nC * (b.z - dbx));\n let NC = normalize(_nA * b.x + _nB * (b.y + dby) + _nC * (b.z - dby)); \n uv_a = projectUV(uvProjection, p_a, NA) * uvScale;\n uv_b = projectUV(uvProjection, p_b, NB) * uvScale;\n uv_c = projectUV(uvProjection, p_c, NC) * uvScale;\n }\n else {\n uv_a = _tcA * b.x + _tcB * b.y + _tcC * b.z;\n uv_b = _tcA * (b.x + dbx) + _tcB * b.y + _tcC * (b.z - dbx);\n uv_c = _tcA * b.x + _tcB * (b.y + dby) + _tcC * (b.z - dby);\n }\n\n let s_a = p_a + hSign * N * sampleMap(heightMapIndex, wrapUv(uv_a)).x * hScale;\n let s_b = p_b + hSign * N * sampleMap(heightMapIndex, wrapUv(uv_b)).x * hScale;\n let s_c = p_c + hSign * N * sampleMap(heightMapIndex, wrapUv(uv_c)).x * hScale;\n\n let N_s = -hSign * normalize(cross(s_c - s_a, s_b - s_a));\n\n result.t = t;\n result.barycentric = b;\n result.normal = normalize(N_s - faceN + hSign * N);\n }\n\n return result;\n\n}\n";
2
+ declare const _default: "\n\n\n\n\nstruct MicroTriangleIntersect {\n barycentric: vec3f,\n t: f32,\n normal: vec3f,\n\n}\n\nfn findVT(\n uu: f32,\n pARel: vec3f, pBRel: vec3f,\n eAC: vec3f, eBD: vec3f,\n rayDir: vec3f,\n distMin: f32,\n hitDist: ptr<function, f32>\n) -> bool {\n if (uu >= 0.0 && uu <= 1.0) {\n let pAB = mix(pARel, pBRel, uu);\n let pCD = mix(eAC, eBD, uu);\n var n = cross(rayDir, pCD);\n let recDet = 1.0 / dot(n, n);\n n = cross(n, pAB);\n let tt = dot(n, pCD) * recDet;\n let vv = dot(n, rayDir) * recDet;\n if (vv >= 0.0 && vv <= 1.0 && tt > distMin && tt < *hitDist) {\n *hitDist = tt;\n return true;\n }\n }\n return false;\n}\n\nfn testRayVsBilinearPatch(\n rayOrg: vec3f, rayDir: vec3f, distMin: f32, distMax: f32,\n pA: vec3f, pB: vec3f, pC: vec3f, pD: vec3f,\n hitDist: ptr<function, f32>\n) -> bool {\n let eAB = pB - pA;\n let eAC = pC - pA;\n let eBD = pD - pB;\n let eCD = pD - pC;\n let pARel = pA - rayOrg;\n let pBRel = pB - rayOrg;\n\n var u1: f32;\n var u2: f32;\n {\n let qN = cross(eAB, -eCD);\n let a = dot(qN, rayDir);\n var b = dot(cross(pBRel, rayDir), eBD);\n let c = dot(cross(pARel, rayDir), eAC);\n b -= a + c;\n\n let det = b * b - 4.0 * a * c;\n if (det < 0.0) {\n return false;\n }\n\n if (a == 0.0) {\n u1 = -c / b;\n u2 = -1.0;\n } else {\n let sqrtDet = sqrt(det);\n let temp = -0.5 * (b + sign(b) * sqrtDet);\n u1 = temp / a;\n u2 = c / temp;\n }\n }\n\n *hitDist = distMax;\n\n var hit = false;\n\n hit = findVT(u1, pARel, pBRel, eAC, eBD, rayDir, distMin, hitDist) || \n findVT(u2, pARel, pBRel, eAC, eBD, rayDir, distMin, hitDist);\n if (!hit) {\n return false;\n }\n\n return true;\n}\n\nfn intersectPrism(\n rayOrg: vec3f, rayDir: vec3f, distMin: f32, distMax: f32,\n pA: vec3f, pB: vec3f, pC: vec3f,\n pD: vec3f, pE: vec3f, pF: vec3f,\n\n hitDistMin: ptr<function, f32>,\n hitDistMax: ptr<function, f32>\n) -> bool {\n *hitDistMin = INF;\n *hitDistMax = -INF;\n\n let maxD = maxDimension(abs(rayDir));\n let shear = getShear(rayDir, maxD);\n var tt: f32;\n\n tt = intersectTriangle(\n rayOrg, rayDir,\n Triangle(pC, pB, pA), maxD, shear, INF\n ).t;\n if (tt > 0.0) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n tt = intersectTriangle(\n rayOrg, rayDir,\n Triangle(pD, pE, pF), maxD, shear, INF\n ).t;\n if (tt > 0.0) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pA, pB, pD, pE,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pB, pC, pE, pF,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pC, pA, pF, pD,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n\n *hitDistMin = max(*hitDistMin, distMin);\n *hitDistMax = min(*hitDistMax, distMax);\n\n return *hitDistMin <= *hitDistMax && *hitDistMax > 0.0;\n}\n\n\nfn triangleBarycentric(p: vec3f, p0: vec3f, p1: vec3f, p2: vec3f) -> vec3f {\n let v0 = p1 - p0;\n let v1 = p2 - p0;\n let v2 = p - p0;\n\n let d00 = dot(v0, v0);\n let d01 = dot(v0, v1);\n let d11 = dot(v1, v1);\n let d20 = dot(v2, v0);\n let d21 = dot(v2, v1);\n\n let invDenom = 1.0 / (d00 * d11 - d01 * d01);\n let v = clamp((d11 * d20 - d01 * d21) * invDenom, 0.0, 1.0);\n let w = clamp((d00 * d21 - d01 * d20) * invDenom, 0.0, 1.0);\n let u = 1.0 - v - w;\n\n return vec3f(u, v, w);\n}\n\nfn wrapUv(uv: vec2f) -> vec2f {\n return (uv % 1.0 + 1.0) % 1.0;\n}\n\n\nfn intersectDisplacement(\n _rayOrigin: vec3f, _rayDir: vec3f, _tMax: f32,\n _pA: vec3f, _pB: vec3f, _pC: vec3f,\n _nA: vec3f, _nB: vec3f, _nC: vec3f,\n _tcA: vec2f, _tcB: vec2f, _tcC: vec2f,\n\n heightMapIndex: i32,\n heightMapSize: vec2f,\n\n _minH: f32, _maxH: f32,\n hScale: f32,\n hBias: f32,\n stepSize: f32,\n uvProjection: i32,\n uvScale: vec2f,\n isShadowHit: bool,\n isRefraction: bool\n) -> MicroTriangleIntersect {\n\n // Zero keeps marching resolution proportional to the height instead of\n // letting a fixed local-unit step dominate small displacements.\n let DT = select(max(abs(hScale) / 32.0, 1e-12), stepSize, stepSize > 0.0);\n let dt = DT / length(_rayDir);\n let dbx = 0.001;\n let dby = 0.001;\n\n var result: MicroTriangleIntersect;\n result.t = INF;\n\n var hitDistMin = INF;\n var hitDistMax = -INF;\n\n let hSign = sign(hScale);\n let hScaleAbs = abs(hScale);\n // Face normal.\n let faceN = hSign * normalize(cross(_pB - _pA, _pC - _pA));\n\n // dA, dB, dC are negative if hScale is negative\n let dA = dot(_nA, faceN);\n let dB = dot(_nB, faceN);\n let dC = dot(_nC, faceN);\n\n var minH = _minH * hScale * min(min(dA, dB), dC);\n var maxH = _maxH * hScale * max(max(dA, dB), dC);\n\n // Add gap\n // 1. Avoid too small height cause ray marching miss.\n // 2. Make sure the ray start beyond the displaced surface when surface height is same with prism height.\n let prismHeight = abs(maxH) - abs(minH);\n // DT is a local-space length; dt is a ray-parameter increment and changes\n // when the instance transform scales the ray direction.\n minH = sign(minH) * max(abs(minH) - DT * 2.0, 0.0);\n if (prismHeight < DT * 2.0) {\n maxH = sign(maxH) * min(abs(maxH) + DT * 2.0, abs(hScale));\n }\n\n let pA = _pA + _nA * minH / dA;\n let pB = _pB + _nB * minH / dB;\n let pC = _pC + _nC * minH / dC;\n\n let pD = _pA + _nA * maxH / dA;\n let pE = _pB + _nB * maxH / dB;\n let pF = _pC + _nC * maxH / dC;\n\n if (!intersectPrism(\n _rayOrigin, _rayDir, 0.0, INF,\n pA, pB, pC,\n pD, pE, pF,\n \n &hitDistMin, &hitDistMax\n )) {\n return result;\n }\n\n var testFlag = false;\n // Ray is inside the prism\n if (hitDistMax == hitDistMin) {\n hitDistMin = 0.0;\n }\n\n var t = hitDistMin + dt * hashedSample(2u);\n var s = _rayOrigin + _rayDir * t;\n var hRay = dot(s - _pA, faceN);\n var hSurf = select(0.0, INF, hSign < 0.0);\n // initial scanning triangle\n var c0 = _pA + _nA * hRay / dA;\n var c1 = _pB + _nB * hRay / dB;\n var c2 = _pC + _nC * hRay / dC;\n\n var projPos: vec3f;\n\n hRay = abs(hRay);\n\n var hDiff = hRay - hSurf;\n var hDiffPrev = hDiff;\n var step = 0;\n\n while (true) {\n // TODO Avoid too long loop\n let b = triangleBarycentric(s, c0, c1, c2);\n // Projected point on base triangle\n projPos = _pA * b.x + _pB * b.y + _pC * b.z;\n // Height at projected point\n hRay = distance(projPos, s);\n // Update scanning point\n var uv: vec2f;\n if (uvProjection > 0) {\n let n = normalize(_nA * b.x + _nB * b.y + _nC * b.z);\n uv = wrapUv(projectUV(uvProjection, projPos - (_nA * b.x + _nB * b.y + _nC * b.z) * hBias, n) * uvScale);\n }\n else {\n uv = wrapUv(_tcA * b.x + _tcB * b.y + _tcC * b.z);\n }\n let h = sampleMap(heightMapIndex, uv).x;\n // Heights are measured in mesh-local units, independently of ray length.\n hSurf = max(hScaleAbs * h, DT);\n\n // Advance scanning triangle\n let dh = dot(faceN, s - c0);\n c0 = c0 + _nA * dh / dA;\n c1 = c1 + _nB * dh / dB;\n c2 = c2 + _nC * dh / dC;\n\n hDiffPrev = hDiff;\n hDiff = hRay - hSurf;\n\n if (!(select(hDiff * hSign, hDiff * hDiffPrev, isRefraction) > 0.0\n && t < hitDistMax + dt) \n // Ignore first step\n && step > 0) {\n break;\n }\n\n step++;\n t = t + dt;\n s = s + _rayDir * dt;\n }\n\n if (select(hDiff * hSign, hDiff * hDiffPrev, isRefraction) <= 0.0) {\n let dtt = dt * (abs(hDiff) / (abs(hDiffPrev) + abs(hDiff) + EPS));\n t = t - dtt;\n // t = interpolateCrossing(_rayOrigin, _rayDir, projPos, t, dt, hSurf);\n let pHit = _rayOrigin + _rayDir * t;\n let b = triangleBarycentric(pHit, c0, c1, c2);\n\n let N = normalize(_nA * b.x + _nB * b.y + _nC * b.z);\n\n let p_a = _pA * b.x + _pB * b.y + _pC * b.z;\n let p_b = _pA * (b.x + dbx) + _pB * b.y + _pC * (b.z - dbx);\n let p_c = _pA * b.x + _pB * (b.y + dby) + _pC * (b.z - dby);\n\n var uv_a: vec2f;\n var uv_b: vec2f;\n var uv_c: vec2f;\n\n if (uvProjection > 0) {\n let NA = normalize(_nA * b.x + _nB * b.y + _nC * b.z);\n let NB = normalize(_nA * (b.x + dbx) + _nB * b.y + _nC * (b.z - dbx));\n let NC = normalize(_nA * b.x + _nB * (b.y + dby) + _nC * (b.z - dby)); \n uv_a = projectUV(uvProjection, p_a - (_nA * b.x + _nB * b.y + _nC * b.z) * hBias, NA) * uvScale;\n uv_b = projectUV(uvProjection, p_b - (_nA * (b.x + dbx) + _nB * b.y + _nC * (b.z - dbx)) * hBias, NB) * uvScale;\n uv_c = projectUV(uvProjection, p_c - (_nA * b.x + _nB * (b.y + dby) + _nC * (b.z - dby)) * hBias, NC) * uvScale;\n }\n else {\n uv_a = _tcA * b.x + _tcB * b.y + _tcC * b.z;\n uv_b = _tcA * (b.x + dbx) + _tcB * b.y + _tcC * (b.z - dbx);\n uv_c = _tcA * b.x + _tcB * (b.y + dby) + _tcC * (b.z - dby);\n }\n\n let s_a = p_a + hSign * N * sampleMap(heightMapIndex, wrapUv(uv_a)).x * hScale;\n let s_b = p_b + hSign * N * sampleMap(heightMapIndex, wrapUv(uv_b)).x * hScale;\n let s_c = p_c + hSign * N * sampleMap(heightMapIndex, wrapUv(uv_c)).x * hScale;\n\n let N_s = -hSign * normalize(cross(s_c - s_a, s_b - s_a));\n\n result.t = t;\n result.barycentric = b;\n result.normal = normalize(N_s - faceN + hSign * N);\n }\n\n return result;\n\n}\n";
3
3
  export default _default;
4
4
  export { displacementCommon };
@@ -8,7 +8,7 @@ normal: vec3f,
8
8
 
9
9
  }
10
10
 
11
- fn uJ(
11
+ fn uL(
12
12
  uu: f32,
13
13
  tL: vec3f, tM: vec3f,
14
14
  eAC: vec3f, eBD: vec3f,
@@ -20,10 +20,10 @@ if (uu >= 0.0 && uu <= 1.0) {
20
20
  let pAB = mix(tL, tM, uu);
21
21
  let pCD = mix(eAC, eBD, uu);
22
22
  var n = cross(iI, pCD);
23
- let vj = 1.0 / dot(n, n);
23
+ let vl = 1.0 / dot(n, n);
24
24
  n = cross(n, pAB);
25
- let tt = dot(n, pCD) * vj;
26
- let vv = dot(n, iI) * vj;
25
+ let tt = dot(n, pCD) * vl;
26
+ let vv = dot(n, iI) * vl;
27
27
  if (vv >= 0.0 && vv <= 1.0 && tt > pL && tt < *pN) {
28
28
  *pN = tt;
29
29
  return true;
@@ -62,10 +62,10 @@ if (a == 0.0) {
62
62
  u1 = -c / b;
63
63
  u2 = -1.0;
64
64
  } else {
65
- let vD = sqrt(det);
66
- let wu = -0.5 * (b + sign(b) * vD);
67
- u1 = wu / a;
68
- u2 = c / wu;
65
+ let vE = sqrt(det);
66
+ let wv = -0.5 * (b + sign(b) * vE);
67
+ u1 = wv / a;
68
+ u2 = c / wv;
69
69
  }
70
70
  }
71
71
 
@@ -73,8 +73,8 @@ u2 = c / wu;
73
73
 
74
74
  var hit = false;
75
75
 
76
- hit = uJ(u1, tL, tM, eAC, eBD, iI, pL, pN) ||
77
- uJ(u2, tL, tM, eAC, eBD, iI, pL, pN);
76
+ hit = uL(u1, tL, tM, eAC, eBD, iI, pL, pN) ||
77
+ uL(u2, tL, tM, eAC, eBD, iI, pL, pN);
78
78
  if (!hit) {
79
79
  return false;
80
80
  }
@@ -93,13 +93,13 @@ bS: ptr<function, f32>
93
93
  *bT = INF;
94
94
  *bS = -INF;
95
95
 
96
- let vQ = maxDimension(abs(iI));
97
- let gJ = mg(iI, vQ);
96
+ let vR = maxDimension(abs(iI));
97
+ let gJ = mg(iI, vR);
98
98
  var tt: f32;
99
99
 
100
100
  tt = fI(
101
101
  pt, iI,
102
- fu(pC, pB, pA), vQ, gJ, INF
102
+ fu(pC, pB, pA), vR, gJ, INF
103
103
  ).t;
104
104
  if (tt > 0.0) {
105
105
  *bT = min(*bT, tt);
@@ -107,7 +107,7 @@ if (tt > 0.0) {
107
107
  }
108
108
  tt = fI(
109
109
  pt, iI,
110
- fu(pD, pE, pF), vQ, gJ, INF
110
+ fu(pD, pE, pF), vR, gJ, INF
111
111
  ).t;
112
112
  if (tt > 0.0) {
113
113
  *bT = min(*bT, tt);
@@ -170,24 +170,27 @@ return (uv % 1.0 + 1.0) % 1.0;
170
170
 
171
171
 
172
172
  fn oP(
173
- qf: vec3f, qA: vec3f, wB: f32,
173
+ qf: vec3f, qA: vec3f, wC: f32,
174
174
  _pA: vec3f, _pB: vec3f, _pC: vec3f,
175
175
  _nA: vec3f, _nB: vec3f, _nC: vec3f,
176
- vq: vec2f, vs: vec2f, vt: vec2f,
176
+ vs: vec2f, vt: vec2f, vu: vec2f,
177
177
 
178
178
  jH: i32,
179
- vp: vec2f,
179
+ vq: vec2f,
180
180
 
181
- vW: f32, vV: f32,
181
+ vX: f32, vW: f32,
182
182
  hScale: f32,
183
- vm: f32,
183
+ ux: f32,
184
+ tT: f32,
184
185
  uvProjection: i32,
185
186
  uvScale: vec2f,
186
- vI: bool,
187
+ vJ: bool,
187
188
  qQ: bool
188
189
  ) -> jv {
189
190
 
190
- let DT = vm;
191
+
192
+
193
+ let DT = select(max(abs(hScale) / 32.0, 1e-12), tT, tT > 0.0);
191
194
  let dt = DT / length(qA);
192
195
  let dbx = 0.001;
193
196
  let dby = 0.001;
@@ -199,7 +202,7 @@ var bT = INF;
199
202
  var bS = -INF;
200
203
 
201
204
  let qO = sign(hScale);
202
- let uB = abs(hScale);
205
+ let uD = abs(hScale);
203
206
 
204
207
  let sS = qO * normalize(cross(_pB - _pA, _pC - _pA));
205
208
 
@@ -208,16 +211,18 @@ let dA = dot(_nA, sS);
208
211
  let dB = dot(_nB, sS);
209
212
  let dC = dot(_nC, sS);
210
213
 
211
- var minH = vW * hScale * min(min(dA, dB), dC);
212
- var maxH = vV * hScale * max(max(dA, dB), dC);
214
+ var minH = vX * hScale * min(min(dA, dB), dC);
215
+ var maxH = vW * hScale * max(max(dA, dB), dC);
213
216
 
214
217
 
215
218
 
216
219
 
217
220
  let tN = abs(maxH) - abs(minH);
218
- minH = sign(minH) * max(abs(minH) - dt * 2.0, 0.0);
219
- if (tN < dt * 2.0) {
220
- maxH = sign(maxH) * min(abs(maxH) + dt * 2.0, abs(hScale));
221
+
222
+
223
+ minH = sign(minH) * max(abs(minH) - DT * 2.0, 0.0);
224
+ if (tN < DT * 2.0) {
225
+ maxH = sign(maxH) * min(abs(maxH) + DT * 2.0, abs(hScale));
221
226
  }
222
227
 
223
228
  let pA = _pA + _nA * minH / dA;
@@ -238,7 +243,7 @@ pD, pE, pF,
238
243
  return result;
239
244
  }
240
245
 
241
- var wv = false;
246
+ var ww = false;
242
247
 
243
248
  if (bS == bT) {
244
249
  bT = 0.0;
@@ -247,7 +252,7 @@ bT = 0.0;
247
252
  var t = bT + dt * eo(2u);
248
253
  var s = qf + qA * t;
249
254
  var tG = dot(s - _pA, sS);
250
- var uP = select(0.0, INF, qO < 0.0);
255
+ var uR = select(0.0, INF, qO < 0.0);
251
256
 
252
257
  var c0 = _pA + _nA * tG / dA;
253
258
  var c1 = _pB + _nB * tG / dB;
@@ -257,7 +262,7 @@ var tn: vec3f;
257
262
 
258
263
  tG = abs(tG);
259
264
 
260
- var qM = tG - uP;
265
+ var qM = tG - uR;
261
266
  var pM = qM;
262
267
  var step = 0;
263
268
 
@@ -272,14 +277,14 @@ tG = distance(tn, s);
272
277
  var uv: vec2f;
273
278
  if (uvProjection > 0) {
274
279
  let n = normalize(_nA * b.x + _nB * b.y + _nC * b.z);
275
- uv = sJ(gz(uvProjection, tn, n) * uvScale);
280
+ uv = sJ(gz(uvProjection, tn - (_nA * b.x + _nB * b.y + _nC * b.z) * ux, n) * uvScale);
276
281
  }
277
282
  else {
278
- uv = sJ(vq * b.x + vs * b.y + vt * b.z);
283
+ uv = sJ(vs * b.x + vt * b.y + vu * b.z);
279
284
  }
280
285
  let h = sampleMap(jH, uv).x;
281
286
 
282
- uP = max(uB * h, dt);
287
+ uR = max(uD * h, DT);
283
288
 
284
289
 
285
290
  let dh = dot(sS, s - c0);
@@ -288,7 +293,7 @@ c1 = c1 + _nB * dh / dB;
288
293
  c2 = c2 + _nC * dh / dC;
289
294
 
290
295
  pM = qM;
291
- qM = tG - uP;
296
+ qM = tG - uR;
292
297
 
293
298
  if (!(select(qM * qO, qM * pM, qQ) > 0.0
294
299
  && t < bS + dt)
@@ -306,8 +311,8 @@ if (select(qM * qO, qM * pM, qQ) <= 0.0) {
306
311
  let dtt = dt * (abs(qM) / (abs(pM) + abs(qM) + EPS));
307
312
  t = t - dtt;
308
313
 
309
- let wx = qf + qA * t;
310
- let b = lD(wx, c0, c1, c2);
314
+ let wy = qf + qA * t;
315
+ let b = lD(wy, c0, c1, c2);
311
316
 
312
317
  let N = normalize(_nA * b.x + _nB * b.y + _nC * b.z);
313
318
 
@@ -315,27 +320,27 @@ let p_a = _pA * b.x + _pB * b.y + _pC * b.z;
315
320
  let p_b = _pA * (b.x + dbx) + _pB * b.y + _pC * (b.z - dbx);
316
321
  let p_c = _pA * b.x + _pB * (b.y + dby) + _pC * (b.z - dby);
317
322
 
318
- var vS: vec2f;
319
323
  var vT: vec2f;
320
324
  var vU: vec2f;
325
+ var vV: vec2f;
321
326
 
322
327
  if (uvProjection > 0) {
323
328
  let NA = normalize(_nA * b.x + _nB * b.y + _nC * b.z);
324
329
  let NB = normalize(_nA * (b.x + dbx) + _nB * b.y + _nC * (b.z - dbx));
325
330
  let NC = normalize(_nA * b.x + _nB * (b.y + dby) + _nC * (b.z - dby));
326
- vS = gz(uvProjection, p_a, NA) * uvScale;
327
- vT = gz(uvProjection, p_b, NB) * uvScale;
328
- vU = gz(uvProjection, p_c, NC) * uvScale;
331
+ vT = gz(uvProjection, p_a - (_nA * b.x + _nB * b.y + _nC * b.z) * ux, NA) * uvScale;
332
+ vU = gz(uvProjection, p_b - (_nA * (b.x + dbx) + _nB * b.y + _nC * (b.z - dbx)) * ux, NB) * uvScale;
333
+ vV = gz(uvProjection, p_c - (_nA * b.x + _nB * (b.y + dby) + _nC * (b.z - dby)) * ux, NC) * uvScale;
329
334
  }
330
335
  else {
331
- vS = vq * b.x + vs * b.y + vt * b.z;
332
- vT = vq * (b.x + dbx) + vs * b.y + vt * (b.z - dbx);
333
- vU = vq * b.x + vs * (b.y + dby) + vt * (b.z - dby);
336
+ vT = vs * b.x + vt * b.y + vu * b.z;
337
+ vU = vs * (b.x + dbx) + vt * b.y + vu * (b.z - dbx);
338
+ vV = vs * b.x + vt * (b.y + dby) + vu * (b.z - dby);
334
339
  }
335
340
 
336
- let s_a = p_a + qO * N * sampleMap(jH, sJ(vS)).x * hScale;
337
- let s_b = p_b + qO * N * sampleMap(jH, sJ(vT)).x * hScale;
338
- let s_c = p_c + qO * N * sampleMap(jH, sJ(vU)).x * hScale;
341
+ let s_a = p_a + qO * N * sampleMap(jH, sJ(vT)).x * hScale;
342
+ let s_b = p_b + qO * N * sampleMap(jH, sJ(vU)).x * hScale;
343
+ let s_c = p_c + qO * N * sampleMap(jH, sJ(vV)).x * hScale;
339
344
 
340
345
  let N_s = -qO * normalize(cross(s_c - s_a, s_b - s_a));
341
346
 
@@ -1 +1 @@
1
- {"version":3,"file":"pdm_displacement.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/pdm_displacement.wgsl.ts"],"names":[],"mappings":"AAAA,MAAM,kBAAkB,GAAG,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8InC,CAAC;AAEF,eAAe,UAAU,CAAC;;EAExB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4MnB,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,CAAC","sourcesContent":["const displacementCommon = /*wgsl*/ `\n\n\nstruct MicroTriangleIntersect {\n barycentric: vec3f,\n t: f32,\n normal: vec3f,\n\n}\n\nfn findVT(\n uu: f32,\n pARel: vec3f, pBRel: vec3f,\n eAC: vec3f, eBD: vec3f,\n rayDir: vec3f,\n distMin: f32,\n hitDist: ptr<function, f32>\n) -> bool {\n if (uu >= 0.0 && uu <= 1.0) {\n let pAB = mix(pARel, pBRel, uu);\n let pCD = mix(eAC, eBD, uu);\n var n = cross(rayDir, pCD);\n let recDet = 1.0 / dot(n, n);\n n = cross(n, pAB);\n let tt = dot(n, pCD) * recDet;\n let vv = dot(n, rayDir) * recDet;\n if (vv >= 0.0 && vv <= 1.0 && tt > distMin && tt < *hitDist) {\n *hitDist = tt;\n return true;\n }\n }\n return false;\n}\n\nfn testRayVsBilinearPatch(\n rayOrg: vec3f, rayDir: vec3f, distMin: f32, distMax: f32,\n pA: vec3f, pB: vec3f, pC: vec3f, pD: vec3f,\n hitDist: ptr<function, f32>\n) -> bool {\n let eAB = pB - pA;\n let eAC = pC - pA;\n let eBD = pD - pB;\n let eCD = pD - pC;\n let pARel = pA - rayOrg;\n let pBRel = pB - rayOrg;\n\n var u1: f32;\n var u2: f32;\n {\n let qN = cross(eAB, -eCD);\n let a = dot(qN, rayDir);\n var b = dot(cross(pBRel, rayDir), eBD);\n let c = dot(cross(pARel, rayDir), eAC);\n b -= a + c;\n\n let det = b * b - 4.0 * a * c;\n if (det < 0.0) {\n return false;\n }\n\n if (a == 0.0) {\n u1 = -c / b;\n u2 = -1.0;\n } else {\n let sqrtDet = sqrt(det);\n let temp = -0.5 * (b + sign(b) * sqrtDet);\n u1 = temp / a;\n u2 = c / temp;\n }\n }\n\n *hitDist = distMax;\n\n var hit = false;\n\n hit = findVT(u1, pARel, pBRel, eAC, eBD, rayDir, distMin, hitDist) || \n findVT(u2, pARel, pBRel, eAC, eBD, rayDir, distMin, hitDist);\n if (!hit) {\n return false;\n }\n\n return true;\n}\n\nfn intersectPrism(\n rayOrg: vec3f, rayDir: vec3f, distMin: f32, distMax: f32,\n pA: vec3f, pB: vec3f, pC: vec3f,\n pD: vec3f, pE: vec3f, pF: vec3f,\n\n hitDistMin: ptr<function, f32>,\n hitDistMax: ptr<function, f32>\n) -> bool {\n *hitDistMin = INF;\n *hitDistMax = -INF;\n\n let maxD = maxDimension(abs(rayDir));\n let shear = getShear(rayDir, maxD);\n var tt: f32;\n\n tt = intersectTriangle(\n rayOrg, rayDir,\n Triangle(pC, pB, pA), maxD, shear, INF\n ).t;\n if (tt > 0.0) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n tt = intersectTriangle(\n rayOrg, rayDir,\n Triangle(pD, pE, pF), maxD, shear, INF\n ).t;\n if (tt > 0.0) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pA, pB, pD, pE,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pB, pC, pE, pF,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pC, pA, pF, pD,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n\n *hitDistMin = max(*hitDistMin, distMin);\n *hitDistMax = min(*hitDistMax, distMax);\n\n return *hitDistMin <= *hitDistMax && *hitDistMax > 0.0;\n}\n`;\n\nexport default /* wgsl */ `\n\n${displacementCommon}\n\nfn triangleBarycentric(p: vec3f, p0: vec3f, p1: vec3f, p2: vec3f) -> vec3f {\n let v0 = p1 - p0;\n let v1 = p2 - p0;\n let v2 = p - p0;\n\n let d00 = dot(v0, v0);\n let d01 = dot(v0, v1);\n let d11 = dot(v1, v1);\n let d20 = dot(v2, v0);\n let d21 = dot(v2, v1);\n\n let invDenom = 1.0 / (d00 * d11 - d01 * d01);\n let v = clamp((d11 * d20 - d01 * d21) * invDenom, 0.0, 1.0);\n let w = clamp((d00 * d21 - d01 * d20) * invDenom, 0.0, 1.0);\n let u = 1.0 - v - w;\n\n return vec3f(u, v, w);\n}\n\nfn wrapUv(uv: vec2f) -> vec2f {\n return (uv % 1.0 + 1.0) % 1.0;\n}\n\n\nfn intersectDisplacement(\n _rayOrigin: vec3f, _rayDir: vec3f, _tMax: f32,\n _pA: vec3f, _pB: vec3f, _pC: vec3f,\n _nA: vec3f, _nB: vec3f, _nC: vec3f,\n _tcA: vec2f, _tcB: vec2f, _tcC: vec2f,\n\n heightMapIndex: i32,\n heightMapSize: vec2f,\n\n _minH: f32, _maxH: f32,\n hScale: f32,\n stepSize: f32,\n uvProjection: i32,\n uvScale: vec2f,\n isShadowHit: bool,\n isRefraction: bool\n) -> MicroTriangleIntersect {\n\n let DT = stepSize;\n let dt = DT / length(_rayDir);\n let dbx = 0.001;\n let dby = 0.001;\n\n var result: MicroTriangleIntersect;\n result.t = INF;\n\n var hitDistMin = INF;\n var hitDistMax = -INF;\n\n let hSign = sign(hScale);\n let hScaleAbs = abs(hScale);\n // Face normal.\n let faceN = hSign * normalize(cross(_pB - _pA, _pC - _pA));\n\n // dA, dB, dC are negative if hScale is negative\n let dA = dot(_nA, faceN);\n let dB = dot(_nB, faceN);\n let dC = dot(_nC, faceN);\n\n var minH = _minH * hScale * min(min(dA, dB), dC);\n var maxH = _maxH * hScale * max(max(dA, dB), dC);\n\n // Add gap\n // 1. Avoid too small height cause ray marching miss.\n // 2. Make sure the ray start beyond the displaced surface when surface height is same with prism height.\n let prismHeight = abs(maxH) - abs(minH);\n minH = sign(minH) * max(abs(minH) - dt * 2.0, 0.0);\n if (prismHeight < dt * 2.0) {\n maxH = sign(maxH) * min(abs(maxH) + dt * 2.0, abs(hScale));\n }\n\n let pA = _pA + _nA * minH / dA;\n let pB = _pB + _nB * minH / dB;\n let pC = _pC + _nC * minH / dC;\n\n let pD = _pA + _nA * maxH / dA;\n let pE = _pB + _nB * maxH / dB;\n let pF = _pC + _nC * maxH / dC;\n\n if (!intersectPrism(\n _rayOrigin, _rayDir, 0.0, INF,\n pA, pB, pC,\n pD, pE, pF,\n \n &hitDistMin, &hitDistMax\n )) {\n return result;\n }\n\n var testFlag = false;\n // Ray is inside the prism\n if (hitDistMax == hitDistMin) {\n hitDistMin = 0.0;\n }\n\n var t = hitDistMin + dt * hashedSample(2u);\n var s = _rayOrigin + _rayDir * t;\n var hRay = dot(s - _pA, faceN);\n var hSurf = select(0.0, INF, hSign < 0.0);\n // initial scanning triangle\n var c0 = _pA + _nA * hRay / dA;\n var c1 = _pB + _nB * hRay / dB;\n var c2 = _pC + _nC * hRay / dC;\n\n var projPos: vec3f;\n\n hRay = abs(hRay);\n\n var hDiff = hRay - hSurf;\n var hDiffPrev = hDiff;\n var step = 0;\n\n while (true) {\n // TODO Avoid too long loop\n let b = triangleBarycentric(s, c0, c1, c2);\n // Projected point on base triangle\n projPos = _pA * b.x + _pB * b.y + _pC * b.z;\n // Height at projected point\n hRay = distance(projPos, s);\n // Update scanning point\n var uv: vec2f;\n if (uvProjection > 0) {\n let n = normalize(_nA * b.x + _nB * b.y + _nC * b.z);\n uv = wrapUv(projectUV(uvProjection, projPos, n) * uvScale);\n }\n else {\n uv = wrapUv(_tcA * b.x + _tcB * b.y + _tcC * b.z);\n }\n let h = sampleMap(heightMapIndex, uv).x;\n // height < dt will be ignored in ray marching\n hSurf = max(hScaleAbs * h, dt);\n\n // Advance scanning triangle\n let dh = dot(faceN, s - c0);\n c0 = c0 + _nA * dh / dA;\n c1 = c1 + _nB * dh / dB;\n c2 = c2 + _nC * dh / dC;\n\n hDiffPrev = hDiff;\n hDiff = hRay - hSurf;\n\n if (!(select(hDiff * hSign, hDiff * hDiffPrev, isRefraction) > 0.0\n && t < hitDistMax + dt) \n // Ignore first step\n && step > 0) {\n break;\n }\n\n step++;\n t = t + dt;\n s = s + _rayDir * dt;\n }\n\n if (select(hDiff * hSign, hDiff * hDiffPrev, isRefraction) <= 0.0) {\n let dtt = dt * (abs(hDiff) / (abs(hDiffPrev) + abs(hDiff) + EPS));\n t = t - dtt;\n // t = interpolateCrossing(_rayOrigin, _rayDir, projPos, t, dt, hSurf);\n let pHit = _rayOrigin + _rayDir * t;\n let b = triangleBarycentric(pHit, c0, c1, c2);\n\n let N = normalize(_nA * b.x + _nB * b.y + _nC * b.z);\n\n let p_a = _pA * b.x + _pB * b.y + _pC * b.z;\n let p_b = _pA * (b.x + dbx) + _pB * b.y + _pC * (b.z - dbx);\n let p_c = _pA * b.x + _pB * (b.y + dby) + _pC * (b.z - dby);\n\n var uv_a: vec2f;\n var uv_b: vec2f;\n var uv_c: vec2f;\n\n if (uvProjection > 0) {\n let NA = normalize(_nA * b.x + _nB * b.y + _nC * b.z);\n let NB = normalize(_nA * (b.x + dbx) + _nB * b.y + _nC * (b.z - dbx));\n let NC = normalize(_nA * b.x + _nB * (b.y + dby) + _nC * (b.z - dby)); \n uv_a = projectUV(uvProjection, p_a, NA) * uvScale;\n uv_b = projectUV(uvProjection, p_b, NB) * uvScale;\n uv_c = projectUV(uvProjection, p_c, NC) * uvScale;\n }\n else {\n uv_a = _tcA * b.x + _tcB * b.y + _tcC * b.z;\n uv_b = _tcA * (b.x + dbx) + _tcB * b.y + _tcC * (b.z - dbx);\n uv_c = _tcA * b.x + _tcB * (b.y + dby) + _tcC * (b.z - dby);\n }\n\n let s_a = p_a + hSign * N * sampleMap(heightMapIndex, wrapUv(uv_a)).x * hScale;\n let s_b = p_b + hSign * N * sampleMap(heightMapIndex, wrapUv(uv_b)).x * hScale;\n let s_c = p_c + hSign * N * sampleMap(heightMapIndex, wrapUv(uv_c)).x * hScale;\n\n let N_s = -hSign * normalize(cross(s_c - s_a, s_b - s_a));\n\n result.t = t;\n result.barycentric = b;\n result.normal = normalize(N_s - faceN + hSign * N);\n }\n\n return result;\n\n}\n`;\n\nexport { displacementCommon };\n"]}
1
+ {"version":3,"file":"pdm_displacement.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/pdm_displacement.wgsl.ts"],"names":[],"mappings":"AAAA,MAAM,kBAAkB,GAAG,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8InC,CAAC;AAEF,eAAe,UAAU,CAAC;;EAExB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiNnB,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,CAAC","sourcesContent":["const displacementCommon = /*wgsl*/ `\n\n\nstruct MicroTriangleIntersect {\n barycentric: vec3f,\n t: f32,\n normal: vec3f,\n\n}\n\nfn findVT(\n uu: f32,\n pARel: vec3f, pBRel: vec3f,\n eAC: vec3f, eBD: vec3f,\n rayDir: vec3f,\n distMin: f32,\n hitDist: ptr<function, f32>\n) -> bool {\n if (uu >= 0.0 && uu <= 1.0) {\n let pAB = mix(pARel, pBRel, uu);\n let pCD = mix(eAC, eBD, uu);\n var n = cross(rayDir, pCD);\n let recDet = 1.0 / dot(n, n);\n n = cross(n, pAB);\n let tt = dot(n, pCD) * recDet;\n let vv = dot(n, rayDir) * recDet;\n if (vv >= 0.0 && vv <= 1.0 && tt > distMin && tt < *hitDist) {\n *hitDist = tt;\n return true;\n }\n }\n return false;\n}\n\nfn testRayVsBilinearPatch(\n rayOrg: vec3f, rayDir: vec3f, distMin: f32, distMax: f32,\n pA: vec3f, pB: vec3f, pC: vec3f, pD: vec3f,\n hitDist: ptr<function, f32>\n) -> bool {\n let eAB = pB - pA;\n let eAC = pC - pA;\n let eBD = pD - pB;\n let eCD = pD - pC;\n let pARel = pA - rayOrg;\n let pBRel = pB - rayOrg;\n\n var u1: f32;\n var u2: f32;\n {\n let qN = cross(eAB, -eCD);\n let a = dot(qN, rayDir);\n var b = dot(cross(pBRel, rayDir), eBD);\n let c = dot(cross(pARel, rayDir), eAC);\n b -= a + c;\n\n let det = b * b - 4.0 * a * c;\n if (det < 0.0) {\n return false;\n }\n\n if (a == 0.0) {\n u1 = -c / b;\n u2 = -1.0;\n } else {\n let sqrtDet = sqrt(det);\n let temp = -0.5 * (b + sign(b) * sqrtDet);\n u1 = temp / a;\n u2 = c / temp;\n }\n }\n\n *hitDist = distMax;\n\n var hit = false;\n\n hit = findVT(u1, pARel, pBRel, eAC, eBD, rayDir, distMin, hitDist) || \n findVT(u2, pARel, pBRel, eAC, eBD, rayDir, distMin, hitDist);\n if (!hit) {\n return false;\n }\n\n return true;\n}\n\nfn intersectPrism(\n rayOrg: vec3f, rayDir: vec3f, distMin: f32, distMax: f32,\n pA: vec3f, pB: vec3f, pC: vec3f,\n pD: vec3f, pE: vec3f, pF: vec3f,\n\n hitDistMin: ptr<function, f32>,\n hitDistMax: ptr<function, f32>\n) -> bool {\n *hitDistMin = INF;\n *hitDistMax = -INF;\n\n let maxD = maxDimension(abs(rayDir));\n let shear = getShear(rayDir, maxD);\n var tt: f32;\n\n tt = intersectTriangle(\n rayOrg, rayDir,\n Triangle(pC, pB, pA), maxD, shear, INF\n ).t;\n if (tt > 0.0) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n tt = intersectTriangle(\n rayOrg, rayDir,\n Triangle(pD, pE, pF), maxD, shear, INF\n ).t;\n if (tt > 0.0) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pA, pB, pD, pE,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pB, pC, pE, pF,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n if (testRayVsBilinearPatch(\n rayOrg, rayDir, -INF, INF,\n pC, pA, pF, pD,\n &tt)) {\n *hitDistMin = min(*hitDistMin, tt);\n *hitDistMax = max(*hitDistMax, tt);\n }\n\n *hitDistMin = max(*hitDistMin, distMin);\n *hitDistMax = min(*hitDistMax, distMax);\n\n return *hitDistMin <= *hitDistMax && *hitDistMax > 0.0;\n}\n`;\n\nexport default /* wgsl */ `\n\n${displacementCommon}\n\nfn triangleBarycentric(p: vec3f, p0: vec3f, p1: vec3f, p2: vec3f) -> vec3f {\n let v0 = p1 - p0;\n let v1 = p2 - p0;\n let v2 = p - p0;\n\n let d00 = dot(v0, v0);\n let d01 = dot(v0, v1);\n let d11 = dot(v1, v1);\n let d20 = dot(v2, v0);\n let d21 = dot(v2, v1);\n\n let invDenom = 1.0 / (d00 * d11 - d01 * d01);\n let v = clamp((d11 * d20 - d01 * d21) * invDenom, 0.0, 1.0);\n let w = clamp((d00 * d21 - d01 * d20) * invDenom, 0.0, 1.0);\n let u = 1.0 - v - w;\n\n return vec3f(u, v, w);\n}\n\nfn wrapUv(uv: vec2f) -> vec2f {\n return (uv % 1.0 + 1.0) % 1.0;\n}\n\n\nfn intersectDisplacement(\n _rayOrigin: vec3f, _rayDir: vec3f, _tMax: f32,\n _pA: vec3f, _pB: vec3f, _pC: vec3f,\n _nA: vec3f, _nB: vec3f, _nC: vec3f,\n _tcA: vec2f, _tcB: vec2f, _tcC: vec2f,\n\n heightMapIndex: i32,\n heightMapSize: vec2f,\n\n _minH: f32, _maxH: f32,\n hScale: f32,\n hBias: f32,\n stepSize: f32,\n uvProjection: i32,\n uvScale: vec2f,\n isShadowHit: bool,\n isRefraction: bool\n) -> MicroTriangleIntersect {\n\n // Zero keeps marching resolution proportional to the height instead of\n // letting a fixed local-unit step dominate small displacements.\n let DT = select(max(abs(hScale) / 32.0, 1e-12), stepSize, stepSize > 0.0);\n let dt = DT / length(_rayDir);\n let dbx = 0.001;\n let dby = 0.001;\n\n var result: MicroTriangleIntersect;\n result.t = INF;\n\n var hitDistMin = INF;\n var hitDistMax = -INF;\n\n let hSign = sign(hScale);\n let hScaleAbs = abs(hScale);\n // Face normal.\n let faceN = hSign * normalize(cross(_pB - _pA, _pC - _pA));\n\n // dA, dB, dC are negative if hScale is negative\n let dA = dot(_nA, faceN);\n let dB = dot(_nB, faceN);\n let dC = dot(_nC, faceN);\n\n var minH = _minH * hScale * min(min(dA, dB), dC);\n var maxH = _maxH * hScale * max(max(dA, dB), dC);\n\n // Add gap\n // 1. Avoid too small height cause ray marching miss.\n // 2. Make sure the ray start beyond the displaced surface when surface height is same with prism height.\n let prismHeight = abs(maxH) - abs(minH);\n // DT is a local-space length; dt is a ray-parameter increment and changes\n // when the instance transform scales the ray direction.\n minH = sign(minH) * max(abs(minH) - DT * 2.0, 0.0);\n if (prismHeight < DT * 2.0) {\n maxH = sign(maxH) * min(abs(maxH) + DT * 2.0, abs(hScale));\n }\n\n let pA = _pA + _nA * minH / dA;\n let pB = _pB + _nB * minH / dB;\n let pC = _pC + _nC * minH / dC;\n\n let pD = _pA + _nA * maxH / dA;\n let pE = _pB + _nB * maxH / dB;\n let pF = _pC + _nC * maxH / dC;\n\n if (!intersectPrism(\n _rayOrigin, _rayDir, 0.0, INF,\n pA, pB, pC,\n pD, pE, pF,\n \n &hitDistMin, &hitDistMax\n )) {\n return result;\n }\n\n var testFlag = false;\n // Ray is inside the prism\n if (hitDistMax == hitDistMin) {\n hitDistMin = 0.0;\n }\n\n var t = hitDistMin + dt * hashedSample(2u);\n var s = _rayOrigin + _rayDir * t;\n var hRay = dot(s - _pA, faceN);\n var hSurf = select(0.0, INF, hSign < 0.0);\n // initial scanning triangle\n var c0 = _pA + _nA * hRay / dA;\n var c1 = _pB + _nB * hRay / dB;\n var c2 = _pC + _nC * hRay / dC;\n\n var projPos: vec3f;\n\n hRay = abs(hRay);\n\n var hDiff = hRay - hSurf;\n var hDiffPrev = hDiff;\n var step = 0;\n\n while (true) {\n // TODO Avoid too long loop\n let b = triangleBarycentric(s, c0, c1, c2);\n // Projected point on base triangle\n projPos = _pA * b.x + _pB * b.y + _pC * b.z;\n // Height at projected point\n hRay = distance(projPos, s);\n // Update scanning point\n var uv: vec2f;\n if (uvProjection > 0) {\n let n = normalize(_nA * b.x + _nB * b.y + _nC * b.z);\n uv = wrapUv(projectUV(uvProjection, projPos - (_nA * b.x + _nB * b.y + _nC * b.z) * hBias, n) * uvScale);\n }\n else {\n uv = wrapUv(_tcA * b.x + _tcB * b.y + _tcC * b.z);\n }\n let h = sampleMap(heightMapIndex, uv).x;\n // Heights are measured in mesh-local units, independently of ray length.\n hSurf = max(hScaleAbs * h, DT);\n\n // Advance scanning triangle\n let dh = dot(faceN, s - c0);\n c0 = c0 + _nA * dh / dA;\n c1 = c1 + _nB * dh / dB;\n c2 = c2 + _nC * dh / dC;\n\n hDiffPrev = hDiff;\n hDiff = hRay - hSurf;\n\n if (!(select(hDiff * hSign, hDiff * hDiffPrev, isRefraction) > 0.0\n && t < hitDistMax + dt) \n // Ignore first step\n && step > 0) {\n break;\n }\n\n step++;\n t = t + dt;\n s = s + _rayDir * dt;\n }\n\n if (select(hDiff * hSign, hDiff * hDiffPrev, isRefraction) <= 0.0) {\n let dtt = dt * (abs(hDiff) / (abs(hDiffPrev) + abs(hDiff) + EPS));\n t = t - dtt;\n // t = interpolateCrossing(_rayOrigin, _rayDir, projPos, t, dt, hSurf);\n let pHit = _rayOrigin + _rayDir * t;\n let b = triangleBarycentric(pHit, c0, c1, c2);\n\n let N = normalize(_nA * b.x + _nB * b.y + _nC * b.z);\n\n let p_a = _pA * b.x + _pB * b.y + _pC * b.z;\n let p_b = _pA * (b.x + dbx) + _pB * b.y + _pC * (b.z - dbx);\n let p_c = _pA * b.x + _pB * (b.y + dby) + _pC * (b.z - dby);\n\n var uv_a: vec2f;\n var uv_b: vec2f;\n var uv_c: vec2f;\n\n if (uvProjection > 0) {\n let NA = normalize(_nA * b.x + _nB * b.y + _nC * b.z);\n let NB = normalize(_nA * (b.x + dbx) + _nB * b.y + _nC * (b.z - dbx));\n let NC = normalize(_nA * b.x + _nB * (b.y + dby) + _nC * (b.z - dby)); \n uv_a = projectUV(uvProjection, p_a - (_nA * b.x + _nB * b.y + _nC * b.z) * hBias, NA) * uvScale;\n uv_b = projectUV(uvProjection, p_b - (_nA * (b.x + dbx) + _nB * b.y + _nC * (b.z - dbx)) * hBias, NB) * uvScale;\n uv_c = projectUV(uvProjection, p_c - (_nA * b.x + _nB * (b.y + dby) + _nC * (b.z - dby)) * hBias, NC) * uvScale;\n }\n else {\n uv_a = _tcA * b.x + _tcB * b.y + _tcC * b.z;\n uv_b = _tcA * (b.x + dbx) + _tcB * b.y + _tcC * (b.z - dbx);\n uv_c = _tcA * b.x + _tcB * (b.y + dby) + _tcC * (b.z - dby);\n }\n\n let s_a = p_a + hSign * N * sampleMap(heightMapIndex, wrapUv(uv_a)).x * hScale;\n let s_b = p_b + hSign * N * sampleMap(heightMapIndex, wrapUv(uv_b)).x * hScale;\n let s_c = p_c + hSign * N * sampleMap(heightMapIndex, wrapUv(uv_c)).x * hScale;\n\n let N_s = -hSign * normalize(cross(s_c - s_a, s_b - s_a));\n\n result.t = t;\n result.barycentric = b;\n result.normal = normalize(N_s - faceN + hSign * N);\n }\n\n return result;\n\n}\n`;\n\nexport { displacementCommon };\n"]}
@@ -10,7 +10,7 @@ s0 = vec4u(p, u32(frame), u32(p.x) + u32(p.y));
10
10
  }
11
11
 
12
12
 
13
- fn vg() {
13
+ fn vj() {
14
14
  s0 = s0 * 1664525u + 1013904223u;
15
15
  s0.x += s0.y*s0.w; s0.y += s0.z*s0.x; s0.z += s0.x*s0.y; s0.w += s0.y*s0.z;
16
16
  s0 = s0 ^ (s0>>vec4(16u));
@@ -18,7 +18,7 @@ s0.x += s0.y*s0.w; s0.y += s0.z*s0.x; s0.z += s0.x*s0.y; s0.w += s0.y*s0.z;
18
18
  }
19
19
 
20
20
  fn rand() -> f32 {
21
- vg(); return f32(s0.x)/f32(0xffffffffu);
21
+ vj(); return f32(s0.x)/f32(0xffffffffu);
22
22
  }
23
23
 
24
24
  `;
@@ -303,10 +303,10 @@ if (light.v.y > 1e-6) {
303
303
  tD = smoothstep(light.v.x, light.v.x + light.v.y, cc);
304
304
  }
305
305
  if (tD <= 0.0 || light.textureIndex < 0.0) { return tD; }
306
- let tW = light.iesReference;
307
- let vn = cross(axis, tW);
306
+ let tX = light.iesReference;
307
+ let vo = cross(axis, tX);
308
308
  let vertical = acos(clamp(cc, -1.0, 1.0));
309
- let horizontal = atan2(dot(dJ, vn), dot(dJ, tW));
309
+ let horizontal = atan2(dot(dJ, vo), dot(dJ, tX));
310
310
  return tD * kF(i32(light.textureIndex), vec2f(vertical / PI, horizontal / TWOPI + 0.5));
311
311
  }
312
312
 
@@ -262,11 +262,11 @@ fm: vec3f,
262
262
  iT: vec2f,
263
263
  lightSample: ptr<function, LightSampleRec>
264
264
  ) {
265
- let vl = sqrt(iT.x);
265
+ let vn = sqrt(iT.x);
266
266
  let barycentric = vec3f(
267
- 1.0 - vl,
268
- vl * (1.0 - iT.y),
269
- vl * iT.y
267
+ 1.0 - vn,
268
+ vn * (1.0 - iT.y),
269
+ vn * iT.y
270
270
  );
271
271
  let sN =
272
272
  barycentric.x * triangle.p0 +
@@ -230,9 +230,9 @@ ${hasCoatNormals ? /* wgsl */ `
230
230
 
231
231
  fn fB(input: vec3f, tc: vec3f, view: vec3f) -> vec3f {
232
232
  let qL = dot(tc, view) >= 0.0;
233
- let ub = select(-tc, tc, qL);
233
+ let uc = select(-tc, tc, qL);
234
234
  let qK = select(-input, input, qL);
235
- if (dot(input, tc) <= 0.0 || dot(qK, view) <= 1e-6) { return ub; }
235
+ if (dot(input, tc) <= 0.0 || dot(qK, view) <= 1e-6) { return uc; }
236
236
  return qK;
237
237
  }
238
238
  ` : ''}
@@ -364,11 +364,11 @@ var aT = false;
364
364
  var bE = true;
365
365
  var aR = u32(OPENPBR_LOBE_DIFFUSE);
366
366
  var qw = 0.0;
367
- let ud = vec3f(fk(cv(BSDF_DIRECTION)), dz(cv(BSDF_LOBE)));
367
+ let ue = vec3f(fk(cv(BSDF_DIRECTION)), dz(cv(BSDF_LOBE)));
368
368
  var gR = vec3f(0.0);
369
369
  let f = dv(
370
370
  prepared,
371
- ud,
371
+ ue,
372
372
  &cF,
373
373
  &scatteringPdf,
374
374
  &isNextRefraction,
@@ -6,11 +6,11 @@ export default /*wgsl*/ `
6
6
  fn aQ(view: vec3f, alpha: vec2f, samplePoint: vec2f) -> vec3f {
7
7
  let qY = vec3f(alpha, 1.0);
8
8
  let ge = normalize(qY * view);
9
- let tU = min(ge.z, 1.0);
10
- let qD = 1.0 + tU;
9
+ let tV = min(ge.z, 1.0);
10
+ let qD = 1.0 + tV;
11
11
  let qT = (1.0 - samplePoint.y) * qD;
12
12
  let rE = samplePoint.y * qD;
13
- let st = qT + (1.0 - tU);
13
+ let st = qT + (1.0 - tV);
14
14
  let fi = sqrt(max(0.0, st * rE));
15
15
  let br = TWOPI * samplePoint.x;
16
16
  let lt = vec3f(
@@ -44,7 +44,7 @@ var r = reverseBits(ki);
44
44
  ${sobolD1Steps.map(([shift, mask]) => `r ^= (r << ${shift}u) & 0x${mask.toString(16)}u;`).join("\n ")}
45
45
  return r;
46
46
  }
47
- fn vC(index: u32, ie: u32) -> vec2f {
47
+ fn vD(index: u32, ie: u32) -> vec2f {
48
48
  let i = sv(index, aq(ie, 0u));
49
49
  let x = reverseBits(iA(i, aq(ie, 1u)));
50
50
  let y = sv(qX(i), aq(ie, 2u));
@@ -66,9 +66,9 @@ return (word >> ((tm & 3u) * 8u)) & 255u;
66
66
  }
67
67
  fn pK(kB: u32, dim: u32, logSPP: u32) -> u32 {
68
68
  let odd = logSPP & 1u;
69
- let tZ = 8u + ((logSPP + 1u) >> 1u);
69
+ let ua = 8u + ((logSPP + 1u) >> 1u);
70
70
  var result = 0u;
71
- for (var digit = i32(tZ) - 1; digit >= i32(odd); digit--) {
71
+ for (var digit = i32(ua) - 1; digit >= i32(odd); digit--) {
72
72
  let shift = 2u*u32(digit) - odd;
73
73
 
74
74
  var sd = 0u;
@@ -172,8 +172,8 @@ var eM = gS(background.rgb / max(background.a, 0.000001) * exposure);
172
172
  eM *= 1.0 - toneMappingParams.y * kj;
173
173
  if (!hx) { eM = cH(eM); }
174
174
  let lY = select(pow(max(eM, vec3f(0.0)), vec3f(1.0 / 2.2)), fJ(eM), hx);
175
- let tX = select(vec3f(0.0), max(backgroundColor - lY, vec3f(0.0)), bloomIntensity > 0.0);
176
- backgroundColor = fJ(max(flatBackgroundColor.rgb, vec3f(0.0))) + tX;
175
+ let tY = select(vec3f(0.0), max(backgroundColor - lY, vec3f(0.0)), bloomIntensity > 0.0);
176
+ backgroundColor = fJ(max(flatBackgroundColor.rgb, vec3f(0.0))) + tY;
177
177
  }
178
178
 
179
179
 
@@ -8,10 +8,10 @@ let background = load_backgroundTex(uv, 0);
8
8
  var me = foreground;
9
9
  var mc = background;
10
10
  if (any(filtered != original)) {
11
- let uj = abs(original) > vec3f(0.000001);
12
- let ap = select(vec3f(1.0), original, uj);
13
- let scale = select(vec3f(1.0), filtered / ap, uj);
14
- let tP = select(filtered - original, vec3f(0.0), uj);
11
+ let uk = abs(original) > vec3f(0.000001);
12
+ let ap = select(vec3f(1.0), original, uk);
13
+ let scale = select(vec3f(1.0), filtered / ap, uk);
14
+ let tP = select(filtered - original, vec3f(0.0), uk);
15
15
  me = vec4f(foreground.rgb * scale + tP, foreground.a);
16
16
 
17
17
  mc = vec4f(background.rgb * scale + tP * background.a, background.a);