|
@@ -117,14 +117,6 @@ class GTAONode extends TempNode {
|
|
|
*/
|
|
*/
|
|
|
this.radius = uniform( 0.25 );
|
|
this.radius = uniform( 0.25 );
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * The resolution of the effect. Can be scaled via
|
|
|
|
|
- * `resolutionScale`.
|
|
|
|
|
- *
|
|
|
|
|
- * @type {UniformNode<vec2>}
|
|
|
|
|
- */
|
|
|
|
|
- this.resolution = uniform( new Vector2() );
|
|
|
|
|
-
|
|
|
|
|
/**
|
|
/**
|
|
|
* The thickness of the ambient occlusion.
|
|
* The thickness of the ambient occlusion.
|
|
|
*
|
|
*
|
|
@@ -178,6 +170,14 @@ class GTAONode extends TempNode {
|
|
|
*/
|
|
*/
|
|
|
this.useTemporalFiltering = false;
|
|
this.useTemporalFiltering = false;
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * The resolution of the effect. Can be scaled via `resolutionScale`.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @private
|
|
|
|
|
+ * @type {UniformNode<vec2>}
|
|
|
|
|
+ */
|
|
|
|
|
+ this._resolution = uniform( new Vector2() );
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* The node represents the internal noise texture used by the AO.
|
|
* The node represents the internal noise texture used by the AO.
|
|
|
*
|
|
*
|
|
@@ -234,6 +234,13 @@ class GTAONode extends TempNode {
|
|
|
*/
|
|
*/
|
|
|
this._temporalOffset = uniform( 0 );
|
|
this._temporalOffset = uniform( 0 );
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Resolution scale uniform.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @private
|
|
|
|
|
+ * @type {UniformNode<float>}
|
|
|
|
|
+ */
|
|
|
|
|
+ this._resolutionScale = uniform( 0 );
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* The material that is used to render the effect.
|
|
* The material that is used to render the effect.
|
|
@@ -276,7 +283,8 @@ class GTAONode extends TempNode {
|
|
|
width = Math.round( this.resolutionScale * width );
|
|
width = Math.round( this.resolutionScale * width );
|
|
|
height = Math.round( this.resolutionScale * height );
|
|
height = Math.round( this.resolutionScale * height );
|
|
|
|
|
|
|
|
- this.resolution.value.set( width, height );
|
|
|
|
|
|
|
+ this._resolutionScale.value = this.resolutionScale;
|
|
|
|
|
+ this._resolution.value.set( width, height );
|
|
|
this._aoRenderTarget.setSize( width, height );
|
|
this._aoRenderTarget.setSize( width, height );
|
|
|
|
|
|
|
|
}
|
|
}
|
|
@@ -341,9 +349,7 @@ class GTAONode extends TempNode {
|
|
|
|
|
|
|
|
const uvNode = uv();
|
|
const uvNode = uv();
|
|
|
|
|
|
|
|
- const sampleDepth = ( uv ) => {
|
|
|
|
|
-
|
|
|
|
|
- const depth = this.depthNode.sample( uv ).r;
|
|
|
|
|
|
|
+ const linearizeDepth = ( depth ) => {
|
|
|
|
|
|
|
|
if ( builder.renderer.logarithmicDepthBuffer === true ) {
|
|
if ( builder.renderer.logarithmicDepthBuffer === true ) {
|
|
|
|
|
|
|
@@ -357,12 +363,25 @@ class GTAONode extends TempNode {
|
|
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ const sampleDepth = ( uv ) => linearizeDepth( this.depthNode.sample( uv ).r );
|
|
|
|
|
+
|
|
|
|
|
+ const sampleCenterDepth = ( uv ) => {
|
|
|
|
|
+
|
|
|
|
|
+ // Sidestep the nearest-rounding during depth access for the unjittered center pixel to avoid banding
|
|
|
|
|
+
|
|
|
|
|
+ const g = this.depthNode.gather().sample( uv );
|
|
|
|
|
+ const depth = min( min( g.x, g.y ), min( g.z, g.w ) );
|
|
|
|
|
+
|
|
|
|
|
+ return linearizeDepth( depth );
|
|
|
|
|
+
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
const sampleNoise = ( uv ) => this._noiseNode.sample( uv );
|
|
const sampleNoise = ( uv ) => this._noiseNode.sample( uv );
|
|
|
const sampleNormal = ( uv ) => ( this.normalNode !== null ) ? this.normalNode.sample( uv ).rgb.normalize() : getNormalFromDepth( uv, this.depthNode.value, this._cameraProjectionMatrixInverse );
|
|
const sampleNormal = ( uv ) => ( this.normalNode !== null ) ? this.normalNode.sample( uv ).rgb.normalize() : getNormalFromDepth( uv, this.depthNode.value, this._cameraProjectionMatrixInverse );
|
|
|
|
|
|
|
|
const ao = Fn( () => {
|
|
const ao = Fn( () => {
|
|
|
|
|
|
|
|
- const depth = sampleDepth( uvNode ).toVar();
|
|
|
|
|
|
|
+ const depth = this._resolutionScale.lessThan( 1 ).select( sampleCenterDepth( uvNode ), sampleDepth( uvNode ) ).toConst();
|
|
|
|
|
|
|
|
depth.greaterThanEqual( 1.0 ).discard();
|
|
depth.greaterThanEqual( 1.0 ).discard();
|
|
|
|
|
|
|
@@ -375,7 +394,7 @@ class GTAONode extends TempNode {
|
|
|
|
|
|
|
|
const noiseResolution = textureSize( this._noiseNode, 0 );
|
|
const noiseResolution = textureSize( this._noiseNode, 0 );
|
|
|
let noiseUv = vec2( uvNode.x, uvNode.y.oneMinus() );
|
|
let noiseUv = vec2( uvNode.x, uvNode.y.oneMinus() );
|
|
|
- noiseUv = noiseUv.mul( this.resolution.div( noiseResolution ) );
|
|
|
|
|
|
|
+ noiseUv = noiseUv.mul( this._resolution.div( noiseResolution ) );
|
|
|
|
|
|
|
|
const noiseTexel = sampleNoise( noiseUv );
|
|
const noiseTexel = sampleNoise( noiseUv );
|
|
|
const randomVec = noiseTexel.xyz.mul( 2.0 ).sub( 1.0 );
|
|
const randomVec = noiseTexel.xyz.mul( 2.0 ).sub( 1.0 );
|