|
|
@@ -1,5 +1,5 @@
|
|
|
import { DataTexture, RepeatWrapping, Vector2, Vector3, TempNode } from 'three/webgpu';
|
|
|
-import { texture, getNormalFromDepth, getViewPosition, convertToTexture, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, luminance, vec2, vec3, vec4, uniformArray, int, dot, max, pow, abs, If, textureSize, sin, cos, mat2, PI } from 'three/tsl';
|
|
|
+import { texture, getNormalFromDepth, getViewPosition, convertToTexture, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, luminance, vec2, vec3, vec4, uniformArray, int, dot, max, pow, abs, If, textureSize, sin, cos, mat2, PI, property } from 'three/tsl';
|
|
|
import { SimplexNoise } from '../../math/SimplexNoise.js';
|
|
|
|
|
|
/**
|
|
|
@@ -187,59 +187,58 @@ class DenoiseNode extends TempNode {
|
|
|
const viewNormal = sampleNormal( uvNode ).toVar();
|
|
|
|
|
|
const texel = sampleTexture( uvNode ).toVar();
|
|
|
+ const result = property( 'vec4' );
|
|
|
|
|
|
If( depth.greaterThanEqual( 1.0 ).or( dot( viewNormal, viewNormal ).equal( 0.0 ) ), () => {
|
|
|
|
|
|
- return texel;
|
|
|
+ result.assign( texel );
|
|
|
|
|
|
- } );
|
|
|
+ } ).Else( () => {
|
|
|
|
|
|
- const center = vec3( texel.rgb ).toVar();
|
|
|
+ const center = vec3( texel.rgb );
|
|
|
|
|
|
- const viewPosition = getViewPosition( uvNode, depth, this._cameraProjectionMatrixInverse ).toVar();
|
|
|
+ const viewPosition = getViewPosition( uvNode, depth, this._cameraProjectionMatrixInverse ).toConst();
|
|
|
|
|
|
- const noiseResolution = textureSize( this.noiseNode, 0 );
|
|
|
- let noiseUv = vec2( uvNode.x, uvNode.y.oneMinus() );
|
|
|
- noiseUv = noiseUv.mul( this._resolution.div( noiseResolution ) );
|
|
|
- const noiseTexel = sampleNoise( noiseUv ).toVar();
|
|
|
+ const noiseResolution = textureSize( this.noiseNode, 0 );
|
|
|
+ let noiseUv = vec2( uvNode.x, uvNode.y.oneMinus() );
|
|
|
+ noiseUv = noiseUv.mul( this._resolution.div( noiseResolution ) );
|
|
|
+ const noiseTexel = sampleNoise( noiseUv ).toVar();
|
|
|
|
|
|
- const x = sin( noiseTexel.element( this.index.mod( 4 ).mul( 2 ).mul( PI ) ) ).toVar();
|
|
|
- const y = cos( noiseTexel.element( this.index.mod( 4 ).mul( 2 ).mul( PI ) ) ).toVar();
|
|
|
+ const x = sin( noiseTexel.element( this.index.mod( 4 ).mul( 2 ).mul( PI ) ) );
|
|
|
+ const y = cos( noiseTexel.element( this.index.mod( 4 ).mul( 2 ).mul( PI ) ) );
|
|
|
|
|
|
- const noiseVec = vec2( x, y ).toVar();
|
|
|
- const rotationMatrix = mat2( noiseVec.x, noiseVec.y.negate(), noiseVec.x, noiseVec.y ).toVar();
|
|
|
+ const noiseVec = vec2( x, y );
|
|
|
+ const rotationMatrix = mat2( noiseVec.x, noiseVec.y.negate(), noiseVec.x, noiseVec.y );
|
|
|
|
|
|
- const totalWeight = float( 1.0 ).toVar();
|
|
|
- const denoised = vec3( texel.rgb ).toVar();
|
|
|
+ const totalWeight = float( 1.0 ).toVar();
|
|
|
+ const denoised = vec3( texel.rgb ).toVar();
|
|
|
|
|
|
- Loop( { start: int( 0 ), end: int( 16 ), type: 'int', condition: '<' }, ( { i } ) => {
|
|
|
+ Loop( { start: int( 0 ), end: int( 16 ), type: 'int', condition: '<' }, ( { i } ) => {
|
|
|
|
|
|
- const sampleDir = this._sampleVectors.element( i ).toVar();
|
|
|
- const offset = rotationMatrix.mul( sampleDir.xy.mul( float( 1.0 ).add( sampleDir.z.mul( this.radius.sub( 1 ) ) ) ) ).div( this._resolution ).toVar();
|
|
|
- const sampleUv = uvNode.add( offset ).toVar();
|
|
|
+ const sampleDir = this._sampleVectors.element( i );
|
|
|
+ const offset = rotationMatrix.mul( sampleDir.xy.mul( float( 1.0 ).add( sampleDir.z.mul( this.radius.sub( 1 ) ) ) ) ).div( this._resolution );
|
|
|
+ const sampleUv = uvNode.add( offset );
|
|
|
|
|
|
- const result = denoiseSample( center, viewNormal, viewPosition, sampleUv );
|
|
|
+ const sampleResult = denoiseSample( center, viewNormal, viewPosition, sampleUv );
|
|
|
|
|
|
- denoised.addAssign( result.xyz );
|
|
|
- totalWeight.addAssign( result.w );
|
|
|
+ denoised.addAssign( sampleResult.xyz );
|
|
|
+ totalWeight.addAssign( sampleResult.w );
|
|
|
|
|
|
- } );
|
|
|
+ } );
|
|
|
+
|
|
|
+ If( totalWeight.greaterThan( float( 0 ) ), () => {
|
|
|
|
|
|
- If( totalWeight.greaterThan( float( 0 ) ), () => {
|
|
|
+ denoised.divAssign( totalWeight );
|
|
|
|
|
|
- denoised.divAssign( totalWeight );
|
|
|
+ } );
|
|
|
+
|
|
|
+ result.assign( vec4( denoised, texel.a ) );
|
|
|
|
|
|
} );
|
|
|
|
|
|
- return vec4( denoised, texel.a );
|
|
|
+ return result;
|
|
|
|
|
|
- } ).setLayout( {
|
|
|
- name: 'denoise',
|
|
|
- type: 'vec4',
|
|
|
- inputs: [
|
|
|
- { name: 'uv', type: 'vec2' }
|
|
|
- ]
|
|
|
- } );
|
|
|
+ }/*, { uv: 'vec2', return: 'vec4' }*/ );
|
|
|
|
|
|
const output = Fn( () => {
|
|
|
|