@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
@@ -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 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";
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\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 = projectUV(uvProjection, projPos - (_nA * b.x + _nB * b.y + _nC * b.z) * hBias, n) * uvScale;\n }\n else {\n uv = _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, uv_a).x * hScale;\n let s_b = p_b + hSign * N * sampleMap(heightMapIndex, uv_b).x * hScale;\n let s_c = p_c + hSign * N * sampleMap(heightMapIndex, 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 };
@@ -1,56 +1,56 @@
1
1
  const displacementCommon = /*wgsl*/ `
2
2
 
3
3
 
4
- struct jx {
4
+ struct jD {
5
5
  barycentric: vec3f,
6
6
  t: f32,
7
7
  normal: vec3f,
8
8
 
9
9
  }
10
10
 
11
- fn uQ(
11
+ fn uX(
12
12
  uu: f32,
13
- tQ: vec3f, tR: vec3f,
13
+ tX: vec3f, tY: vec3f,
14
14
  eAC: vec3f, eBD: vec3f,
15
- iJ: vec3f,
16
- pP: f32,
17
- pR: ptr<function, f32>
15
+ iO: vec3f,
16
+ pX: f32,
17
+ pZ: ptr<function, f32>
18
18
  ) -> bool {
19
19
  if (uu >= 0.0 && uu <= 1.0) {
20
- let pAB = mix(tQ, tR, uu);
20
+ let pAB = mix(tX, tY, uu);
21
21
  let pCD = mix(eAC, eBD, uu);
22
- var n = cross(iJ, pCD);
23
- let vq = 1.0 / dot(n, n);
22
+ var n = cross(iO, pCD);
23
+ let vA = 1.0 / dot(n, n);
24
24
  n = cross(n, pAB);
25
- let tt = dot(n, pCD) * vq;
26
- let vv = dot(n, iJ) * vq;
27
- if (vv >= 0.0 && vv <= 1.0 && tt > pP && tt < *pR) {
28
- *pR = tt;
25
+ let tt = dot(n, pCD) * vA;
26
+ let vv = dot(n, iO) * vA;
27
+ if (vv >= 0.0 && vv <= 1.0 && tt > pX && tt < *pZ) {
28
+ *pZ = tt;
29
29
  return true;
30
30
  }
31
31
  }
32
32
  return false;
33
33
  }
34
34
 
35
- fn he(
36
- pH: vec3f, iJ: vec3f, pP: f32, tf: f32,
35
+ fn hj(
36
+ pP: vec3f, iO: vec3f, pX: f32, tn: f32,
37
37
  pA: vec3f, pB: vec3f, pC: vec3f, pD: vec3f,
38
- pR: ptr<function, f32>
38
+ pZ: ptr<function, f32>
39
39
  ) -> bool {
40
40
  let eAB = pB - pA;
41
41
  let eAC = pC - pA;
42
42
  let eBD = pD - pB;
43
43
  let eCD = pD - pC;
44
- let tQ = pA - pH;
45
- let tR = pB - pH;
44
+ let tX = pA - pP;
45
+ let tY = pB - pP;
46
46
 
47
47
  var u1: f32;
48
48
  var u2: f32;
49
49
  {
50
50
  let qN = cross(eAB, -eCD);
51
- let a = dot(qN, iJ);
52
- var b = dot(cross(tR, iJ), eBD);
53
- let c = dot(cross(tQ, iJ), eAC);
51
+ let a = dot(qN, iO);
52
+ var b = dot(cross(tY, iO), eBD);
53
+ let c = dot(cross(tX, iO), eAC);
54
54
  b -= a + c;
55
55
 
56
56
  let det = b * b - 4.0 * a * c;
@@ -62,19 +62,19 @@ if (a == 0.0) {
62
62
  u1 = -c / b;
63
63
  u2 = -1.0;
64
64
  } else {
65
- let vJ = sqrt(det);
66
- let wC = -0.5 * (b + sign(b) * vJ);
67
- u1 = wC / a;
68
- u2 = c / wC;
65
+ let vQ = sqrt(det);
66
+ let wL = -0.5 * (b + sign(b) * vQ);
67
+ u1 = wL / a;
68
+ u2 = c / wL;
69
69
  }
70
70
  }
71
71
 
72
- *pR = tf;
72
+ *pZ = tn;
73
73
 
74
74
  var hit = false;
75
75
 
76
- hit = uQ(u1, tQ, tR, eAC, eBD, iJ, pP, pR) ||
77
- uQ(u2, tQ, tR, eAC, eBD, iJ, pP, pR);
76
+ hit = uX(u1, tX, tY, eAC, eBD, iO, pX, pZ) ||
77
+ uX(u2, tX, tY, eAC, eBD, iO, pX, pZ);
78
78
  if (!hit) {
79
79
  return false;
80
80
  }
@@ -82,8 +82,8 @@ return false;
82
82
  return true;
83
83
  }
84
84
 
85
- fn sl(
86
- pH: vec3f, iJ: vec3f, pP: f32, tf: f32,
85
+ fn sv(
86
+ pP: vec3f, iO: vec3f, pX: f32, tn: f32,
87
87
  pA: vec3f, pB: vec3f, pC: vec3f,
88
88
  pD: vec3f, pE: vec3f, pF: vec3f,
89
89
 
@@ -93,50 +93,50 @@ bS: ptr<function, f32>
93
93
  *bT = INF;
94
94
  *bS = -INF;
95
95
 
96
- let vW = maxDimension(abs(iJ));
97
- let gL = mj(iJ, vW);
96
+ let wd = maxDimension(abs(iO));
97
+ let gQ = mu(iO, wd);
98
98
  var tt: f32;
99
99
 
100
- tt = fI(
101
- pH, iJ,
102
- fu(pC, pB, pA), vW, gL, INF
100
+ tt = fM(
101
+ pP, iO,
102
+ fB(pC, pB, pA), wd, gQ, INF
103
103
  ).t;
104
104
  if (tt > 0.0) {
105
105
  *bT = min(*bT, tt);
106
106
  *bS = max(*bS, tt);
107
107
  }
108
- tt = fI(
109
- pH, iJ,
110
- fu(pD, pE, pF), vW, gL, INF
108
+ tt = fM(
109
+ pP, iO,
110
+ fB(pD, pE, pF), wd, gQ, INF
111
111
  ).t;
112
112
  if (tt > 0.0) {
113
113
  *bT = min(*bT, tt);
114
114
  *bS = max(*bS, tt);
115
115
  }
116
- if (he(
117
- pH, iJ, -INF, INF,
116
+ if (hj(
117
+ pP, iO, -INF, INF,
118
118
  pA, pB, pD, pE,
119
119
  &tt)) {
120
120
  *bT = min(*bT, tt);
121
121
  *bS = max(*bS, tt);
122
122
  }
123
- if (he(
124
- pH, iJ, -INF, INF,
123
+ if (hj(
124
+ pP, iO, -INF, INF,
125
125
  pB, pC, pE, pF,
126
126
  &tt)) {
127
127
  *bT = min(*bT, tt);
128
128
  *bS = max(*bS, tt);
129
129
  }
130
- if (he(
131
- pH, iJ, -INF, INF,
130
+ if (hj(
131
+ pP, iO, -INF, INF,
132
132
  pC, pA, pF, pD,
133
133
  &tt)) {
134
134
  *bT = min(*bT, tt);
135
135
  *bS = max(*bS, tt);
136
136
  }
137
137
 
138
- *bT = max(*bT, pP);
139
- *bS = min(*bS, tf);
138
+ *bT = max(*bT, pX);
139
+ *bS = min(*bS, tn);
140
140
 
141
141
  return *bT <= *bS && *bS > 0.0;
142
142
  }
@@ -145,7 +145,7 @@ export default /* wgsl */ `
145
145
 
146
146
  ${displacementCommon}
147
147
 
148
- fn lG(p: vec3f, p0: vec3f, p1: vec3f, p2: vec3f) -> vec3f {
148
+ fn lP(p: vec3f, p0: vec3f, p1: vec3f, p2: vec3f) -> vec3f {
149
149
  let v0 = p1 - p0;
150
150
  let v1 = p2 - p0;
151
151
  let v2 = p - p0;
@@ -156,72 +156,69 @@ let d11 = dot(v1, v1);
156
156
  let d20 = dot(v2, v0);
157
157
  let d21 = dot(v2, v1);
158
158
 
159
- let tM = 1.0 / (d00 * d11 - d01 * d01);
160
- let v = clamp((d11 * d20 - d01 * d21) * tM, 0.0, 1.0);
161
- let w = clamp((d00 * d21 - d01 * d20) * tM, 0.0, 1.0);
159
+ let tT = 1.0 / (d00 * d11 - d01 * d01);
160
+ let v = clamp((d11 * d20 - d01 * d21) * tT, 0.0, 1.0);
161
+ let w = clamp((d00 * d21 - d01 * d20) * tT, 0.0, 1.0);
162
162
  let u = 1.0 - v - w;
163
163
 
164
164
  return vec3f(u, v, w);
165
165
  }
166
166
 
167
- fn sO(uv: vec2f) -> vec2f {
168
- return (uv % 1.0 + 1.0) % 1.0;
169
- }
170
167
 
171
168
 
172
- fn oT(
173
- qj: vec3f, qE: vec3f, wJ: f32,
169
+ fn pc(
170
+ qr: vec3f, qM: vec3f, wQ: f32,
174
171
  _pA: vec3f, _pB: vec3f, _pC: vec3f,
175
172
  _nA: vec3f, _nB: vec3f, _nC: vec3f,
176
- vy: vec2f, vA: vec2f, vB: vec2f,
173
+ vG: vec2f, vH: vec2f, vI: vec2f,
177
174
 
178
- jJ: i32,
179
- vx: vec2f,
175
+ jQ: i32,
176
+ vF: vec2f,
180
177
 
181
- wc: f32, wb: f32,
178
+ wk: f32, wj: f32,
182
179
  hScale: f32,
183
- uC: f32,
184
- tY: f32,
180
+ uJ: f32,
181
+ uf: f32,
185
182
  uvProjection: i32,
186
183
  uvScale: vec2f,
187
- vO: bool,
188
- qU: bool
189
- ) -> jx {
184
+ vV: bool,
185
+ rc: bool
186
+ ) -> jD {
190
187
 
191
188
 
192
189
 
193
- let DT = select(max(abs(hScale) / 32.0, 1e-12), tY, tY > 0.0);
194
- let dt = DT / length(qE);
190
+ let DT = select(max(abs(hScale) / 32.0, 1e-12), uf, uf > 0.0);
191
+ let dt = DT / length(qM);
195
192
  let dbx = 0.001;
196
193
  let dby = 0.001;
197
194
 
198
- var result: jx;
195
+ var result: jD;
199
196
  result.t = INF;
200
197
 
201
198
  var bT = INF;
202
199
  var bS = -INF;
203
200
 
204
- let qS = sign(hScale);
205
- let uI = abs(hScale);
201
+ let ra = sign(hScale);
202
+ let uP = abs(hScale);
206
203
 
207
- let sX = qS * normalize(cross(_pB - _pA, _pC - _pA));
204
+ let te = ra * normalize(cross(_pB - _pA, _pC - _pA));
208
205
 
209
206
 
210
- let dA = dot(_nA, sX);
211
- let dB = dot(_nB, sX);
212
- let dC = dot(_nC, sX);
207
+ let dA = dot(_nA, te);
208
+ let dB = dot(_nB, te);
209
+ let dC = dot(_nC, te);
213
210
 
214
- var minH = wc * hScale * min(min(dA, dB), dC);
215
- var maxH = wb * hScale * max(max(dA, dB), dC);
211
+ var minH = wk * hScale * min(min(dA, dB), dC);
212
+ var maxH = wj * hScale * max(max(dA, dB), dC);
216
213
 
217
214
 
218
215
 
219
216
 
220
- let tS = abs(maxH) - abs(minH);
217
+ let tZ = abs(maxH) - abs(minH);
221
218
 
222
219
 
223
220
  minH = sign(minH) * max(abs(minH) - DT * 2.0, 0.0);
224
- if (tS < DT * 2.0) {
221
+ if (tZ < DT * 2.0) {
225
222
  maxH = sign(maxH) * min(abs(maxH) + DT * 2.0, abs(hScale));
226
223
  }
227
224
 
@@ -233,8 +230,8 @@ let pD = _pA + _nA * maxH / dA;
233
230
  let pE = _pB + _nB * maxH / dB;
234
231
  let pF = _pC + _nC * maxH / dC;
235
232
 
236
- if (!sl(
237
- qj, qE, 0.0, INF,
233
+ if (!sv(
234
+ qr, qM, 0.0, INF,
238
235
  pA, pB, pC,
239
236
  pD, pE, pF,
240
237
 
@@ -243,59 +240,59 @@ pD, pE, pF,
243
240
  return result;
244
241
  }
245
242
 
246
- var wE = false;
243
+ var wM = false;
247
244
 
248
245
  if (bS == bT) {
249
246
  bT = 0.0;
250
247
  }
251
248
 
252
249
  var t = bT + dt * eo(2u);
253
- var s = qj + qE * t;
254
- var tL = dot(s - _pA, sX);
255
- var uW = select(0.0, INF, qS < 0.0);
250
+ var s = qr + qM * t;
251
+ var tS = dot(s - _pA, te);
252
+ var vd = select(0.0, INF, ra < 0.0);
256
253
 
257
- var c0 = _pA + _nA * tL / dA;
258
- var c1 = _pB + _nB * tL / dB;
259
- var c2 = _pC + _nC * tL / dC;
254
+ var c0 = _pA + _nA * tS / dA;
255
+ var c1 = _pB + _nB * tS / dB;
256
+ var c2 = _pC + _nC * tS / dC;
260
257
 
261
- var tv: vec3f;
258
+ var tF: vec3f;
262
259
 
263
- tL = abs(tL);
260
+ tS = abs(tS);
264
261
 
265
- var qR = tL - uW;
266
- var pQ = qR;
262
+ var qZ = tS - vd;
263
+ var pY = qZ;
267
264
  var step = 0;
268
265
 
269
266
  while (true) {
270
267
 
271
- let b = lG(s, c0, c1, c2);
268
+ let b = lP(s, c0, c1, c2);
272
269
 
273
- tv = _pA * b.x + _pB * b.y + _pC * b.z;
270
+ tF = _pA * b.x + _pB * b.y + _pC * b.z;
274
271
 
275
- tL = distance(tv, s);
272
+ tS = distance(tF, s);
276
273
 
277
274
  var uv: vec2f;
278
275
  if (uvProjection > 0) {
279
276
  let n = normalize(_nA * b.x + _nB * b.y + _nC * b.z);
280
- uv = sO(gC(uvProjection, tv - (_nA * b.x + _nB * b.y + _nC * b.z) * uC, n) * uvScale);
277
+ uv = gI(uvProjection, tF - (_nA * b.x + _nB * b.y + _nC * b.z) * uJ, n) * uvScale;
281
278
  }
282
279
  else {
283
- uv = sO(vy * b.x + vA * b.y + vB * b.z);
280
+ uv = vG * b.x + vH * b.y + vI * b.z;
284
281
  }
285
- let h = sampleMap(jJ, uv).x;
282
+ let h = sampleMap(jQ, uv).x;
286
283
 
287
- uW = max(uI * h, DT);
284
+ vd = max(uP * h, DT);
288
285
 
289
286
 
290
- let dh = dot(sX, s - c0);
287
+ let dh = dot(te, s - c0);
291
288
  c0 = c0 + _nA * dh / dA;
292
289
  c1 = c1 + _nB * dh / dB;
293
290
  c2 = c2 + _nC * dh / dC;
294
291
 
295
- pQ = qR;
296
- qR = tL - uW;
292
+ pY = qZ;
293
+ qZ = tS - vd;
297
294
 
298
- if (!(select(qR * qS, qR * pQ, qU) > 0.0
295
+ if (!(select(qZ * ra, qZ * pY, rc) > 0.0
299
296
  && t < bS + dt)
300
297
 
301
298
  && step > 0) {
@@ -304,15 +301,15 @@ break;
304
301
 
305
302
  step++;
306
303
  t = t + dt;
307
- s = s + qE * dt;
304
+ s = s + qM * dt;
308
305
  }
309
306
 
310
- if (select(qR * qS, qR * pQ, qU) <= 0.0) {
311
- let dtt = dt * (abs(qR) / (abs(pQ) + abs(qR) + EPS));
307
+ if (select(qZ * ra, qZ * pY, rc) <= 0.0) {
308
+ let dtt = dt * (abs(qZ) / (abs(pY) + abs(qZ) + EPS));
312
309
  t = t - dtt;
313
310
 
314
- let wG = qj + qE * t;
315
- let b = lG(wG, c0, c1, c2);
311
+ let wO = qr + qM * t;
312
+ let b = lP(wO, c0, c1, c2);
316
313
 
317
314
  let N = normalize(_nA * b.x + _nB * b.y + _nC * b.z);
318
315
 
@@ -320,33 +317,33 @@ let p_a = _pA * b.x + _pB * b.y + _pC * b.z;
320
317
  let p_b = _pA * (b.x + dbx) + _pB * b.y + _pC * (b.z - dbx);
321
318
  let p_c = _pA * b.x + _pB * (b.y + dby) + _pC * (b.z - dby);
322
319
 
323
- var vY: vec2f;
324
- var vZ: vec2f;
325
- var wa: vec2f;
320
+ var wg: vec2f;
321
+ var wh: vec2f;
322
+ var wi: vec2f;
326
323
 
327
324
  if (uvProjection > 0) {
328
325
  let NA = normalize(_nA * b.x + _nB * b.y + _nC * b.z);
329
326
  let NB = normalize(_nA * (b.x + dbx) + _nB * b.y + _nC * (b.z - dbx));
330
327
  let NC = normalize(_nA * b.x + _nB * (b.y + dby) + _nC * (b.z - dby));
331
- vY = gC(uvProjection, p_a - (_nA * b.x + _nB * b.y + _nC * b.z) * uC, NA) * uvScale;
332
- vZ = gC(uvProjection, p_b - (_nA * (b.x + dbx) + _nB * b.y + _nC * (b.z - dbx)) * uC, NB) * uvScale;
333
- wa = gC(uvProjection, p_c - (_nA * b.x + _nB * (b.y + dby) + _nC * (b.z - dby)) * uC, NC) * uvScale;
328
+ wg = gI(uvProjection, p_a - (_nA * b.x + _nB * b.y + _nC * b.z) * uJ, NA) * uvScale;
329
+ wh = gI(uvProjection, p_b - (_nA * (b.x + dbx) + _nB * b.y + _nC * (b.z - dbx)) * uJ, NB) * uvScale;
330
+ wi = gI(uvProjection, p_c - (_nA * b.x + _nB * (b.y + dby) + _nC * (b.z - dby)) * uJ, NC) * uvScale;
334
331
  }
335
332
  else {
336
- vY = vy * b.x + vA * b.y + vB * b.z;
337
- vZ = vy * (b.x + dbx) + vA * b.y + vB * (b.z - dbx);
338
- wa = vy * b.x + vA * (b.y + dby) + vB * (b.z - dby);
333
+ wg = vG * b.x + vH * b.y + vI * b.z;
334
+ wh = vG * (b.x + dbx) + vH * b.y + vI * (b.z - dbx);
335
+ wi = vG * b.x + vH * (b.y + dby) + vI * (b.z - dby);
339
336
  }
340
337
 
341
- let s_a = p_a + qS * N * sampleMap(jJ, sO(vY)).x * hScale;
342
- let s_b = p_b + qS * N * sampleMap(jJ, sO(vZ)).x * hScale;
343
- let s_c = p_c + qS * N * sampleMap(jJ, sO(wa)).x * hScale;
338
+ let s_a = p_a + ra * N * sampleMap(jQ, wg).x * hScale;
339
+ let s_b = p_b + ra * N * sampleMap(jQ, wh).x * hScale;
340
+ let s_c = p_c + ra * N * sampleMap(jQ, wi).x * hScale;
344
341
 
345
- let N_s = -qS * normalize(cross(s_c - s_a, s_b - s_a));
342
+ let N_s = -ra * normalize(cross(s_c - s_a, s_b - s_a));
346
343
 
347
344
  result.t = t;
348
345
  result.barycentric = b;
349
- result.normal = normalize(N_s - sX + qS * N);
346
+ result.normal = normalize(N_s - te + ra * N);
350
347
  }
351
348
 
352
349
  return result;
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"]}
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8MnB,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\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 = projectUV(uvProjection, projPos - (_nA * b.x + _nB * b.y + _nC * b.z) * hBias, n) * uvScale;\n }\n else {\n uv = _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, uv_a).x * hScale;\n let s_b = p_b + hSign * N * sampleMap(heightMapIndex, uv_b).x * hScale;\n let s_c = p_c + hSign * N * sampleMap(heightMapIndex, 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"]}
@@ -4,13 +4,13 @@
4
4
  export default /* wgsl */ `
5
5
  var<private> s0: vec4u;
6
6
 
7
- fn ka(p: vec2u, frame: i32) {
7
+ fn kh(p: vec2u, frame: i32) {
8
8
 
9
9
  s0 = vec4u(p, u32(frame), u32(p.x) + u32(p.y));
10
10
  }
11
11
 
12
12
 
13
- fn vo() {
13
+ fn vx() {
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
- vo(); return f32(s0.x)/f32(0xffffffffu);
21
+ vx(); return f32(s0.x)/f32(0xffffffffu);
22
22
  }
23
23
 
24
24
  `;