Procházet zdrojové kódy

TSL: Move Interleaved Gradient Noise into `PostProcessingUtils`. (#32074)

* TSL: Move Interleaved Gradient Noise into `PostProcessingUtils`.

* Update PostProcessingUtils.js
Michael Herzog před 2 měsíci
rodič
revize
b140fba01d

+ 2 - 16
examples/jsm/tsl/display/SSGINode.js

@@ -1,5 +1,5 @@
 import { RenderTarget, Vector2, TempNode, QuadMesh, NodeMaterial, RendererUtils, MathUtils } from 'three/webgpu';
-import { clamp, normalize, reference, nodeObject, Fn, NodeUpdateType, uniform, vec4, passTexture, uv, logarithmicDepthToViewZ, viewZToPerspectiveDepth, getViewPosition, screenCoordinate, float, sub, fract, dot, vec2, rand, vec3, Loop, mul, PI, cos, sin, uint, cross, acos, sign, pow, luminance, If, max, abs, Break, sqrt, HALF_PI, div, ceil, shiftRight, convertToTexture, bool, getNormalFromDepth } from 'three/tsl';
+import { clamp, normalize, reference, nodeObject, Fn, NodeUpdateType, uniform, vec4, passTexture, uv, logarithmicDepthToViewZ, viewZToPerspectiveDepth, getViewPosition, screenCoordinate, float, sub, fract, dot, vec2, rand, vec3, Loop, mul, PI, cos, sin, uint, cross, acos, sign, pow, luminance, If, max, abs, Break, sqrt, HALF_PI, div, ceil, shiftRight, convertToTexture, bool, getNormalFromDepth, interleavedGradientNoise } from 'three/tsl';
 
 const _quadMesh = /*@__PURE__*/ new QuadMesh();
 const _size = /*@__PURE__*/ new Vector2();
@@ -413,20 +413,6 @@ class SSGINode extends TempNode {
 			]
 		} );
 
-		// Interleaved gradient function from Jimenez 2014 http://goo.gl/eomGso
-
-		const gradientNoise = Fn( ( [ position ] ) => {
-
-			return fract( float( 52.9829189 ).mul( fract( dot( position, vec2( 0.06711056, 0.00583715 ) ) ) ) );
-
-		} ).setLayout( {
-			name: 'gradientNoise',
-			type: 'float',
-			inputs: [
-				{ name: 'position', type: 'vec2' }
-			]
-		} );
-
 		const GTAOFastAcos = Fn( ( [ value ] ) => {
 
 			const outVal = abs( value ).mul( float( - 0.156583 ) ).add( HALF_PI );
@@ -576,7 +562,7 @@ class SSGINode extends TempNode {
 			//
 
 			const noiseOffset = spatialOffsets( screenCoordinate );
-			const noiseDirection = gradientNoise( screenCoordinate );
+			const noiseDirection = interleavedGradientNoise( screenCoordinate );
 			const noiseJitterIdx = this._temporalDirection.mul( 0.02 ); // Port: Add noiseJitterIdx here for slightly better noise convergence with TRAA (see #31890 for more details)
 			const initialRayStep = fract( noiseOffset.add( this._temporalOffset ) ).add( rand( uvNode.add( noiseJitterIdx ).mul( 2 ).sub( 1 ) ) );
 

+ 2 - 16
examples/jsm/tsl/display/SSSNode.js

@@ -1,5 +1,5 @@
 import { RedFormat, RenderTarget, Vector2, RendererUtils, QuadMesh, TempNode, NodeMaterial, NodeUpdateType, UnsignedByteType } from 'three/webgpu';
-import { reference, viewZToPerspectiveDepth, logarithmicDepthToViewZ, getScreenPosition, getViewPosition, float, Break, Loop, int, max, abs, If, dot, screenCoordinate, nodeObject, Fn, passTexture, uv, uniform, perspectiveDepthToViewZ, orthographicDepthToViewZ, vec2, lightPosition, lightTargetPosition, fract, rand, mix } from 'three/tsl';
+import { reference, viewZToPerspectiveDepth, logarithmicDepthToViewZ, getScreenPosition, getViewPosition, float, Break, Loop, int, max, abs, If, interleavedGradientNoise, screenCoordinate, nodeObject, Fn, passTexture, uv, uniform, perspectiveDepthToViewZ, orthographicDepthToViewZ, vec2, lightPosition, lightTargetPosition, fract, rand, mix } from 'three/tsl';
 
 const _quadMesh = /*@__PURE__*/ new QuadMesh();
 const _size = /*@__PURE__*/ new Vector2();
@@ -371,20 +371,6 @@ class SSSNode extends TempNode {
 
 		};
 
-		// Interleaved gradient function from Jimenez 2014 http://goo.gl/eomGso
-
-		const gradientNoise = Fn( ( [ position ] ) => {
-
-			return fract( float( 52.9829189 ).mul( fract( dot( position, vec2( 0.06711056, 0.00583715 ) ) ) ) );
-
-		} ).setLayout( {
-			name: 'gradientNoise',
-			type: 'float',
-			inputs: [
-				{ name: 'position', type: 'vec2' }
-			]
-		} );
-
 		const sss = Fn( () => {
 
 			const depth = sampleDepth( uvNode ).toVar();
@@ -419,7 +405,7 @@ class SSSNode extends TempNode {
 			const ySpan = yLen.div( totalStep ).toVar();
 
 			// compute noise based ray offset
-			const noise = gradientNoise( screenCoordinate );
+			const noise = interleavedGradientNoise( screenCoordinate );
 			const offset = fract( noise.add( this._temporalOffset ) ).add( rand( uvNode.add( this._frameId ) ) ).toConst( 'offset' );
 
 			const occlusion = float( 0 ).toVar();

+ 1 - 0
src/Three.TSL.js

@@ -198,6 +198,7 @@ export const getDirection = TSL.getDirection;
 export const getDistanceAttenuation = TSL.getDistanceAttenuation;
 export const getGeometryRoughness = TSL.getGeometryRoughness;
 export const getNormalFromDepth = TSL.getNormalFromDepth;
+export const interleavedGradientNoise = TSL.interleavedGradientNoise;
 export const getParallaxCorrectNormal = TSL.getParallaxCorrectNormal;
 export const getRoughness = TSL.getRoughness;
 export const getScreenPosition = TSL.getScreenPosition;

+ 28 - 1
src/nodes/utils/PostProcessingUtils.js

@@ -1,4 +1,4 @@
-import { abs, cross, float, Fn, normalize, ivec2, sub, vec2, vec3, vec4 } from '../tsl/TSLBase.js';
+import { abs, cross, float, Fn, normalize, ivec2, sub, vec2, vec3, vec4, fract, dot } from '../tsl/TSLBase.js';
 import { textureSize } from '../accessors/TextureSizeNode.js';
 import { textureLoad } from '../accessors/TextureNode.js';
 import { WebGPUCoordinateSystem } from '../../constants.js';
@@ -93,3 +93,30 @@ export const getNormalFromDepth = /*@__PURE__*/ Fn( ( [ uv, depthTexture, projec
 	return normalize( cross( dpdx, dpdy ) );
 
 } );
+
+/**
+ * Interleaved Gradient Noise (IGN) from Jimenez 2014.
+ *
+ * IGN has "low discrepancy" resulting in evenly distributed samples. It's superior compared to
+ * default white noise, blue noise or Bayer.
+ *
+ * References:
+ * - {@link https://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare/}
+ * - {@link https://blog.demofox.org/2022/01/01/interleaved-gradient-noise-a-different-kind-of-low-discrepancy-sequence/}
+ *
+ * @tsl
+ * @function
+ * @param {Node<vec2>} position - The input position, usually screen coordinates.
+ * @return {Node<float>} The noise value.
+ */
+export const interleavedGradientNoise = Fn( ( [ position ] ) => {
+
+	return fract( float( 52.9829189 ).mul( fract( dot( position, vec2( 0.06711056, 0.00583715 ) ) ) ) );
+
+} ).setLayout( {
+	name: 'interleavedGradientNoise',
+	type: 'float',
+	inputs: [
+		{ name: 'position', type: 'vec2' }
+	]
+} );

粤ICP备19079148号