@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.
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +4155 -4052
- package/docs/api.md +13 -10
- package/docs/materials.md +17 -26
- package/docs/threejs.md +35 -9
- package/docs/viewer.md +36 -3
- package/lib/Engine.js +18 -1
- package/lib/Engine.js.map +1 -1
- package/lib/main.d.ts +1 -1
- package/lib/main.js.map +1 -1
- package/lib/oidn.d.ts +1 -1
- package/lib/oidnBundledWeights.cdn.d.ts +2 -2
- package/lib/renderer/MaterialTable.d.ts +1 -0
- package/lib/renderer/MaterialTable.js +10 -4
- package/lib/renderer/MaterialTable.js.map +1 -1
- package/lib/renderer/WGPUBloomPass.js +18 -18
- package/lib/renderer/WGPUFullQuadPass.js +6 -6
- package/lib/renderer/WGPUJNLMDenoiser.js +69 -69
- package/lib/renderer/WGPURayTraceOutput.js +14 -14
- package/lib/renderer/WGPURayTracePass.d.ts +2 -0
- package/lib/renderer/WGPURayTracePass.js +17 -9
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.js +15 -15
- package/lib/renderer/WebGLJNLMDenoiser.js +69 -69
- package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
- package/lib/renderer/WebGLRayTracePass.d.ts +1 -0
- package/lib/renderer/WebGLRayTracePass.js +8 -1
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/envMapCreation.d.ts +5 -1
- package/lib/renderer/envMapCreation.js +42 -5
- package/lib/renderer/envMapCreation.js.map +1 -1
- package/lib/renderer/geometryUpdates.js +1 -1
- package/lib/renderer/geometryUpdates.js.map +1 -1
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +12 -12
- package/lib/renderer/glsl/chunks/envMap.glsl.js +66 -54
- package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/intersect.glsl.js +323 -315
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +154 -121
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +434 -434
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +42 -41
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +69 -69
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +84 -84
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +12 -12
- package/lib/renderer/glsl/chunks/sampling.glsl.js +75 -75
- package/lib/renderer/glsl/chunks/sobol.glsl.js +61 -61
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
- package/lib/renderer/glsl/depthQuery.frag.js +5 -5
- package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +8 -8
- package/lib/renderer/glsl/rayTrace.frag.js +133 -133
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +9 -9
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +52 -52
- package/lib/renderer/lightsUtil.js +6 -4
- package/lib/renderer/lightsUtil.js.map +1 -1
- package/lib/renderer/materialChanges.js +1 -1
- package/lib/renderer/materialChanges.js.map +1 -1
- package/lib/renderer/materialComparison.generated.js +36 -18
- package/lib/renderer/materialComparison.generated.js.map +1 -1
- package/lib/renderer/prepareMeshBVH.js +2 -2
- package/lib/renderer/prepareMeshBVH.js.map +1 -1
- package/lib/renderer/sceneChangeDetector.js +4 -1
- package/lib/renderer/sceneChangeDetector.js.map +1 -1
- package/lib/renderer/sceneLightChanges.js +3 -2
- package/lib/renderer/sceneLightChanges.js.map +1 -1
- package/lib/renderer/scratchSampling.js +18 -18
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +39 -31
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +476 -470
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +8 -8
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +95 -60
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +469 -469
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +117 -120
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +25 -22
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +127 -127
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +136 -136
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +6 -6
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +73 -73
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +62 -62
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
- package/lib/renderer/wgsl/compose.frag.wgsl.js +105 -105
- package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
- package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/depthQuery.wgsl.js +5 -5
- package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +28 -28
- package/lib/renderer/wgsl/rayTrace.compute.js +251 -248
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/EnvironmentLight.d.ts +9 -3
- package/lib/scene/EnvironmentLight.js +9 -2
- package/lib/scene/EnvironmentLight.js.map +1 -1
- package/lib/scene/OpenPBRMaterial.d.ts +1 -1
- package/lib/scene/OpenPBRMaterial.js +1 -1
- package/lib/scene/OpenPBRMaterial.js.map +1 -1
- package/lib/scene/Scene.d.ts +4 -0
- package/lib/scene/Scene.js.map +1 -1
- package/lib/scene/SpotLight.d.ts +2 -2
- package/lib/scene/SpotLight.js +1 -1
- package/lib/scene/SpotLight.js.map +1 -1
- package/lib/scene/Texture.d.ts +17 -6
- package/lib/scene/Texture.js +13 -4
- package/lib/scene/Texture.js.map +1 -1
- package/lib/util/fromTHREE.js +151 -29
- package/lib/util/fromTHREE.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sampleMaterial.glsl.js","sourceRoot":"","sources":["../../../../src/renderer/glsl/chunks/sampleMaterial.glsl.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,iIAAiI;AAEjI,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,eAAe,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkRlB,CAAC","sourcesContent":["// Estimate the direct lighting integral using multiple importance sampling\n// http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Direct_Lighting.html#EstimatingtheDirectLightingIntegral\n\nimport { glsl } from '../../shader.js';\nexport default glsl`\nvec3 DirectLight(SurfaceInteraction si, OpenPbrResolvedMaterial mat, OpenPbrPreparedBsdf prepared, inout Path path, vec3 ffnormal, bool isSurface) {\n float occluded = 1.0;\n vec3 lightRnd = vec3(sample2D(bounceDim(LIGHT_POSITION)), sample1D(bounceDim(LIGHT_SELECT)));\n\n LightSampleRec lightSample;\n sampleLight(si.position, lightRnd, lightSample, false);\n lightSample.emission = sampling_spectral_rgb_filter(lightSample.emission, pathWavelength);\n\n vec3 lightDir = lightSample.direction;\n vec3 viewDir = -path.ray.d;\n float lightPdf = lightSample.pdf;\n // Opaque surfaces are rendered two-sided by the core renderer. Use the\n // face-forward shading normal here as well, otherwise the early-out rejects\n // every direct-light sample seen from the back of a triangle (for example\n // the inside of an imported room wall).\n float cosThetaL = dot(ffnormal, lightDir);\n#ifdef NUM_COAT_NORMAL_MAPS\n if (isSurface && mat.coatNormalEnabled) { cosThetaL = dot(mat.geometricNormal, lightDir); }\n#endif\n\n if (lightPdf <= 0.0 || max(max(lightSample.emission.x, lightSample.emission.y), lightSample.emission.z) <= 0.0) {\n return vec3(0.0);\n }\n\n float scatteringPdf = 0.0;\n vec3 f = vec3(0.0);\n if (isSurface) {\n if (cosThetaL <= 0.0 && mat.transmissionWeight <= 0.0 && mat.subsurfaceWeight <= 0.0) {\n return vec3(0.0);\n }\n f = openpbr_eval_prepared(prepared, lightDir, scatteringPdf);\n }\n else {\n scatteringPdf = sampling_henyey_greenstein_phase(\n dot(viewDir, lightDir),\n si.mediumAnisotropy\n );\n f = vec3(scatteringPdf);\n }\n\n if (scatteringPdf <= 0.0 || max(max(f.x, f.y), f.z) <= 0.0) {\n return vec3(0.0);\n }\n\n Ray lightRay;\n vec3 shadowOrigin = si.position + EPS * lightDir;\n if (isSurface) {\n const float shadowTerminatorCutoff = 0.1;\n float normalLight = dot(si.normal, lightDir);\n#ifdef NUM_COAT_NORMAL_MAPS\n if (mat.coatNormalEnabled) { normalLight = dot(si.faceNormal, lightDir); }\n#endif\n vec3 geometricNormal = normalLight < 0.0 ? -si.faceNormal : si.faceNormal;\n normalLight = abs(normalLight);\n float geometricLight = dot(geometricNormal, lightDir);\n float offsetAmount = normalLight < shadowTerminatorCutoff\n ? clamp(\n 2.0 - (geometricLight + normalLight) / shadowTerminatorCutoff,\n 0.0,\n 1.0\n )\n : clamp(1.0 - geometricLight / shadowTerminatorCutoff, 0.0, 1.0);\n shadowOrigin += si.shadowOffset * offsetAmount;\n }\n initRay(lightRay, shadowOrigin, lightDir);\n if (intersectSceneShadow(lightRay, lightSample.dist - EPS, si.triangleIndex)) {\n return vec3(0.0);\n }\n\n#ifdef USE_ENVMAP\n // Match the endpoint used by a BSDF-sampled surface transmission, including\n // a separately displayed or grounded background and its coverage.\n if (isSurface && cosThetaL < 0.0 && lightRnd.z < envLightSelectionPmf) {\n vec4 background = sampleBackgroundFromRay(lightRay.o, lightDir);\n lightSample.emission = sampling_spectral_rgb_filter(background.rgb * background.a, pathWavelength);\n }\n#endif\n\n // Delta lights cannot be sampled by the BSDF strategy, so their MIS weight\n // is exactly one even when their light-selection PMF is small.\n float misWeight = lightSample.isDelta\n ? 1.0\n : sampling_power_heuristic(lightPdf, scatteringPdf);\n return misWeight > 0.0\n ? misWeight * lightSample.emission * f / lightPdf\n : vec3(0.0);\n}\n\n#ifdef NUM_COAT_NORMAL_MAPS\nvec3 coat_frame_normal(vec3 inputNormal, vec3 face, vec3 view) {\n bool front = dot(face, view) >= 0.0;\n vec3 ffFace = front ? face : -face;\n vec3 ffInput = front ? inputNormal : -inputNormal;\n if (dot(inputNormal, face) <= 0.0 || dot(ffInput, view) <= 1e-6) { return ffFace; }\n return ffInput;\n}\n#endif\nvoid SampleMaterial(inout SurfaceInteraction si, OpenPbrResolvedMaterial mat, inout Path path) {\n vec3 matRnd = vec3(sample2D(bounceDim(BSDF_DIRECTION)), sample1D(bounceDim(BSDF_LOBE)));\n#ifdef NUM_COAT_NORMAL_MAPS\n vec3 originalFace = si.faceNormal;\n vec3 originalNormal = si.normal;\n#endif\n float ndv1 = -dot(si.faceNormal, path.ray.d);\n float ndv2 = -dot(si.normal, path.ray.d);\n if ((mat.transmissionWeight > 0.0 || mat.subsurfaceWeight > 0.0) && mat.thinWalled) {\n // Always treat thin material as entering medium\n if (ndv1 < 0.0) {\n si.faceNormal = -si.faceNormal;\n ndv1 = -ndv1;\n }\n if (ndv2 < 0.0) {\n si.normal = -si.normal;\n ndv2 = -ndv2;\n }\n }\n // In same edge cases normal is not torwards the camera while we can still see the face.\n // We need to choose faceNormal in this case.\n bool useFaceN = ndv1 >= 0.0 && ndv2 < 0.0;\n float ndv = useFaceN ? ndv1 : ndv2;\n vec3 normal = useFaceN ? si.faceNormal : si.normal;\n\n mat.inside = ndv <= 0.0 && !mat.thinWalled;\n // In or out\n mat.relativeIor = ndv > 0.0 ? (1.0 / mat.specularIor) : mat.specularIor;\n vec3 ffnormal = ndv >= 0.0 ? normal : -normal;\n#ifdef NUM_COAT_NORMAL_MAPS\n if (mat.coatNormalEnabled) {\n vec3 view = -path.ray.d;\n float geometricView = dot(originalFace, view);\n mat.geometricNormal = geometricView >= 0.0 ? originalFace : -originalFace;\n ffnormal = coat_frame_normal(originalNormal, originalFace, view);\n mat.coatNormal = coat_frame_normal(si.coatNormal, originalFace, view);\n mat.inside = geometricView <= 0.0 && !mat.thinWalled;\n mat.relativeIor = (geometricView > 0.0 || mat.thinWalled) ? 1.0 / mat.specularIor : mat.specularIor;\n }\n#endif\n\n\n float scatteringPdf;\n vec3 scatterDir;\n path.scatteringIsDelta = false;\n bool mediumSampled = false;\n bool crossedBoundary = false;\n OpenPbrPreparedBsdf prepared;\n\n#ifdef HAS_MEDIUM\n int mediumType = si.mediumType;\n float d = distance(si.position, path.ray.o);\n vec3 segmentOrigin = path.ray.o;\n vec3 extinction = si.mediumExtinction;\n vec3 scattering = min(si.mediumScattering, extinction);\n float majorant = max(max(extinction.x, extinction.y), extinction.z);\n if (mediumType > 0 && majorant > 0.0) {\n // Sample one RGB extinction channel and divide by the mixture PDF. This\n // is the homogeneous-medium estimator used by PBRT and avoids the very\n // large exp((majorant - extinction) * distance) weights produced by\n // majorant tracking when OpenPBR SSS radii differ strongly by channel.\n int mediumChannel = min(int(sample1D(bounceDim(MEDIUM_CHANNEL)) * 3.0), 2);\n float channelExtinction = extinction[mediumChannel];\n float scatterDist = channelExtinction > 0.0\n ? min(-log(max(sample1D(bounceDim(MEDIUM_DISTANCE)), 1e-7)) / channelExtinction, d)\n : d;\n mediumSampled = scatterDist < d;\n vec3 transmittance = exp(-extinction * scatterDist);\n vec3 density = mediumSampled\n ? extinction * transmittance\n : transmittance;\n float mediumPdf = max(\n (density.x + density.y + density.z) / 3.0,\n 1e-8\n );\n if (mediumSampled) {\n path.beta *= transmittance * scattering / mediumPdf;\n // Move from the start of the segment, not from its end surface.\n path.ray.o = segmentOrigin + scatterDist * path.ray.d;\n si.position = path.ray.o;\n path.li += DirectLight(si, mat, prepared, path, ffnormal, false) * path.beta;\n\n // Pick a new direction based on the phase function\n scatterDir = sampling_henyey_greenstein(\n -path.ray.d,\n si.mediumAnisotropy,\n sample2D(bounceDim(PHASE_DIRECTION))\n );\n scatteringPdf = sampling_henyey_greenstein_phase(\n dot(scatterDir, -path.ray.d),\n si.mediumAnisotropy\n );\n }\n else {\n path.beta *= transmittance / mediumPdf;\n }\n }\n#endif\n\n // Direct lighting\n if (!mediumSampled) {\n path.li += mat.emission * path.beta;\n if (mat.materialType == UNLIT) {\n path.abort = true;\n return;\n }\n vec3 surfaceTangent = vec3(0.0);\n#ifdef USE_TANGENT\n surfaceTangent = si.tangent;\n#endif\n mat.directionTangent = si.directionTangent;\n mat.directionBitangent = si.directionBitangent;\n mat.geometryTangent = si.geometryTangent;\n mat.geometryBitangent = si.geometryBitangent;\n prepared = openpbr_prepare(surfaceTangent, mat, -path.ray.d, ffnormal);\n path.li += DirectLight(si, mat, prepared, path, ffnormal, true) * path.beta;\n // Sample BSDF for color and outgoing direction\n bool isNextRefraction;\n vec3 f = openpbr_sample_prepared(\n prepared,\n matRnd,\n scatterDir,\n scatteringPdf,\n isNextRefraction\n );\n // Null-boundary transmission is discrete and has no NEE competitor.\n path.scatteringIsDelta = !prepared.material.thinWalled &&\n abs(prepared.material.relativeIor - 1.0) <= 1e-6 &&\n prepared.probabilities[OPENPBR_LOBE_TRANSMISSION] >= 1.0 - 1e-6;\n // Match WebGPU: rejected VNDF/refraction proposals have no continuation.\n // Tracing their fallback direction with the incoming throughput invents\n // light paths, especially after total internal reflection inside glass.\n if (!(scatteringPdf > 0.0) || any(isnan(f)) || any(isinf(f)) ||\n dot(scatterDir, scatterDir) < 0.5) {\n path.scatteringPdf = 0.0;\n path.abort = true;\n return;\n }\n path.beta *= f / scatteringPdf;\n crossedBoundary = !mat.thinWalled &&\n isNextRefraction;\n path.isNextRefraction = isNextRefraction;\n // TODO prefer the opaque surface when transmission surface and opaque surface are overlapped.\n // Or the ray go out from transmission material will miss the opque surface.\n path.ray.o = si.position + EPS * scatterDir;\n#ifdef NUM_COAT_NORMAL_MAPS\n if (mat.coatNormalEnabled) { path.ray.o = si.position + EPS * (dot(originalFace, scatterDir) >= 0.0 ? originalFace : -originalFace); }\n#endif\n }\n\n path.scatteringPdf = scatteringPdf;\n initRay(path.ray, path.ray.o, scatterDir);\n if (mediumSampled) {\n path.isNextRefraction = false;\n }\n path.fromEye = false;\n\n#ifdef HAS_MEDIUM\n // A reflected ray stays in its current medium. Only a sampled transmission\n // event crosses the boundary of a medium-bearing closed mesh.\n if (!mediumSampled && crossedBoundary && mat.mediumType > 0) {\n if (ndv1 >= 0.0) {\n si.mediumType = mat.mediumType;\n si.mediumExtinction = mat.mediumExtinction;\n si.mediumScattering = mat.mediumScattering;\n si.mediumAnisotropy = mat.mediumAnisotropy;\n }\n else {\n si.mediumType = 0;\n si.mediumExtinction = vec3(0.0);\n si.mediumScattering = vec3(0.0);\n si.mediumAnisotropy = 0.0;\n }\n }\n#endif\n}\n`;\n"]}
|
|
1
|
+
{"version":3,"file":"sampleMaterial.glsl.js","sourceRoot":"","sources":["../../../../src/renderer/glsl/chunks/sampleMaterial.glsl.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,iIAAiI;AAEjI,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,eAAe,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkRlB,CAAC","sourcesContent":["// Estimate the direct lighting integral using multiple importance sampling\n// http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Direct_Lighting.html#EstimatingtheDirectLightingIntegral\n\nimport { glsl } from '../../shader.js';\nexport default glsl`\nvec3 DirectLight(SurfaceInteraction si, OpenPbrResolvedMaterial mat, OpenPbrPreparedBsdf prepared, inout Path path, vec3 ffnormal, bool isSurface) {\n float occluded = 1.0;\n vec3 lightRnd = vec3(sample2D(bounceDim(LIGHT_POSITION)), sample1D(bounceDim(LIGHT_SELECT)));\n\n LightSampleRec lightSample;\n sampleLight(si.position, lightRnd, lightSample, false);\n lightSample.emission = sampling_spectral_rgb_filter(lightSample.emission, pathWavelength);\n\n vec3 lightDir = lightSample.direction;\n vec3 viewDir = -path.ray.d;\n float lightPdf = lightSample.pdf;\n // Opaque surfaces are rendered two-sided by the core renderer. Use the\n // face-forward shading normal here as well, otherwise the early-out rejects\n // every direct-light sample seen from the back of a triangle (for example\n // the inside of an imported room wall).\n float cosThetaL = dot(ffnormal, lightDir);\n#ifdef USE_COAT_NORMAL_FRAMES\n if (isSurface && mat.coatNormalEnabled) { cosThetaL = dot(mat.geometricNormal, lightDir); }\n#endif\n\n if (lightPdf <= 0.0 || max(max(lightSample.emission.x, lightSample.emission.y), lightSample.emission.z) <= 0.0) {\n return vec3(0.0);\n }\n\n float scatteringPdf = 0.0;\n vec3 f = vec3(0.0);\n if (isSurface) {\n if (cosThetaL <= 0.0 && mat.transmissionWeight <= 0.0 && mat.subsurfaceWeight <= 0.0) {\n return vec3(0.0);\n }\n f = openpbr_eval_prepared(prepared, lightDir, scatteringPdf);\n }\n else {\n scatteringPdf = sampling_henyey_greenstein_phase(\n dot(viewDir, lightDir),\n si.mediumAnisotropy\n );\n f = vec3(scatteringPdf);\n }\n\n if (scatteringPdf <= 0.0 || max(max(f.x, f.y), f.z) <= 0.0) {\n return vec3(0.0);\n }\n\n Ray lightRay;\n vec3 shadowOrigin = si.position + EPS * lightDir;\n if (isSurface) {\n const float shadowTerminatorCutoff = 0.1;\n float normalLight = dot(si.normal, lightDir);\n#ifdef USE_COAT_NORMAL_FRAMES\n if (mat.coatNormalEnabled) { normalLight = dot(si.faceNormal, lightDir); }\n#endif\n vec3 geometricNormal = normalLight < 0.0 ? -si.faceNormal : si.faceNormal;\n normalLight = abs(normalLight);\n float geometricLight = dot(geometricNormal, lightDir);\n float offsetAmount = normalLight < shadowTerminatorCutoff\n ? clamp(\n 2.0 - (geometricLight + normalLight) / shadowTerminatorCutoff,\n 0.0,\n 1.0\n )\n : clamp(1.0 - geometricLight / shadowTerminatorCutoff, 0.0, 1.0);\n shadowOrigin += si.shadowOffset * offsetAmount;\n }\n initRay(lightRay, shadowOrigin, lightDir);\n if (intersectSceneShadow(lightRay, lightSample.dist - EPS, si.triangleIndex)) {\n return vec3(0.0);\n }\n\n#ifdef USE_ENVMAP\n // Match the endpoint used by a BSDF-sampled surface transmission, including\n // a separately displayed or grounded background and its coverage.\n if (isSurface && cosThetaL < 0.0 && lightRnd.z < envLightSelectionPmf) {\n vec4 background = sampleBackgroundFromRay(lightRay.o, lightDir);\n lightSample.emission = sampling_spectral_rgb_filter(background.rgb * background.a, pathWavelength);\n }\n#endif\n\n // Delta lights cannot be sampled by the BSDF strategy, so their MIS weight\n // is exactly one even when their light-selection PMF is small.\n float misWeight = lightSample.isDelta\n ? 1.0\n : sampling_power_heuristic(lightPdf, scatteringPdf);\n return misWeight > 0.0\n ? misWeight * lightSample.emission * f / lightPdf\n : vec3(0.0);\n}\n\n#ifdef USE_COAT_NORMAL_FRAMES\nvec3 coat_frame_normal(vec3 inputNormal, vec3 face, vec3 view) {\n bool front = dot(face, view) >= 0.0;\n vec3 ffFace = front ? face : -face;\n vec3 ffInput = front ? inputNormal : -inputNormal;\n if (dot(inputNormal, face) <= 0.0 || dot(ffInput, view) <= 1e-6) { return ffFace; }\n return ffInput;\n}\n#endif\nvoid SampleMaterial(inout SurfaceInteraction si, OpenPbrResolvedMaterial mat, inout Path path) {\n vec3 matRnd = vec3(sample2D(bounceDim(BSDF_DIRECTION)), sample1D(bounceDim(BSDF_LOBE)));\n#ifdef USE_COAT_NORMAL_FRAMES\n vec3 originalFace = si.faceNormal;\n vec3 originalNormal = si.normal;\n#endif\n float ndv1 = -dot(si.faceNormal, path.ray.d);\n float ndv2 = -dot(si.normal, path.ray.d);\n if ((mat.transmissionWeight > 0.0 || mat.subsurfaceWeight > 0.0) && mat.thinWalled) {\n // Always treat thin material as entering medium\n if (ndv1 < 0.0) {\n si.faceNormal = -si.faceNormal;\n ndv1 = -ndv1;\n }\n if (ndv2 < 0.0) {\n si.normal = -si.normal;\n ndv2 = -ndv2;\n }\n }\n // In same edge cases normal is not torwards the camera while we can still see the face.\n // We need to choose faceNormal in this case.\n bool useFaceN = ndv1 >= 0.0 && ndv2 < 0.0;\n float ndv = useFaceN ? ndv1 : ndv2;\n vec3 normal = useFaceN ? si.faceNormal : si.normal;\n\n mat.inside = ndv <= 0.0 && !mat.thinWalled;\n // In or out\n mat.relativeIor = ndv > 0.0 ? (1.0 / mat.specularIor) : mat.specularIor;\n vec3 ffnormal = ndv >= 0.0 ? normal : -normal;\n#ifdef USE_COAT_NORMAL_FRAMES\n if (mat.coatNormalEnabled) {\n vec3 view = -path.ray.d;\n float geometricView = dot(originalFace, view);\n mat.geometricNormal = geometricView >= 0.0 ? originalFace : -originalFace;\n ffnormal = coat_frame_normal(originalNormal, originalFace, view);\n mat.coatNormal = coat_frame_normal(si.coatNormal, originalFace, view);\n mat.inside = geometricView <= 0.0 && !mat.thinWalled;\n mat.relativeIor = (geometricView > 0.0 || mat.thinWalled) ? 1.0 / mat.specularIor : mat.specularIor;\n }\n#endif\n\n\n float scatteringPdf;\n vec3 scatterDir;\n path.scatteringIsDelta = false;\n bool mediumSampled = false;\n bool crossedBoundary = false;\n OpenPbrPreparedBsdf prepared;\n\n#ifdef HAS_MEDIUM\n int mediumType = si.mediumType;\n float d = distance(si.position, path.ray.o);\n vec3 segmentOrigin = path.ray.o;\n vec3 extinction = si.mediumExtinction;\n vec3 scattering = min(si.mediumScattering, extinction);\n float majorant = max(max(extinction.x, extinction.y), extinction.z);\n if (mediumType > 0 && majorant > 0.0) {\n // Sample one RGB extinction channel and divide by the mixture PDF. This\n // is the homogeneous-medium estimator used by PBRT and avoids the very\n // large exp((majorant - extinction) * distance) weights produced by\n // majorant tracking when OpenPBR SSS radii differ strongly by channel.\n int mediumChannel = min(int(sample1D(bounceDim(MEDIUM_CHANNEL)) * 3.0), 2);\n float channelExtinction = extinction[mediumChannel];\n float scatterDist = channelExtinction > 0.0\n ? min(-log(max(sample1D(bounceDim(MEDIUM_DISTANCE)), 1e-7)) / channelExtinction, d)\n : d;\n mediumSampled = scatterDist < d;\n vec3 transmittance = exp(-extinction * scatterDist);\n vec3 density = mediumSampled\n ? extinction * transmittance\n : transmittance;\n float mediumPdf = max(\n (density.x + density.y + density.z) / 3.0,\n 1e-8\n );\n if (mediumSampled) {\n path.beta *= transmittance * scattering / mediumPdf;\n // Move from the start of the segment, not from its end surface.\n path.ray.o = segmentOrigin + scatterDist * path.ray.d;\n si.position = path.ray.o;\n path.li += DirectLight(si, mat, prepared, path, ffnormal, false) * path.beta;\n\n // Pick a new direction based on the phase function\n scatterDir = sampling_henyey_greenstein(\n -path.ray.d,\n si.mediumAnisotropy,\n sample2D(bounceDim(PHASE_DIRECTION))\n );\n scatteringPdf = sampling_henyey_greenstein_phase(\n dot(scatterDir, -path.ray.d),\n si.mediumAnisotropy\n );\n }\n else {\n path.beta *= transmittance / mediumPdf;\n }\n }\n#endif\n\n // Direct lighting\n if (!mediumSampled) {\n path.li += mat.emission * path.beta;\n if (mat.materialType == UNLIT) {\n path.abort = true;\n return;\n }\n vec3 surfaceTangent = vec3(0.0);\n#ifdef USE_TANGENT\n surfaceTangent = si.tangent;\n#endif\n mat.directionTangent = si.directionTangent;\n mat.directionBitangent = si.directionBitangent;\n mat.geometryTangent = si.geometryTangent;\n mat.geometryBitangent = si.geometryBitangent;\n prepared = openpbr_prepare(surfaceTangent, mat, -path.ray.d, ffnormal);\n path.li += DirectLight(si, mat, prepared, path, ffnormal, true) * path.beta;\n // Sample BSDF for color and outgoing direction\n bool isNextRefraction;\n vec3 f = openpbr_sample_prepared(\n prepared,\n matRnd,\n scatterDir,\n scatteringPdf,\n isNextRefraction\n );\n // Null-boundary transmission is discrete and has no NEE competitor.\n path.scatteringIsDelta = !prepared.material.thinWalled &&\n abs(prepared.material.relativeIor - 1.0) <= 1e-6 &&\n prepared.probabilities[OPENPBR_LOBE_TRANSMISSION] >= 1.0 - 1e-6;\n // Match WebGPU: rejected VNDF/refraction proposals have no continuation.\n // Tracing their fallback direction with the incoming throughput invents\n // light paths, especially after total internal reflection inside glass.\n if (!(scatteringPdf > 0.0) || any(isnan(f)) || any(isinf(f)) ||\n dot(scatterDir, scatterDir) < 0.5) {\n path.scatteringPdf = 0.0;\n path.abort = true;\n return;\n }\n path.beta *= f / scatteringPdf;\n crossedBoundary = !mat.thinWalled &&\n isNextRefraction;\n path.isNextRefraction = isNextRefraction;\n // TODO prefer the opaque surface when transmission surface and opaque surface are overlapped.\n // Or the ray go out from transmission material will miss the opque surface.\n path.ray.o = si.position + EPS * scatterDir;\n#ifdef USE_COAT_NORMAL_FRAMES\n if (mat.coatNormalEnabled) { path.ray.o = si.position + EPS * (dot(originalFace, scatterDir) >= 0.0 ? originalFace : -originalFace); }\n#endif\n }\n\n path.scatteringPdf = scatteringPdf;\n initRay(path.ray, path.ray.o, scatterDir);\n if (mediumSampled) {\n path.isNextRefraction = false;\n }\n path.fromEye = false;\n\n#ifdef HAS_MEDIUM\n // A reflected ray stays in its current medium. Only a sampled transmission\n // event crosses the boundary of a medium-bearing closed mesh.\n if (!mediumSampled && crossedBoundary && mat.mediumType > 0) {\n if (ndv1 >= 0.0) {\n si.mediumType = mat.mediumType;\n si.mediumExtinction = mat.mediumExtinction;\n si.mediumScattering = mat.mediumScattering;\n si.mediumAnisotropy = mat.mediumAnisotropy;\n }\n else {\n si.mediumType = 0;\n si.mediumExtinction = vec3(0.0);\n si.mediumScattering = vec3(0.0);\n si.mediumAnisotropy = 0.0;\n }\n }\n#endif\n}\n`;\n"]}
|
|
@@ -11,33 +11,33 @@ export default glsl `
|
|
|
11
11
|
|
|
12
12
|
const uint SHADOW_CATCHER_LIGHT_SAMPLES = 4u;
|
|
13
13
|
|
|
14
|
-
uint
|
|
14
|
+
uint ky(uint candidate, uint slot) {
|
|
15
15
|
return candidate == 0u ? cw(slot) : cw(9u + (candidate - 1u) * 3u + slot);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
void sampleShadowCatcher(ad si, int bounce, inout Path aa) {
|
|
19
|
-
vec3
|
|
19
|
+
vec3 oS = -aa.ray.d;
|
|
20
20
|
|
|
21
21
|
#if defined(NUM_LIGHTS) || defined(USE_ENVMAP)
|
|
22
22
|
float visibility = 0.0;
|
|
23
23
|
for (uint candidate = 0u; candidate < SHADOW_CATCHER_LIGHT_SAMPLES; candidate++) {
|
|
24
24
|
LightSampleRec lightSample;
|
|
25
|
-
vec3
|
|
26
|
-
|
|
27
|
-
dz(
|
|
25
|
+
vec3 ln = vec3(
|
|
26
|
+
fp(ky(candidate, LIGHT_POSITION)),
|
|
27
|
+
dz(ky(candidate, LIGHT_SELECT))
|
|
28
28
|
);
|
|
29
|
-
sampleLight(si.position,
|
|
29
|
+
sampleLight(si.position, ln, lightSample, false);
|
|
30
30
|
|
|
31
31
|
vec3 lightDir = lightSample.direction;
|
|
32
32
|
float cosThetaL = dot(si.normal, lightDir);
|
|
33
|
-
float
|
|
34
|
-
bool
|
|
35
|
-
if (
|
|
33
|
+
float pM = dot(si.normal, oS) * cosThetaL;
|
|
34
|
+
bool mC = false;
|
|
35
|
+
if (pM >= 0.0) {
|
|
36
36
|
Ray ray;
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
iC(ray, si.position + EPS * lightDir, lightDir);
|
|
38
|
+
mC = ex(ray, lightSample.dist - EPS, si.triangleIndex);
|
|
39
39
|
}
|
|
40
|
-
visibility +=
|
|
40
|
+
visibility += mC ? 0.0 : 1.0;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
aa.alpha = visibility / float(SHADOW_CATCHER_LIGHT_SAMPLES);
|
|
@@ -5,70 +5,70 @@ export default glsl `
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
vec3 aQ(vec3 view, vec2 alpha, vec2 samplePoint) {
|
|
8
|
-
vec3
|
|
9
|
-
vec3
|
|
10
|
-
float
|
|
11
|
-
float
|
|
12
|
-
float
|
|
13
|
-
float
|
|
14
|
-
float
|
|
15
|
-
float
|
|
8
|
+
vec3 rm = vec3(alpha, 1.0);
|
|
9
|
+
vec3 gk = normalize(rm * view);
|
|
10
|
+
float uh = min(gk.z, 1.0);
|
|
11
|
+
float qQ = 1.0 + uh;
|
|
12
|
+
float rh = (1.0 - samplePoint.y) * qQ;
|
|
13
|
+
float rR = samplePoint.y * qQ;
|
|
14
|
+
float sI = rh + (1.0 - uh);
|
|
15
|
+
float fl = sqrt(max(0.0, sI * rR));
|
|
16
16
|
float br = TWOPI * samplePoint.x;
|
|
17
|
-
vec3
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
vec3 lI = vec3(
|
|
18
|
+
gk.x + fl * cos(br),
|
|
19
|
+
gk.y + fl * sin(br),
|
|
20
|
+
rh
|
|
21
21
|
);
|
|
22
|
-
return normalize(
|
|
22
|
+
return normalize(rm * lI);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
float
|
|
26
|
-
vec3
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
float gL(vec3 oo, vec2 alpha) {
|
|
26
|
+
vec3 hr = vec3(
|
|
27
|
+
oo.x / alpha.x,
|
|
28
|
+
oo.y / alpha.y,
|
|
29
|
+
oo.z
|
|
30
30
|
);
|
|
31
|
-
float ap = dot(
|
|
31
|
+
float ap = dot(hr, hr);
|
|
32
32
|
return 1.0 / (
|
|
33
33
|
PI * alpha.x * alpha.y * ap * ap
|
|
34
34
|
);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
float bk(vec3 direction, vec2 alpha) {
|
|
38
|
-
float
|
|
39
|
-
if (
|
|
38
|
+
float eF = abs(direction.z);
|
|
39
|
+
if (eF <= 1e-8) {
|
|
40
40
|
return 0.0;
|
|
41
41
|
}
|
|
42
|
-
vec2
|
|
43
|
-
float
|
|
44
|
-
/ (
|
|
45
|
-
return 2.0 / (1.0 + sqrt(1.0 +
|
|
42
|
+
vec2 ic = alpha * direction.xy;
|
|
43
|
+
float lJ = dot(ic, ic)
|
|
44
|
+
/ (eF * eF);
|
|
45
|
+
return 2.0 / (1.0 + sqrt(1.0 + lJ));
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
float aE(float au) {
|
|
49
|
-
float
|
|
50
|
-
return pow(
|
|
49
|
+
float di = clamp(1.0 - au, 0.0, 1.0);
|
|
50
|
+
return pow(di, 5.0);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
float cu(float L, float cJ) {
|
|
54
|
-
float
|
|
55
|
-
float
|
|
56
|
-
* max(0.0, 1.0 -
|
|
57
|
-
if (
|
|
54
|
+
float iA = clamp(abs(L), 0.0, 1.0);
|
|
55
|
+
float kl = cJ * cJ
|
|
56
|
+
* max(0.0, 1.0 - iA * iA);
|
|
57
|
+
if (kl >= 1.0) {
|
|
58
58
|
return 1.0;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
float
|
|
62
|
-
float ba = (
|
|
63
|
-
/ max(
|
|
64
|
-
float
|
|
65
|
-
/ max(cJ *
|
|
61
|
+
float lT = sqrt(max(0.0, 1.0 - kl));
|
|
62
|
+
float ba = (iA - cJ * lT)
|
|
63
|
+
/ max(iA + cJ * lT, 1e-8);
|
|
64
|
+
float pN = (cJ * iA - lT)
|
|
65
|
+
/ max(cJ * iA + lT, 1e-8);
|
|
66
66
|
return 0.5 * (
|
|
67
|
-
ba * ba +
|
|
67
|
+
ba * ba + pN * pN
|
|
68
68
|
);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
vec2
|
|
71
|
+
vec2 gi(vec2 samplePoint) {
|
|
72
72
|
vec2 offset = 2.0 * samplePoint - vec2(1.0);
|
|
73
73
|
if (offset.x == 0.0 && offset.y == 0.0) {
|
|
74
74
|
return vec2(0.0);
|
|
@@ -88,35 +88,35 @@ return radius * vec2(cos(angle), sin(angle));
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
vec3 bi(vec2 samplePoint) {
|
|
91
|
-
vec2
|
|
91
|
+
vec2 kF = gi(samplePoint);
|
|
92
92
|
return vec3(
|
|
93
|
-
|
|
94
|
-
sqrt(max(0.0, 1.0 - dot(
|
|
93
|
+
kF,
|
|
94
|
+
sqrt(max(0.0, 1.0 - dot(kF, kF)))
|
|
95
95
|
);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
float aG(float
|
|
99
|
-
float scale = max(
|
|
98
|
+
float aG(float pr, float nN) {
|
|
99
|
+
float scale = max(pr, nN);
|
|
100
100
|
if (scale <= 0.0) {
|
|
101
101
|
return 0.0;
|
|
102
102
|
}
|
|
103
|
-
vec2 normalized = vec2(
|
|
104
|
-
vec2
|
|
105
|
-
return
|
|
103
|
+
vec2 normalized = vec2(pr, nN) / scale;
|
|
104
|
+
vec2 oO = normalized * normalized;
|
|
105
|
+
return oO.x / (oO.x + oO.y);
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
void aL(in vec3 normal, out vec3 tangent, out vec3 bitangent) {
|
|
109
|
-
float
|
|
110
|
-
float dW = -1.0 / (
|
|
109
|
+
float ik = normal.z >= 0.0 ? 1.0 : -1.0;
|
|
110
|
+
float dW = -1.0 / (ik + normal.z);
|
|
111
111
|
float xy = normal.x * normal.y * dW;
|
|
112
112
|
tangent = vec3(
|
|
113
|
-
1.0 +
|
|
114
|
-
|
|
115
|
-
-
|
|
113
|
+
1.0 + ik * normal.x * normal.x * dW,
|
|
114
|
+
ik * xy,
|
|
115
|
+
-ik * normal.x
|
|
116
116
|
);
|
|
117
117
|
bitangent = vec3(
|
|
118
118
|
xy,
|
|
119
|
-
|
|
119
|
+
ik + normal.y * normal.y * dW,
|
|
120
120
|
-normal.y
|
|
121
121
|
);
|
|
122
122
|
}
|
|
@@ -125,40 +125,40 @@ vec3 ai(vec3 rgb, float wavelength) {
|
|
|
125
125
|
if (wavelength == 0.0) {
|
|
126
126
|
return rgb;
|
|
127
127
|
}
|
|
128
|
-
vec3
|
|
128
|
+
vec3 tN = wavelength > 600.0
|
|
129
129
|
? vec3(1.0, 0.0, 0.0)
|
|
130
130
|
: wavelength > 500.0
|
|
131
131
|
? vec3(0.0, 1.0, 0.0)
|
|
132
132
|
: vec3(0.0, 0.0, 1.0);
|
|
133
|
-
return rgb *
|
|
133
|
+
return rgb * tN;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
float
|
|
136
|
+
float eN(
|
|
137
137
|
float wavelength,
|
|
138
|
-
float
|
|
139
|
-
float
|
|
140
|
-
float
|
|
138
|
+
float hh,
|
|
139
|
+
float hp,
|
|
140
|
+
float qs
|
|
141
141
|
) {
|
|
142
|
-
if (wavelength == 0.0 ||
|
|
143
|
-
return
|
|
142
|
+
if (wavelength == 0.0 || hp <= 0.0) {
|
|
143
|
+
return hh;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
const float FRAUNHOFER_C = 656.3;
|
|
147
147
|
const float FRAUNHOFER_D = 587.6;
|
|
148
148
|
const float FRAUNHOFER_F = 486.1;
|
|
149
|
-
float
|
|
149
|
+
float jR = 1.0 / (
|
|
150
150
|
1.0 / (FRAUNHOFER_F * FRAUNHOFER_F)
|
|
151
151
|
- 1.0 / (FRAUNHOFER_C * FRAUNHOFER_C)
|
|
152
152
|
);
|
|
153
|
-
float
|
|
154
|
-
float
|
|
155
|
-
float
|
|
156
|
-
-
|
|
157
|
-
return
|
|
153
|
+
float ng = max(qs / hp, 1e-6);
|
|
154
|
+
float qR = (hh - 1.0) * jR / ng;
|
|
155
|
+
float tl = hh
|
|
156
|
+
- qR / (FRAUNHOFER_D * FRAUNHOFER_D);
|
|
157
|
+
return tl + qR / (wavelength * wavelength);
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
vec3
|
|
161
|
-
vec3
|
|
160
|
+
vec3 fq(
|
|
161
|
+
vec3 gz,
|
|
162
162
|
float anisotropy,
|
|
163
163
|
vec2 samplePoint
|
|
164
164
|
) {
|
|
@@ -167,21 +167,21 @@ if (abs(anisotropy) < 0.001) {
|
|
|
167
167
|
au = 1.0 - 2.0 * samplePoint.y;
|
|
168
168
|
}
|
|
169
169
|
else {
|
|
170
|
-
float
|
|
170
|
+
float ja = (1.0 - anisotropy * anisotropy)
|
|
171
171
|
/ (1.0 + anisotropy - 2.0 * anisotropy * samplePoint.y);
|
|
172
172
|
au = (
|
|
173
|
-
|
|
173
|
+
ja * ja - 1.0 - anisotropy * anisotropy
|
|
174
174
|
) / (2.0 * anisotropy);
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
float
|
|
177
|
+
float ud = sqrt(max(0.0, 1.0 - au * au));
|
|
178
178
|
float br = TWOPI * samplePoint.x;
|
|
179
179
|
vec3 tangent;
|
|
180
180
|
vec3 bitangent;
|
|
181
|
-
aL(
|
|
182
|
-
return tangent * (
|
|
183
|
-
+ bitangent * (
|
|
184
|
-
+
|
|
181
|
+
aL(gz, tangent, bitangent);
|
|
182
|
+
return tangent * (ud * cos(br))
|
|
183
|
+
+ bitangent * (ud * sin(br))
|
|
184
|
+
+ gz * au;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
float bD(float au, float anisotropy) {
|
|
@@ -28,8 +28,8 @@ uvec2 bc;
|
|
|
28
28
|
uint bd;
|
|
29
29
|
uint cF = 0u;
|
|
30
30
|
uint em = 0u;
|
|
31
|
-
uint eg(uint
|
|
32
|
-
uint x =
|
|
31
|
+
uint eg(uint kt) {
|
|
32
|
+
uint x = kt;
|
|
33
33
|
x ^= x >> 16u; x *= 0x7feb352du;
|
|
34
34
|
x ^= x >> 15u; x *= 0x846ca68bu;
|
|
35
35
|
return x ^ (x >> 16u);
|
|
@@ -37,28 +37,28 @@ return x ^ (x >> 16u);
|
|
|
37
37
|
uint aq(uint a, uint b) {
|
|
38
38
|
return eg(a ^ eg(b + 0x9e3779b9u));
|
|
39
39
|
}
|
|
40
|
-
uint
|
|
41
|
-
uint x =
|
|
40
|
+
uint iE(uint kt, uint ij) {
|
|
41
|
+
uint x = kt + ij;
|
|
42
42
|
x ^= x * 0x6c50b47cu; x ^= x * 0xb82f1e52u;
|
|
43
43
|
x ^= x * 0xc7afe638u; x ^= x * 0x8d22f6e6u;
|
|
44
44
|
return x;
|
|
45
45
|
}
|
|
46
|
-
uint
|
|
47
|
-
return reverseBits(
|
|
46
|
+
uint sK(uint x, uint ij) {
|
|
47
|
+
return reverseBits(iE(reverseBits(x), ij));
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
uint
|
|
51
|
-
uint r = reverseBits(
|
|
50
|
+
uint rl(uint kt) {
|
|
51
|
+
uint r = reverseBits(kt);
|
|
52
52
|
${sobolD1Steps.map(([shift, mask]) => `r ^= (r << ${shift}u) & 0x${mask.toString(16)}u;`).join("\n ")}
|
|
53
53
|
return r;
|
|
54
54
|
}
|
|
55
|
-
vec2
|
|
56
|
-
uint i =
|
|
57
|
-
uint x = reverseBits(
|
|
58
|
-
uint y =
|
|
55
|
+
vec2 vP(uint index, uint ij) {
|
|
56
|
+
uint i = sK(index, aq(ij, 0u));
|
|
57
|
+
uint x = reverseBits(iE(i, aq(ij, 1u)));
|
|
58
|
+
uint y = sK(rl(i), aq(ij, 2u));
|
|
59
59
|
return vec2(float(x >> 8u), float(y >> 8u)) * (1.0 / 16777216.0);
|
|
60
60
|
}
|
|
61
|
-
uint
|
|
61
|
+
uint tB(uvec2 p) {
|
|
62
62
|
uvec2 v = p & uvec2(255u);
|
|
63
63
|
v = (v | (v << uvec2(4u))) & uvec2(0x0f0fu);
|
|
64
64
|
v = (v | (v << uvec2(2u))) & uvec2(0x3333u);
|
|
@@ -66,27 +66,27 @@ v = (v | (v << uvec2(1u))) & uvec2(0x5555u);
|
|
|
66
66
|
return v.x | (v.y << 1u);
|
|
67
67
|
}
|
|
68
68
|
${zSobolPackedPermutations.map((v, i) => `const uint Z_PERM_${i} = ${v}u;`).join("\n")}
|
|
69
|
-
uint
|
|
70
|
-
uint group =
|
|
69
|
+
uint kw(uint tE) {
|
|
70
|
+
uint group = tE >> 2u;
|
|
71
71
|
uint word = Z_PERM_5;
|
|
72
72
|
${[0, 1, 2, 3, 4].map(i => `word = group == ${i}u ? Z_PERM_${i} : word;`).join("\n ")}
|
|
73
|
-
return (word >> ((
|
|
73
|
+
return (word >> ((tE & 3u) * 8u)) & 255u;
|
|
74
74
|
}
|
|
75
|
-
uint
|
|
75
|
+
uint pW(uint kN, uint dim, uint logSPP) {
|
|
76
76
|
uint odd = logSPP & 1u;
|
|
77
|
-
uint
|
|
77
|
+
uint um = 8u + ((logSPP + 1u) >> 1u);
|
|
78
78
|
uint result = 0u;
|
|
79
|
-
for (int digit = int(
|
|
79
|
+
for (int digit = int(um) - 1; digit >= int(odd); digit--) {
|
|
80
80
|
uint shift = 2u*uint(digit) - odd;
|
|
81
81
|
|
|
82
|
-
uint
|
|
83
|
-
if (shift < 30u) {
|
|
84
|
-
uint
|
|
85
|
-
uint d = (
|
|
86
|
-
result |= ((
|
|
82
|
+
uint st = 0u;
|
|
83
|
+
if (shift < 30u) { st = kN >> (shift + 2u); }
|
|
84
|
+
uint tE = (eg(st ^ (0x55555555u * dim)) >> 24u) % 24u;
|
|
85
|
+
uint d = (kN >> shift) & 3u;
|
|
86
|
+
result |= ((kw(tE) >> (2u*d)) & 3u) << shift;
|
|
87
87
|
}
|
|
88
88
|
if (odd != 0u) {
|
|
89
|
-
result |= (
|
|
89
|
+
result |= (kN & 1u) ^ (eg((kN >> 1u) ^ (0x55555555u * dim)) & 1u);
|
|
90
90
|
}
|
|
91
91
|
return result;
|
|
92
92
|
}
|
|
@@ -97,62 +97,62 @@ uint cw(uint slot) {
|
|
|
97
97
|
return CAMERA_BEVEL_BASE + uint(BEVEL_SAMPLES) + cF * BOUNCE_STRIDE + slot;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
uvec4
|
|
101
|
-
uint
|
|
102
|
-
bool
|
|
103
|
-
bool
|
|
104
|
-
uint
|
|
105
|
-
uint
|
|
106
|
-
vec2
|
|
100
|
+
uvec4 hl;
|
|
101
|
+
uint hm;
|
|
102
|
+
bool fC = false;
|
|
103
|
+
bool dg = false;
|
|
104
|
+
uint dF;
|
|
105
|
+
uint gv;
|
|
106
|
+
vec2 eQ;
|
|
107
107
|
void dw(uint dim) {
|
|
108
108
|
|
|
109
|
-
uint
|
|
110
|
-
uvec4 key = uvec4(dim, bd,
|
|
111
|
-
if (
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
uint
|
|
109
|
+
uint kd = bc.x + bc.y * uint(round(1.0 / pixelSize.x));
|
|
110
|
+
uvec4 key = uvec4(dim, bd, kd, uint(sequenceSeed));
|
|
111
|
+
if (fC && all(equal(hl, key)) && hm == uint(zSobolLogSPP)) { return; }
|
|
112
|
+
hl = key; hm = uint(zSobolLogSPP);
|
|
113
|
+
fC = true; dg = false;
|
|
114
|
+
uint ij = aq(aq(kd, dim), uint(sequenceSeed));
|
|
115
115
|
uint index = bd;
|
|
116
116
|
if (samplingPattern == 1) {
|
|
117
117
|
uint logSPP = uint(zSobolLogSPP);
|
|
118
118
|
if (index == 0u) { logSPP = 0u; }
|
|
119
119
|
else { index -= 1u; }
|
|
120
120
|
|
|
121
|
-
uint
|
|
121
|
+
uint jb = index >> logSPP;
|
|
122
122
|
uint mask = (1u << logSPP) - 1u;
|
|
123
|
-
uint
|
|
124
|
-
index =
|
|
123
|
+
uint kN = (tB(bc) << logSPP) | (index & mask);
|
|
124
|
+
index = pW(kN, dim, logSPP);
|
|
125
125
|
uvec2 tile = bc >> uvec2(8u);
|
|
126
|
-
|
|
126
|
+
ij = aq(aq(dim, uint(sequenceSeed)), aq(tile.x, tile.y));
|
|
127
127
|
|
|
128
|
-
if (bd != 0u) {
|
|
129
|
-
|
|
128
|
+
if (bd != 0u) { jb += 1u; }
|
|
129
|
+
ij = aq(ij, jb);
|
|
130
130
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
uint x = reverseBits(
|
|
134
|
-
|
|
131
|
+
dF = sK(index, aq(ij, 0u));
|
|
132
|
+
gv = ij;
|
|
133
|
+
uint x = reverseBits(iE(dF, aq(ij, 1u)));
|
|
134
|
+
eQ.x = float(x >> 8u) * (1.0 / 16777216.0);
|
|
135
135
|
}
|
|
136
|
-
vec2
|
|
136
|
+
vec2 kS(uint dim) {
|
|
137
137
|
dw(dim);
|
|
138
|
-
if (!
|
|
139
|
-
uint y =
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
if (!dg) {
|
|
139
|
+
uint y = sK(rl(dF), aq(gv, 2u));
|
|
140
|
+
eQ.y = float(y >> 8u) * (1.0 / 16777216.0);
|
|
141
|
+
dg = true;
|
|
142
142
|
}
|
|
143
|
-
return EPS + (1.0 - 2.0*EPS) *
|
|
143
|
+
return EPS + (1.0 - 2.0*EPS) * eQ;
|
|
144
144
|
}
|
|
145
145
|
float dz(uint dim) {
|
|
146
146
|
if (samplingPattern == 2) { return EPS + (1.0 - 2.0*EPS)*rand(); }
|
|
147
147
|
dw(dim);
|
|
148
|
-
return EPS + (1.0 - 2.0*EPS) *
|
|
148
|
+
return EPS + (1.0 - 2.0*EPS) * eQ.x;
|
|
149
149
|
}
|
|
150
|
-
vec2
|
|
150
|
+
vec2 fp(uint dim) {
|
|
151
151
|
if (samplingPattern == 2) {
|
|
152
152
|
float x = dz(dim); float y = dz(dim);
|
|
153
153
|
return vec2(x,y);
|
|
154
154
|
}
|
|
155
|
-
return
|
|
155
|
+
return kS(dim);
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
float eo(uint slot) {
|
|
@@ -160,10 +160,10 @@ uint dim = aq(aq(cF, slot), em) | 0x80000000u;
|
|
|
160
160
|
em += 1u;
|
|
161
161
|
if (samplingPattern == 2) { return EPS + (1.0 - 2.0*EPS)*rand(); }
|
|
162
162
|
|
|
163
|
-
uint
|
|
164
|
-
uint
|
|
165
|
-
uint i =
|
|
166
|
-
uint x = reverseBits(
|
|
163
|
+
uint kd = bc.x + bc.y * uint(round(1.0 / pixelSize.x));
|
|
164
|
+
uint ij = aq(aq(kd, dim), uint(sequenceSeed));
|
|
165
|
+
uint i = sK(bd, aq(ij, 0u));
|
|
166
|
+
uint x = reverseBits(iE(i, aq(ij, 1u)));
|
|
167
167
|
return EPS + (1.0 - 2.0*EPS) * (float(x >> 8u) * (1.0 / 16777216.0));
|
|
168
168
|
}
|
|
169
169
|
`;
|
|
@@ -9,16 +9,16 @@ vec4 textureLinear(sampler2D map, vec2 uv) {
|
|
|
9
9
|
return texture(map, uv);
|
|
10
10
|
#else
|
|
11
11
|
vec2 size = vec2(textureSize(map, 0));
|
|
12
|
-
vec2
|
|
12
|
+
vec2 qa = 1.0 / size;
|
|
13
13
|
|
|
14
14
|
uv = uv * size - 0.5;
|
|
15
15
|
vec2 f = fract(uv);
|
|
16
16
|
uv = floor(uv) + 0.5;
|
|
17
17
|
|
|
18
|
-
vec4 s1 = texture(map, (uv + vec2(0, 0)) *
|
|
19
|
-
vec4 s2 = texture(map, (uv + vec2(1, 0)) *
|
|
20
|
-
vec4 s3 = texture(map, (uv + vec2(0, 1)) *
|
|
21
|
-
vec4 s4 = texture(map, (uv + vec2(1, 1)) *
|
|
18
|
+
vec4 s1 = texture(map, (uv + vec2(0, 0)) * qa);
|
|
19
|
+
vec4 s2 = texture(map, (uv + vec2(1, 0)) * qa);
|
|
20
|
+
vec4 s3 = texture(map, (uv + vec2(0, 1)) * qa);
|
|
21
|
+
vec4 s4 = texture(map, (uv + vec2(1, 1)) * qa);
|
|
22
22
|
|
|
23
23
|
return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y);
|
|
24
24
|
#endif
|
|
@@ -8,12 +8,12 @@ float phi = acos(n.y) / PI;
|
|
|
8
8
|
return vec2(theta, 1.0 - phi);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
vec2
|
|
12
|
-
vec3
|
|
11
|
+
vec2 iR(vec3 pos, vec3 normal, vec2 uvScale) {
|
|
12
|
+
vec3 dn = abs(normal);
|
|
13
13
|
vec2 uv = vec2(0.0);
|
|
14
|
-
if (
|
|
14
|
+
if (dn.x > dn.y && dn.x > dn.z) {
|
|
15
15
|
uv = pos.yz;
|
|
16
|
-
} else if (
|
|
16
|
+
} else if (dn.y > dn.x && dn.y > dn.z) {
|
|
17
17
|
uv = pos.xz;
|
|
18
18
|
} else {
|
|
19
19
|
uv = pos.xy;
|
|
@@ -53,18 +53,18 @@ return fract(uv * uvScale);
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
|
|
56
|
-
vec2
|
|
56
|
+
vec2 hD(vec3 pos, vec3 normal) {
|
|
57
57
|
float theta = atan(pos.z, pos.x) / (2.0 * PI) + 0.5;
|
|
58
58
|
return vec2(theta, pos.y);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
vec2
|
|
62
|
-
if (
|
|
63
|
-
return
|
|
64
|
-
} else if (
|
|
61
|
+
vec2 gI(int fk, vec3 pos, vec3 normal, vec2 uvScale) {
|
|
62
|
+
if (fk == ${uvProjectionConstants.triplanar + ''}) {
|
|
63
|
+
return iR(pos, normal, uvScale);
|
|
64
|
+
} else if (fk == ${uvProjectionConstants.spherical + ''}) {
|
|
65
65
|
return sphericalProjection(pos) * uvScale;
|
|
66
|
-
} else if (
|
|
67
|
-
return
|
|
66
|
+
} else if (fk == ${uvProjectionConstants.cylindrical + ''}) {
|
|
67
|
+
return hD(pos, normal) * uvScale;
|
|
68
68
|
}
|
|
69
69
|
return vec2(0.0);
|
|
70
70
|
}
|
|
@@ -33,18 +33,18 @@ if (any(lessThan(uv, vec2(0.0))) || any(greaterThan(uv, vec2(1.0)))) return;
|
|
|
33
33
|
vec4 origin = viewProjectionInv * vec4(uv * 2.0 - 1.0, -1.0, 1.0);
|
|
34
34
|
vec4 target = viewProjectionInv * vec4(uv * 2.0 - 1.0, 1.0, 1.0);
|
|
35
35
|
Ray ray;
|
|
36
|
-
|
|
36
|
+
iC(ray, origin.xyz / origin.w, normalize(target.xyz * origin.w - origin.xyz * target.w));
|
|
37
37
|
vec3 eye = viewInv[3].xyz;
|
|
38
|
-
vec3
|
|
38
|
+
vec3 oj = -normalize(viewInv[2].xyz);
|
|
39
39
|
ad si;
|
|
40
40
|
si.triangleIndex = -1;
|
|
41
41
|
for (int layer = 0; layer < 32; layer++) {
|
|
42
|
-
|
|
42
|
+
cZ(ray, si, false);
|
|
43
43
|
if (!si.hit) return;
|
|
44
44
|
J material;
|
|
45
|
-
|
|
45
|
+
eX(material, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
|
|
46
46
|
if (material.materialType != SHADOW_CATCHER && material.alpha > 0.0) {
|
|
47
|
-
out_depth.r = max(dot(si.position - eye,
|
|
47
|
+
out_depth.r = max(dot(si.position - eye, oj), 0.0);
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
50
|
ray.o = si.position + ray.d * (EPS * 0.02);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"depthQuery.frag.js","sourceRoot":"","sources":["../../../src/renderer/glsl/depthQuery.frag.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,IAAI,MAAM,+BAA+B,CAAC;AACjD,OAAO,SAAS,MAAM,iCAAiC,CAAC;AACxD,OAAO,SAAS,MAAM,4BAA4B,CAAC;AACnD,OAAO,YAAY,MAAM,+BAA+B,CAAC;AACzD,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,IAAI,MAAM,uBAAuB,CAAC;AAEzC,eAAe,IAAI,cAAc,CAAC;IAChC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC;IACtC,OAAO,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE;IACnC,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC;IAC9C,QAAQ,EAAE;QACR,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QACjC,iBAAiB,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QACzC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;KAChC;IACD,IAAI,EAAE,UAAU,CAAC;EACjB,MAAM;EACN,IAAI;EACJ,MAAM,CAAC,IAAI;EACX,IAAI,CAAC,IAAI;EACT,YAAY;EACZ,SAAS,CAAC,IAAI;EACd,SAAS,CAAC,IAAI;;;yCAG2B,iBAAiB,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;CAwB/D;CACA,CAAC,CAAC","sourcesContent":["import { FragmentShader, Shader } from '../shader.js';\nimport { DEPTH_SAMPLE_GRID } from '../depthQuery.js';\nimport common from './chunks/common.glsl.js';\nimport core from './chunks/rayTraceCore.glsl.js';\nimport materials from './chunks/materialBuffer.glsl.js';\nimport intersect from './chunks/intersect.glsl.js';\nimport uvProjection from './chunks/uvProjection.glsl.js';\nimport random from './chunks/random.glsl.js';\nimport rand from './chunks/rand.glsl.js';\n\nexport default new FragmentShader({\n name: 'depthQuery', outputs: ['depth'],\n defines: { DEPTH_QUERY_MODE: true },\n includes: [core, materials, intersect, random],\n uniforms: {\n depthArea: Shader.uniform('vec4'),\n viewProjectionInv: Shader.uniform('mat4'),\n viewInv: Shader.uniform('mat4')\n },\n main: /* glsl */ `\n${common}\n${rand}\n${random.main}\n${core.main}\n${uvProjection}\n${materials.main}\n${intersect.main}\n\nvoid main() {\n vec2 offset = floor(gl_FragCoord.xy) / ${DEPTH_SAMPLE_GRID - 1}.0 * 2.0 - 1.0;\n vec2 uv = depthArea.xy + depthArea.zw * offset * vec2(1.0, -1.0);\n out_depth = vec4(0.0);\n if (any(lessThan(uv, vec2(0.0))) || any(greaterThan(uv, vec2(1.0)))) return;\n vec4 origin = viewProjectionInv * vec4(uv * 2.0 - 1.0, -1.0, 1.0);\n vec4 target = viewProjectionInv * vec4(uv * 2.0 - 1.0, 1.0, 1.0);\n Ray ray;\n initRay(ray, origin.xyz / origin.w, normalize(target.xyz * origin.w - origin.xyz * target.w));\n vec3 eye = viewInv[3].xyz;\n vec3 forward = -normalize(viewInv[2].xyz);\n SurfaceInteraction si;\n si.triangleIndex = -1;\n for (int layer = 0; layer < 32; layer++) {\n intersectScene(ray, si, false);\n if (!si.hit) return;\n OpenPbrResolvedMaterial material;\n getMaterial(material, si.materialIndex, si.uv, si.uv1, si.instanceIndex);\n if (material.materialType != SHADOW_CATCHER && material.alpha > 0.0) {\n out_depth.r = max(dot(si.position - eye, forward), 0.0);\n return;\n }\n ray.o = si.position + ray.d * (EPS * 0.02);\n }\n}\n`\n});\n"]}
|
|
1
|
+
{"version":3,"file":"depthQuery.frag.js","sourceRoot":"","sources":["../../../src/renderer/glsl/depthQuery.frag.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,IAAI,MAAM,+BAA+B,CAAC;AACjD,OAAO,SAAS,MAAM,iCAAiC,CAAC;AACxD,OAAO,SAAS,MAAM,4BAA4B,CAAC;AACnD,OAAO,YAAY,MAAM,+BAA+B,CAAC;AACzD,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,IAAI,MAAM,uBAAuB,CAAC;AAEzC,eAAe,IAAI,cAAc,CAAC;IAChC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC;IACtC,OAAO,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE;IACnC,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC;IAC9C,QAAQ,EAAE;QACR,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QACjC,iBAAiB,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QACzC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;KAChC;IACD,IAAI,EAAE,UAAU,CAAC;EACjB,MAAM;EACN,IAAI;EACJ,MAAM,CAAC,IAAI;EACX,IAAI,CAAC,IAAI;EACT,YAAY;EACZ,SAAS,CAAC,IAAI;EACd,SAAS,CAAC,IAAI;;;yCAG2B,iBAAiB,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;CAwB/D;CACA,CAAC,CAAC","sourcesContent":["import { FragmentShader, Shader } from '../shader.js';\nimport { DEPTH_SAMPLE_GRID } from '../depthQuery.js';\nimport common from './chunks/common.glsl.js';\nimport core from './chunks/rayTraceCore.glsl.js';\nimport materials from './chunks/materialBuffer.glsl.js';\nimport intersect from './chunks/intersect.glsl.js';\nimport uvProjection from './chunks/uvProjection.glsl.js';\nimport random from './chunks/random.glsl.js';\nimport rand from './chunks/rand.glsl.js';\n\nexport default new FragmentShader({\n name: 'depthQuery', outputs: ['depth'],\n defines: { DEPTH_QUERY_MODE: true },\n includes: [core, materials, intersect, random],\n uniforms: {\n depthArea: Shader.uniform('vec4'),\n viewProjectionInv: Shader.uniform('mat4'),\n viewInv: Shader.uniform('mat4')\n },\n main: /* glsl */ `\n${common}\n${rand}\n${random.main}\n${core.main}\n${uvProjection}\n${materials.main}\n${intersect.main}\n\nvoid main() {\n vec2 offset = floor(gl_FragCoord.xy) / ${DEPTH_SAMPLE_GRID - 1}.0 * 2.0 - 1.0;\n vec2 uv = depthArea.xy + depthArea.zw * offset * vec2(1.0, -1.0);\n out_depth = vec4(0.0);\n if (any(lessThan(uv, vec2(0.0))) || any(greaterThan(uv, vec2(1.0)))) return;\n vec4 origin = viewProjectionInv * vec4(uv * 2.0 - 1.0, -1.0, 1.0);\n vec4 target = viewProjectionInv * vec4(uv * 2.0 - 1.0, 1.0, 1.0);\n Ray ray;\n initRay(ray, origin.xyz / origin.w, normalize(target.xyz * origin.w - origin.xyz * target.w));\n vec3 eye = viewInv[3].xyz;\n vec3 forward = -normalize(viewInv[2].xyz);\n SurfaceInteraction si;\n si.triangleIndex = -1;\n for (int layer = 0; layer < 32; layer++) {\n intersectScene(ray, si, false);\n if (!si.hit) return;\n OpenPbrResolvedMaterial material;\n getMaterial(material, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);\n if (material.materialType != SHADOW_CATCHER && material.alpha > 0.0) {\n out_depth.r = max(dot(si.position - eye, forward), 0.0);\n return;\n }\n ray.o = si.position + ray.d * (EPS * 0.02);\n }\n}\n`\n});\n"]}
|