UNPKG

@babylonjs/core

Version:

Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.

159 lines 8.43 kB
// Do not edit. import { ShaderStore } from "../../Engines/shaderStore.js"; const name = "screenSpaceRayTrace"; const shader = `fn distanceSquared(a: vec2f,b: vec2f)->f32 { var temp=a-b; return dot(temp,temp); } #ifdef SSRAYTRACE_SCREENSPACE_DEPTH fn linearizeDepth(depth: f32,near: f32,far: f32)->f32 { #ifdef SSRAYTRACE_RIGHT_HANDED_SCENE return -(near*far)/(far-depth*(far-near)); #else return (near*far)/(far-depth*(far-near)); #endif } #endif /** \param csOrigin Camera-space ray origin,which must be within the view volume and must have z>0.01 and project within the valid screen rectangle \param csDirection Unit length camera-space ray direction \param projectToPixelMatrix A projection matrix that maps to **pixel** coordinates (**not** [-1,+1] normalized device coordinates). \param csZBuffer The camera-space Z buffer \param csZBufferSize Dimensions of csZBuffer \param csZThickness Camera space csZThickness to ascribe to each pixel in the depth buffer \param nearPlaneZ Positive number. Doesn't have to be THE actual near plane,just a reasonable value for clipping rays headed towards the camera. Should be the actual near plane if screen-space depth is enabled. \param farPlaneZ The far plane for the camera. Used when screen-space depth is enabled. \param stride Step in horizontal or vertical pixels between samples. This is a var because: f32 integer math is slow on GPUs,but should be set to an integer>=1 \param jitterFraction Number between 0 and 1 for how far to bump the ray in stride units to conceal banding artifacts,plus the stride ray offset. \param maxSteps Maximum number of iterations. Higher gives better images but may be slow \param maxRayTraceDistance Maximum camera-space distance to trace before returning a miss \param selfCollisionNumSkip Number of steps to skip at start when raytracing to avar self: voidnull collisions. 1 is a reasonable value,depending on the scene you may need to set this value to 2 \param hitPixel Pixel coordinates of the first intersection with the scene \param numIterations number of iterations performed \param csHitPovar Camera: i32 space location of the ray hit */ fn traceScreenSpaceRay1( csOrigin: vec3f, csDirection: vec3f, projectToPixelMatrix: mat4x4f, csZBuffer: texture_2d<f32>, csZBufferSize: vec2f, #ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER csZBackBuffer: texture_2d<f32>, csZBackSizeFactor: f32, #endif csZThickness: f32, nearPlaneZ: f32, farPlaneZ: f32, stride: f32, jitterFraction: f32, maxSteps: f32, maxRayTraceDistance: f32, selfCollisionNumSkip: f32, startPixel: ptr<function,vec2f>, hitPixel: ptr<function,vec2f>, csHitPoint: ptr<function,vec3f>, numIterations: ptr<function,f32> #ifdef SSRAYTRACE_DEBUG ,debugColor: ptr<function,vec3f> #endif )->bool { #ifdef SSRAYTRACE_RIGHT_HANDED_SCENE var rayLength: f32=select(maxRayTraceDistance,(-nearPlaneZ-csOrigin.z)/csDirection.z,(csOrigin.z+csDirection.z*maxRayTraceDistance)>-nearPlaneZ); #else var rayLength: f32=select(maxRayTraceDistance,(nearPlaneZ-csOrigin.z)/csDirection.z,(csOrigin.z+csDirection.z*maxRayTraceDistance)<nearPlaneZ); #endif var csEndPoint: vec3f=csOrigin+csDirection*rayLength;*hitPixel= vec2f(-1.0,-1.0);var H0: vec4f=projectToPixelMatrix* vec4f(csOrigin,1.0);var H1: vec4f=projectToPixelMatrix* vec4f(csEndPoint,1.0);var k0: f32=1.0/H0.w;var k1: f32=1.0/H1.w;var Q0: vec3f=csOrigin*k0;var Q1: vec3f=csEndPoint*k1;var P0: vec2f=H0.xy*k0;var P1: vec2f=H1.xy*k1; #ifdef SSRAYTRACE_CLIP_TO_FRUSTUM var xMax: f32=csZBufferSize.x-0.5;var xMin=0.5;var yMax=csZBufferSize.y-0.5;var yMin=0.5;var alpha: f32=0.0;if ((P1.y>yMax) || (P1.y<yMin)) {alpha=(P1.y-select(yMin,yMax,(P1.y>yMax)))/(P1.y-P0.y);} if ((P1.x>xMax) || (P1.x<xMin)) {alpha=max(alpha,(P1.x-select(xMin,xMax,(P1.x>xMax)))/(P1.x-P0.x));} P1=mix(P1,P0,alpha); k1=mix(k1,k0,alpha); Q1=mix(Q1,Q0,alpha); #endif P1+= vec2f(select(0.0,0.01,distanceSquared(P0,P1)<0.0001));var delta: vec2f=P1-P0;var permute: bool=false;if (abs(delta.x)<abs(delta.y)) { permute=true;delta=delta.yx;P0=P0.yx;P1=P1.yx; } var stepDirection: f32=sign(delta.x);var invdx: f32=stepDirection/delta.x;var dP: vec2f= vec2f(stepDirection,delta.y*invdx);var dQ: vec3f=(Q1-Q0)*invdx;var dk: f32=(k1-k0)*invdx;var zMin: f32=min(csEndPoint.z,csOrigin.z);var zMax: f32=max(csEndPoint.z,csOrigin.z);dP*=stride; dQ*=stride; dk*=stride;P0+=dP*jitterFraction; Q0+=dQ*jitterFraction; k0+=dk*jitterFraction;var pqk: vec4f= vec4f(P0,Q0.z,k0);var dPQK: vec4f= vec4f(dP,dQ.z,dk);*startPixel=select(P0.xy,P0.yx,permute);var prevZMaxEstimate: f32=csOrigin.z;var rayZMin: f32=prevZMaxEstimate;var rayZMax=prevZMaxEstimate;var sceneZMax: f32=rayZMax+1e4;var end: f32=P1.x*stepDirection;var hit: bool=false;var stepCount: f32;for (stepCount=0.0;(stepCount<=selfCollisionNumSkip) || ((pqk.x*stepDirection)<=end && stepCount<maxSteps && !hit && sceneZMax != 0.0);pqk+=dPQK ) {*hitPixel=select(pqk.xy,pqk.yx,permute);rayZMin=prevZMaxEstimate;rayZMax=(dPQK.z*0.5+pqk.z)/(dPQK.w*0.5+pqk.w);rayZMax=clamp(rayZMax,zMin,zMax);prevZMaxEstimate=rayZMax;if (rayZMin>rayZMax) { var t: f32=rayZMin; rayZMin=rayZMax; rayZMax=t;} sceneZMax=textureLoad(csZBuffer,vec2<i32>(*hitPixel),0).r; #ifdef SSRAYTRACE_SCREENSPACE_DEPTH sceneZMax=linearizeDepth(sceneZMax,nearPlaneZ,farPlaneZ); #endif if (sceneZMax==0.0) { sceneZMax=1e8; } #ifdef SSRAYTRACE_RIGHT_HANDED_SCENE #ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER var sceneBackZ: f32=textureLoad(csZBackBuffer,vec2<i32>(*hitPixel/csZBackSizeFactor),0).r; #ifdef SSRAYTRACE_SCREENSPACE_DEPTH sceneBackZ=linearizeDepth(sceneBackZ,nearPlaneZ,farPlaneZ); #endif if (sceneBackZ==0.0) { sceneBackZ=-1e8; } hit=(rayZMax>=sceneBackZ-csZThickness) && (rayZMin<=sceneZMax); #else hit=(rayZMax>=sceneZMax-csZThickness) && (rayZMin<=sceneZMax); #endif #else #ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER var sceneBackZ: f32=textureLoad(csZBackBuffer,vec2<i32>(*hitPixel/csZBackSizeFactor),0).r; #ifdef SSRAYTRACE_SCREENSPACE_DEPTH sceneBackZ=linearizeDepth(sceneBackZ,nearPlaneZ,farPlaneZ); #endif if (sceneBackZ==0.0) { sceneBackZ=1e8; } hit=(rayZMin<=sceneBackZ+csZThickness) && (rayZMax>=sceneZMax) && (sceneZMax != 0.0); #else hit=(rayZMin<=sceneZMax+csZThickness) && (rayZMax>=sceneZMax); #endif #endif stepCount+=1.0;} pqk-=dPQK;stepCount-=1.0;if (((pqk.x+dPQK.x)*stepDirection)>end || (stepCount+1.0)>=maxSteps || sceneZMax==0.0) {hit=false;} #ifdef SSRAYTRACE_ENABLE_REFINEMENT if (stride>1.0 && hit) {pqk-=dPQK;stepCount-=1.0;var invStride: f32=1.0/stride;dPQK*=invStride;var refinementStepCount: f32=0.0;prevZMaxEstimate=pqk.z/pqk.w;rayZMax=prevZMaxEstimate;sceneZMax=rayZMax+1e7;for (;refinementStepCount<=1.0 || ((refinementStepCount<=stride*1.4) && (rayZMax<sceneZMax) && (sceneZMax != 0.0));pqk+=dPQK) {rayZMin=prevZMaxEstimate;rayZMax=(dPQK.z*0.5+pqk.z)/(dPQK.w*0.5+pqk.w);rayZMax=clamp(rayZMax,zMin,zMax);prevZMaxEstimate=rayZMax;rayZMax=max(rayZMax,rayZMin);*hitPixel=select(pqk.xy,pqk.yx,permute);sceneZMax=textureLoad(csZBuffer,vec2<i32>(*hitPixel),0).r; #ifdef SSRAYTRACE_SCREENSPACE_DEPTH sceneZMax=linearizeDepth(sceneZMax,nearPlaneZ,farPlaneZ); #endif refinementStepCount+=1.0;} pqk-=dPQK;refinementStepCount-=1.0;stepCount+=refinementStepCount/stride;} #endif Q0=vec3f(Q0.xy+dQ.xy*stepCount,pqk.z);*csHitPoint=Q0/pqk.w;*numIterations=stepCount+1.0; #ifdef SSRAYTRACE_DEBUG if (((pqk.x+dPQK.x)*stepDirection)>end) {*debugColor= vec3f(0,0,1);} else if ((stepCount+1.0)>=maxSteps) {*debugColor= vec3f(1,0,0);} else if (sceneZMax==0.0) {*debugColor= vec3f(1,1,0);} else {*debugColor= vec3f(0,stepCount/maxSteps,0);} #endif return hit;} /** texCoord: in the [0,1] range depth: depth in view space (range [znear,zfar]]) */ fn computeViewPosFromUVDepth(texCoord: vec2f,depth: f32,projection: mat4x4f,invProjectionMatrix: mat4x4f)->vec3f {var xy=texCoord*2.0-1.0;var z: f32; #ifdef SSRAYTRACE_RIGHT_HANDED_SCENE #ifdef ORTHOGRAPHIC_CAMERA z=-projection[2].z*depth+projection[3].z; #else z=-projection[2].z-projection[3].z/depth; #endif #else #ifdef ORTHOGRAPHIC_CAMERA z=projection[2].z*depth+projection[3].z; #else z=projection[2].z+projection[3].z/depth; #endif #endif var w=1.0;var ndc=vec4f(xy,z,w);var eyePos: vec4f=invProjectionMatrix*ndc;var result=eyePos.xyz/eyePos.w;return result;} `; // Sideeffect if (!ShaderStore.IncludesShadersStoreWGSL[name]) { ShaderStore.IncludesShadersStoreWGSL[name] = shader; } /** @internal */ export const screenSpaceRayTraceWGSL = { name, shader }; //# sourceMappingURL=screenSpaceRayTrace.js.map