screenSpaceRayTrace.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Do not edit.
  2. import { ShaderStore } from "../../Engines/shaderStore.js";
  3. const name = "screenSpaceRayTrace";
  4. const shader = `float distanceSquared(vec2 a,vec2 b) { a-=b; return dot(a,a); }
  5. /**
  6. \param csOrigin Camera-space ray origin,which must be
  7. within the view volume and must have z>0.01 and project within the valid screen rectangle
  8. \param csDirection Unit length camera-space ray direction
  9. \param projectToPixelMatrix A projection matrix that maps to **pixel** coordinates
  10. (**not** [-1,+1] normalized device coordinates).
  11. \param csZBuffer The camera-space Z buffer
  12. \param csZBufferSize Dimensions of csZBuffer
  13. \param csZThickness Camera space csZThickness to ascribe to each pixel in the depth buffer
  14. \param nearPlaneZ Positive number. Doesn't have to be THE actual near plane,just a reasonable value
  15. for clipping rays headed towards the camera
  16. \param stride Step in horizontal or vertical pixels between samples. This is a float
  17. because integer math is slow on GPUs,but should be set to an integer>=1
  18. \param jitterFraction Number between 0 and 1 for how far to bump the ray in stride units
  19. to conceal banding artifacts,plus the stride ray offset.
  20. \param maxSteps Maximum number of iterations. Higher gives better images but may be slow
  21. \param maxRayTraceDistance Maximum camera-space distance to trace before returning a miss
  22. \param selfCollisionNumSkip Number of steps to skip at start when raytracing to avoid self collisions.
  23. 1 is a reasonable value,depending on the scene you may need to set this value to 2
  24. \param hitPixel Pixel coordinates of the first intersection with the scene
  25. \param numIterations number of iterations performed
  26. \param csHitPoint Camera space location of the ray hit
  27. */
  28. #define inline
  29. bool traceScreenSpaceRay1(
  30. vec3 csOrigin,
  31. vec3 csDirection,
  32. mat4 projectToPixelMatrix,
  33. sampler2D csZBuffer,
  34. vec2 csZBufferSize,
  35. #ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER
  36. sampler2D csZBackBuffer,
  37. float csZBackSizeFactor,
  38. #endif
  39. float csZThickness,
  40. float nearPlaneZ,
  41. float stride,
  42. float jitterFraction,
  43. float maxSteps,
  44. float maxRayTraceDistance,
  45. float selfCollisionNumSkip,
  46. out vec2 startPixel,
  47. out vec2 hitPixel,
  48. out vec3 csHitPoint,
  49. out float numIterations
  50. #ifdef SSRAYTRACE_DEBUG
  51. ,out vec3 debugColor
  52. #endif
  53. )
  54. {
  55. #ifdef SSRAYTRACE_RIGHT_HANDED_SCENE
  56. float rayLength=(csOrigin.z+csDirection.z*maxRayTraceDistance)>-nearPlaneZ ? (-nearPlaneZ-csOrigin.z)/csDirection.z : maxRayTraceDistance;
  57. #else
  58. float rayLength=(csOrigin.z+csDirection.z*maxRayTraceDistance)<nearPlaneZ ? (nearPlaneZ-csOrigin.z)/csDirection.z : maxRayTraceDistance;
  59. #endif
  60. vec3 csEndPoint=csOrigin+csDirection*rayLength;hitPixel=vec2(-1.0,-1.0);vec4 H0=projectToPixelMatrix*vec4(csOrigin,1.0);vec4 H1=projectToPixelMatrix*vec4(csEndPoint,1.0);float k0=1.0/H0.w;float k1=1.0/H1.w;vec3 Q0=csOrigin*k0;vec3 Q1=csEndPoint*k1;vec2 P0=H0.xy*k0;vec2 P1=H1.xy*k1;
  61. #ifdef SSRAYTRACE_CLIP_TO_FRUSTUM
  62. float xMax=csZBufferSize.x-0.5,xMin=0.5,yMax=csZBufferSize.y-0.5,yMin=0.5;float alpha=0.0;if ((P1.y>yMax) || (P1.y<yMin)) {alpha=(P1.y-((P1.y>yMax) ? yMax : yMin))/(P1.y-P0.y);}
  63. if ((P1.x>xMax) || (P1.x<xMin)) {alpha=max(alpha,(P1.x-((P1.x>xMax) ? xMax : xMin))/(P1.x-P0.x));}
  64. P1=mix(P1,P0,alpha); k1=mix(k1,k0,alpha); Q1=mix(Q1,Q0,alpha);
  65. #endif
  66. P1+=vec2((distanceSquared(P0,P1)<0.0001) ? 0.01 : 0.0);vec2 delta=P1-P0;bool permute=false;if (abs(delta.x)<abs(delta.y)) {
  67. permute=true;delta=delta.yx;P0=P0.yx;P1=P1.yx; }
  68. float stepDirection=sign(delta.x);float invdx=stepDirection/delta.x;vec2 dP=vec2(stepDirection,delta.y*invdx);vec3 dQ=(Q1-Q0)*invdx;float dk=(k1-k0)*invdx;float zMin=min(csEndPoint.z,csOrigin.z);float zMax=max(csEndPoint.z,csOrigin.z);dP*=stride; dQ*=stride; dk*=stride;P0+=dP*jitterFraction; Q0+=dQ*jitterFraction; k0+=dk*jitterFraction;vec4 pqk=vec4(P0,Q0.z,k0);vec4 dPQK=vec4(dP,dQ.z,dk);startPixel=permute ? P0.yx : P0.xy;float prevZMaxEstimate=csOrigin.z;float rayZMin=prevZMaxEstimate,rayZMax=prevZMaxEstimate;float sceneZMax=rayZMax+1e4;float end=P1.x*stepDirection;bool hit=false;float stepCount;for (stepCount=0.0;stepCount<=selfCollisionNumSkip ||
  69. (pqk.x*stepDirection)<=end &&
  70. stepCount<maxSteps &&
  71. !hit &&
  72. sceneZMax != 0.0;
  73. pqk+=dPQK,++stepCount)
  74. {hitPixel=permute ? pqk.yx : pqk.xy;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) {
  75. float t=rayZMin; rayZMin=rayZMax; rayZMax=t;}
  76. sceneZMax=texelFetch(csZBuffer,ivec2(hitPixel),0).r;
  77. #ifdef SSRAYTRACE_RIGHT_HANDED_SCENE
  78. #ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER
  79. float sceneBackZ=texelFetch(csZBackBuffer,ivec2(hitPixel/csZBackSizeFactor),0).r;hit=(rayZMax>=sceneBackZ-csZThickness) && (rayZMin<=sceneZMax);
  80. #else
  81. hit=(rayZMax>=sceneZMax-csZThickness) && (rayZMin<=sceneZMax);
  82. #endif
  83. #else
  84. #ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER
  85. float sceneBackZ=texelFetch(csZBackBuffer,ivec2(hitPixel/csZBackSizeFactor),0).r;hit=(rayZMin<=sceneBackZ+csZThickness) && (rayZMax>=sceneZMax) && (sceneZMax != 0.0);
  86. #else
  87. hit=(rayZMin<=sceneZMax+csZThickness) && (rayZMax>=sceneZMax);
  88. #endif
  89. #endif
  90. }
  91. pqk-=dPQK;stepCount-=1.0;if (((pqk.x+dPQK.x)*stepDirection)>end || (stepCount+1.0)>=maxSteps || sceneZMax==0.0) {hit=false;}
  92. #ifdef SSRAYTRACE_ENABLE_REFINEMENT
  93. if (stride>1.0 && hit) {pqk-=dPQK;stepCount-=1.0;float invStride=1.0/stride;dPQK*=invStride;float refinementStepCount=0.0;prevZMaxEstimate=pqk.z/pqk.w;rayZMax=prevZMaxEstimate;sceneZMax=rayZMax+1e7;for (;refinementStepCount<=1.0 ||
  94. (refinementStepCount<=stride*1.4) &&
  95. (rayZMax<sceneZMax) && (sceneZMax != 0.0);pqk+=dPQK,refinementStepCount+=1.0)
  96. {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=permute ? pqk.yx : pqk.xy;sceneZMax=texelFetch(csZBuffer,ivec2(hitPixel),0).r;}
  97. pqk-=dPQK;refinementStepCount-=1.0;stepCount+=refinementStepCount/stride;}
  98. #endif
  99. Q0.xy+=dQ.xy*stepCount;Q0.z=pqk.z;csHitPoint=Q0/pqk.w;numIterations=stepCount+1.0;
  100. #ifdef SSRAYTRACE_DEBUG
  101. if (((pqk.x+dPQK.x)*stepDirection)>end) {debugColor=vec3(0,0,1);} else if ((stepCount+1.0)>=maxSteps) {debugColor=vec3(1,0,0);} else if (sceneZMax==0.0) {debugColor=vec3(1,1,0);} else {debugColor=vec3(0,stepCount/maxSteps,0);}
  102. #endif
  103. return hit;}
  104. /**
  105. texCoord: in the [0,1] range
  106. depth: depth in view space (range [znear,zfar]])
  107. */
  108. vec3 computeViewPosFromUVDepth(vec2 texCoord,float depth,mat4 projection,mat4 invProjectionMatrix) {vec4 ndc;ndc.xy=texCoord*2.0-1.0;
  109. #ifdef SSRAYTRACE_RIGHT_HANDED_SCENE
  110. ndc.z=-projection[2].z-projection[3].z/depth;
  111. #else
  112. ndc.z=projection[2].z+projection[3].z/depth;
  113. #endif
  114. ndc.w=1.0;vec4 eyePos=invProjectionMatrix*ndc;eyePos.xyz/=eyePos.w;return eyePos.xyz;}
  115. `;
  116. // Sideeffect
  117. ShaderStore.IncludesShadersStore[name] = shader;
  118. /** @internal */
  119. export const screenSpaceRayTrace = { name, shader };
  120. //# sourceMappingURL=screenSpaceRayTrace.js.map