UNPKG

@doegis/core

Version:

DOE GIS API

110 lines (88 loc) 5.06 kB
import{c as e}from"../../../../../../chunks/mat4f64.js";import{ReadLinearDepth as o}from"../output/ReadLinearDepth.glsl.js";import{Float2PassUniform as t}from"../../shaderModules/Float2PassUniform.js";import{FloatPassUniform as r}from"../../shaderModules/FloatPassUniform.js";import{glsl as a}from"../../shaderModules/interfaces.js";import{Matrix4PassUniform as i}from"../../shaderModules/Matrix4PassUniform.js";import{Texture2DPassUniform as d}from"../../shaderModules/Texture2DPassUniform.js";function n(e,n){const c=e.fragment;c.include(o),c.uniforms.add(new t("nearFar",((e,o)=>o.camera.nearFar))),c.uniforms.add(new d("depthMap",((e,o)=>o.linearDepthTexture))),c.uniforms.add(new i("proj",((e,o)=>o.ssr.camera.projectionMatrix))),c.uniforms.add(new r("invResolutionHeight",((e,o)=>1/o.ssr.camera.height))),c.uniforms.add(new i("reprojectionMatrix",((e,o)=>o.ssr.reprojectionMatrix))),c.code.add(a` vec2 reprojectionCoordinate(vec3 projectionCoordinate) { vec4 zw = proj * vec4(0.0, 0.0, -projectionCoordinate.z, 1.0); vec4 reprojectedCoord = reprojectionMatrix * vec4(zw.w * (projectionCoordinate.xy * 2.0 - 1.0), zw.z, zw.w); reprojectedCoord.xy /= reprojectedCoord.w; return reprojectedCoord.xy * 0.5 + 0.5; } const int maxSteps = ${n.highStepCount?"150":"75"}; vec4 applyProjectionMat(mat4 projectionMat, vec3 x) { vec4 projectedCoord = projectionMat * vec4(x, 1.0); projectedCoord.xy /= projectedCoord.w; projectedCoord.xy = projectedCoord.xy*0.5 + 0.5; return projectedCoord; } vec3 screenSpaceIntersection(vec3 dir, vec3 startPosition, vec3 viewDir, vec3 normal) { vec3 viewPos = startPosition; vec3 viewPosEnd = startPosition; // Project the start position to the screen vec4 projectedCoordStart = applyProjectionMat(proj, viewPos); vec3 Q0 = viewPos / projectedCoordStart.w; // homogeneous camera space float k0 = 1.0/ projectedCoordStart.w; // advance the position in the direction of the reflection viewPos += dir; vec4 projectedCoordVanishingPoint = applyProjectionMat(proj, dir); // Project the advanced position to the screen vec4 projectedCoordEnd = applyProjectionMat(proj, viewPos); vec3 Q1 = viewPos / projectedCoordEnd.w; // homogeneous camera space float k1 = 1.0/ projectedCoordEnd.w; // calculate the reflection direction in the screen space vec2 projectedCoordDir = (projectedCoordEnd.xy - projectedCoordStart.xy); vec2 projectedCoordDistVanishingPoint = (projectedCoordVanishingPoint.xy - projectedCoordStart.xy); float yMod = min(abs(projectedCoordDistVanishingPoint.y), 1.0); float projectedCoordDirLength = length(projectedCoordDir); float maxSt = float(maxSteps); // normalize the projection direction depending on maximum steps // this determines how blocky the reflection looks vec2 dP = yMod * (projectedCoordDir)/(maxSt * projectedCoordDirLength); // Normalize the homogeneous camera space coordinates vec3 dQ = yMod * (Q1 - Q0)/(maxSt * projectedCoordDirLength); float dk = yMod * (k1 - k0)/(maxSt * projectedCoordDirLength); // initialize the variables for ray marching vec2 P = projectedCoordStart.xy; vec3 Q = Q0; float k = k0; float rayStartZ = -startPosition.z; // estimated ray start depth value float rayEndZ = -startPosition.z; // estimated ray end depth value float prevEstimateZ = -startPosition.z; float rayDiffZ = 0.0; float dDepth; float depth; float rayDiffZOld = 0.0; // early outs if (dot(normal, dir) < 0.0 || dot(-viewDir, normal) < 0.0) return vec3(P, 0.0); for(int i = 0; i < maxSteps-1; i++) { depth = -linearDepthFromTexture(depthMap, P, nearFar); // get linear depth from the depth buffer // estimate depth of the marching ray rayStartZ = prevEstimateZ; dDepth = -rayStartZ - depth; rayEndZ = (dQ.z * 0.5 + Q.z)/ ((dk * 0.5 + k)); rayDiffZ = rayEndZ- rayStartZ; prevEstimateZ = rayEndZ; if(-rayEndZ > nearFar[1] || -rayEndZ < nearFar[0] || P.y < 0.0 || P.y > 1.0 ) { return vec3(P, 0.); } // If we detect a hit - return the intersection point, two conditions: // - dDepth > 0.0 - sampled point depth is in front of estimated depth // - if difference between dDepth and rayDiffZOld is not too large // - if difference between dDepth and 0.025/abs(k) is not too large // - if the sampled depth is not behind far plane or in front of near plane if((dDepth) < 0.025/abs(k) + abs(rayDiffZ) && dDepth > 0.0 && depth > nearFar[0] && depth < nearFar[1] && abs(P.y - projectedCoordStart.y) > invResolutionHeight) { return vec3(P, depth); } // continue with ray marching P += dP; Q.z += dQ.z; k += dk; rayDiffZOld = rayDiffZ; } return vec3(P, 0.0); } `)}class c{constructor(){this.enabled=!1,this.fadeFactor=1,this.reprojectionMatrix=e()}}export{c as SSRUniforms,n as ScreenSpaceReflections};