|
|
@@ -1,5 +1,5 @@
|
|
|
import { HalfFloatType, RenderTarget, Vector2, RendererUtils, QuadMesh, TempNode, NodeMaterial, NodeUpdateType, LinearFilter, LinearMipmapLinearFilter } from 'three/webgpu';
|
|
|
-import { texture, reference, viewZToPerspectiveDepth, logarithmicDepthToViewZ, getScreenPosition, getViewPosition, sqrt, mul, div, cross, float, Continue, Break, Loop, int, max, abs, sub, If, dot, reflect, normalize, screenCoordinate, nodeObject, Fn, passTexture, uv, uniform, perspectiveDepthToViewZ, orthographicDepthToViewZ, vec2, vec3, vec4 } from 'three/tsl';
|
|
|
+import { texture, reference, viewZToPerspectiveDepth, logarithmicDepthToViewZ, getScreenPosition, getViewPosition, mul, div, cross, float, Break, Loop, int, max, abs, sub, If, dot, reflect, normalize, screenCoordinate, nodeObject, Fn, passTexture, uv, uniform, perspectiveDepthToViewZ, orthographicDepthToViewZ, vec2, vec3, vec4 } from 'three/tsl';
|
|
|
import { boxBlur } from './boxBlur.js';
|
|
|
|
|
|
const _quadMesh = /*@__PURE__*/ new QuadMesh();
|
|
|
@@ -400,9 +400,7 @@ class SSRNode extends TempNode {
|
|
|
// http://paulbourke.net/geometry/pointlineplane/
|
|
|
|
|
|
const d = mul( planeNormal.x, planePoint.x ).add( mul( planeNormal.y, planePoint.y ) ).add( mul( planeNormal.z, planePoint.z ) ).negate().toVar();
|
|
|
-
|
|
|
- const denominator = sqrt( mul( planeNormal.x, planeNormal.x, ).add( mul( planeNormal.y, planeNormal.y ) ).add( mul( planeNormal.z, planeNormal.z ) ) ).toVar();
|
|
|
- const distance = div( mul( planeNormal.x, point.x ).add( mul( planeNormal.y, point.y ) ).add( mul( planeNormal.z, point.z ) ).add( d ), denominator );
|
|
|
+ const distance = mul( planeNormal.x, point.x ).add( mul( planeNormal.y, point.y ) ).add( mul( planeNormal.z, point.z ) ).add( d );
|
|
|
return distance;
|
|
|
|
|
|
} );
|
|
|
@@ -481,9 +479,6 @@ class SSRNode extends TempNode {
|
|
|
|
|
|
// below variables are used to control the raymarching process
|
|
|
|
|
|
- // total length of the ray
|
|
|
- const totalLen = d1.sub( d0 ).length().toVar();
|
|
|
-
|
|
|
// offset in x and y direction
|
|
|
const xLen = d1.x.sub( d0.x ).toVar();
|
|
|
const yLen = d1.y.sub( d0.y ).toVar();
|
|
|
@@ -491,7 +486,9 @@ class SSRNode extends TempNode {
|
|
|
// determine the larger delta
|
|
|
// The larger difference will help to determine how much to travel in the X and Y direction each iteration and
|
|
|
// how many iterations are needed to travel the entire ray
|
|
|
- const totalStep = int( max( abs( xLen ), abs( yLen ) ).mul( this.quality.clamp() ) ).toConst();
|
|
|
+ // scale step count by distance - distant surfaces need less precision (0.5 to 1.0 multiplier)
|
|
|
+ const distanceFactor = float( 1 ).sub( depth.mul( 0.5 ) ).clamp( 0.5, 1 );
|
|
|
+ const totalStep = int( max( abs( xLen ), abs( yLen ) ).mul( this.quality.clamp() ).mul( distanceFactor ) ).toConst();
|
|
|
|
|
|
// step sizes in the x and y directions
|
|
|
const xSpan = xLen.div( totalStep ).toVar();
|
|
|
@@ -499,10 +496,14 @@ class SSRNode extends TempNode {
|
|
|
|
|
|
const output = vec4( 0 ).toVar();
|
|
|
|
|
|
+ // incremental interpolation factor
|
|
|
+ const sStep = float( 1 ).div( float( totalStep ) );
|
|
|
+ const s = sStep.toVar(); // start at sStep since loop starts at i=1
|
|
|
+
|
|
|
// the actual ray marching loop
|
|
|
// starting from d0, the code gradually travels along the ray and looks for an intersection with the geometry.
|
|
|
// it does not exceed d1 (the maximum ray extend)
|
|
|
- Loop( totalStep, ( { i } ) => {
|
|
|
+ Loop( { start: int( 1 ), end: totalStep }, ( { i } ) => {
|
|
|
|
|
|
// advance on the ray by computing a new position in screen coordinates
|
|
|
const xy = vec2( d0.x.add( xSpan.mul( float( i ) ) ), d0.y.add( ySpan.mul( float( i ) ) ) ).toVar();
|
|
|
@@ -521,9 +522,6 @@ class SSRNode extends TempNode {
|
|
|
|
|
|
const viewReflectRayZ = float( 0 ).toVar();
|
|
|
|
|
|
- // normalized distance between the current position xy and the starting point d0
|
|
|
- const s = xy.sub( d0 ).length().div( totalLen );
|
|
|
-
|
|
|
// depending on the camera type, we now compute the z-coordinate of the reflected ray at the current step in view space
|
|
|
If( this._isPerspectiveCamera, () => {
|
|
|
|
|
|
@@ -559,9 +557,9 @@ class SSRNode extends TempNode {
|
|
|
|
|
|
If( dot( viewReflectDir, vN ).greaterThanEqual( 0 ), () => {
|
|
|
|
|
|
- // the reflected ray is pointing towards the same side as the fragment's normal (current ray position),
|
|
|
- // which means it wouldn't reflect off the surface. The loop continues to the next step for the next ray sample.
|
|
|
- Continue();
|
|
|
+ // the reflected ray is hitting a backface (normal pointing away from ray),
|
|
|
+ // treat as opaque surface that blocks the ray
|
|
|
+ Break();
|
|
|
|
|
|
} );
|
|
|
|
|
|
@@ -596,6 +594,9 @@ class SSRNode extends TempNode {
|
|
|
|
|
|
} );
|
|
|
|
|
|
+ // advance interpolation factor
|
|
|
+ s.addAssign( sStep );
|
|
|
+
|
|
|
} );
|
|
|
|
|
|
return output;
|