Browse Source

GTAOPass: distance dependent horizon search (#27370)

Gernot Steinegger 1 year ago
parent
commit
a633443de2

+ 7 - 0
examples/jsm/postprocessing/GTAOPass.js

@@ -241,6 +241,13 @@ class GTAOPass extends Pass {
 
 		}
 
+		if ( parameters.distanceFallOff !== undefined ) {
+
+			this.gtaoMaterial.uniforms.distanceFallOff.value = parameters.distanceFallOff;
+			this.gtaoMaterial.needsUpdate = true;
+
+		}
+
 		if ( parameters.scale !== undefined ) {
 
 			this.gtaoMaterial.uniforms.scale.value = parameters.scale;

+ 5 - 3
examples/jsm/shaders/GTAOShader.js

@@ -63,6 +63,7 @@ const GTAOShader = {
 		radius: { value: 0.25 },
 		distanceExponent: { value: 1. },
 		thickness: { value: 1. },
+		distanceFallOff: { value: 1. },
 		scale: { value: 1. },
 		sceneBoxMin: { value: new Vector3( - 1, - 1, - 1 ) },
 		sceneBoxMax: { value: new Vector3( 1, 1, 1 ) },
@@ -91,6 +92,7 @@ const GTAOShader = {
 		uniform float radius;
 		uniform float distanceExponent;
 		uniform float thickness;
+		uniform float distanceFallOff;
 		uniform float scale;
 		#if SCENE_CLIP_BOX == 1
 			uniform vec3 sceneBoxMin;
@@ -224,7 +226,7 @@ const GTAOShader = {
 					vec3 viewDelta = sampleSceneViewPos - viewPos;
 					if (abs(viewDelta.z) < thickness) {
 						float sampleCosHorizon = dot(viewDir, normalize(viewDelta));
-						cosHorizons.x = max(cosHorizons.x, sampleCosHorizon);	
+						cosHorizons.x += max(0., (sampleCosHorizon - cosHorizons.x) * mix(1., 2. / float(j + 2), distanceFallOff));
 					}		
 
 					sampleSceneUvDepth = getSceneUvAndDepth(viewPos - sampleViewOffset);
@@ -232,7 +234,7 @@ const GTAOShader = {
 					viewDelta = sampleSceneViewPos - viewPos;
 					if (abs(viewDelta.z) < thickness) {
 						float sampleCosHorizon = dot(viewDir, normalize(viewDelta));
-						cosHorizons.y = max(cosHorizons.y, sampleCosHorizon);	
+						cosHorizons.y += max(0., (sampleCosHorizon - cosHorizons.y) * mix(1., 2. / float(j + 2), distanceFallOff));
 					}
 				}
 
@@ -353,7 +355,7 @@ function generateMagicSquareNoise( size = 5 ) {
 		data[ inx * 4 ] = ( randomVec.x * 0.5 + 0.5 ) * 255;
 		data[ inx * 4 + 1 ] = ( randomVec.y * 0.5 + 0.5 ) * 255;
 		data[ inx * 4 + 2 ] = 127;
-		data[ inx * 4 + 3 ] = 0;
+		data[ inx * 4 + 3 ] = 255;
 
 	}
 

BIN
examples/screenshots/webgl_postprocessing_gtao.jpg


+ 2 - 4
examples/webgl_postprocessing_gtao.html

@@ -137,10 +137,7 @@
 					thickness: 1.,
 					scale: 1.,
 					samples: 16,
-					distanceFallOff: true,
-					clipRangeCheck: true,
-					depthRelativeBias: false,
-					nvAlignedSamples: false,
+					distanceFallOff: 1.,
 					screenSpaceRadius: false,
 				};
 				const pdParameters = {
@@ -158,6 +155,7 @@
 				gui.add( aoParameters, 'radius' ).min( 0.01 ).max( 1 ).step( 0.01 ).onChange( () => gtaoPass.updateGtaoMaterial( aoParameters ) );
 				gui.add( aoParameters, 'distanceExponent' ).min( 1 ).max( 4 ).step( 0.01 ).onChange( () => gtaoPass.updateGtaoMaterial( aoParameters ) );
 				gui.add( aoParameters, 'thickness' ).min( 0.01 ).max( 10 ).step( 0.01 ).onChange( () => gtaoPass.updateGtaoMaterial( aoParameters ) );
+				gui.add( aoParameters, 'distanceFallOff' ).min( 0 ).max( 1 ).step( 0.01 ).onChange( () => gtaoPass.updateGtaoMaterial( aoParameters ) );
 				gui.add( aoParameters, 'scale' ).min( 0.01 ).max( 2.0 ).step( 0.01 ).onChange( () => gtaoPass.updateGtaoMaterial( aoParameters ) );
 				gui.add( aoParameters, 'samples' ).min( 2 ).max( 32 ).step( 1 ).onChange( () => gtaoPass.updateGtaoMaterial( aoParameters ) );
 				gui.add( aoParameters, 'screenSpaceRadius' ).onChange( () => gtaoPass.updateGtaoMaterial( aoParameters ) );