浏览代码

finalized sao

ncannasse 10 年之前
父节点
当前提交
bb46d393e0
共有 2 个文件被更改,包括 30 次插入6 次删除
  1. 6 5
      h3d/pass/ScalableAO.hx
  2. 24 1
      samples/sao/Main.hx

+ 6 - 5
h3d/pass/ScalableAO.hx

@@ -19,11 +19,11 @@ private class SAOShader extends h3d.shader.ScreenShader {
 		@param var cameraInverseViewProj : Mat4;
 
 		@param var screenRatio : Vec2;
+		@param var fovTan : Float;
 
 		function sampleAO(uv : Vec2, position : Vec3, normal : Vec3, radiusSS : Float, tapIndex : Int, rotationAngle : Float) : Float {
 			// returns a unit vector and a screen-space radius for the tap on a unit disk
 			// (the caller should scale by the actual disk radius)
-			// radius relative to radiusSS
 			var alpha = (float(tapIndex) + 0.5) * (1.0 / float(numSamples));
 			var angle = alpha * (float(numSpiralTurns) * 6.28) + rotationAngle;
 
@@ -33,7 +33,7 @@ private class SAOShader extends h3d.shader.ScreenShader {
 			var v = Q - position;
 
 			var vv = dot(v, v);
-			var vn = dot(v, normal) - (bias / sampleRadius);
+			var vn = dot(v, normal) - (bias * sampleRadius);
 
 			// Smoother transition to zero (lowers contrast, smoothing out corners). [Recommended]
 			var radius2 = sampleRadius * sampleRadius;
@@ -60,13 +60,13 @@ private class SAOShader extends h3d.shader.ScreenShader {
 			var sampleNoise = noiseTexture.get(vUV * noiseScale / screenRatio).x;
 			var randomPatternRotationAngle = 2.0 * PI * sampleNoise;
 
-			// is it correct enough to go from WS to DepthUV space ?
-			var radiusSS = sampleRadius * 0.5 / (origin * cameraView).z;
+			// change from WS to DepthUV space
+			var radiusSS = (sampleRadius * fovTan) / (origin * cameraView).z;
 
 			for( i in 0...numSamples )
 				occlusion += sampleAO(vUV, origin, normal, radiusSS, i, randomPatternRotationAngle);
 
-			occlusion = 1.0 - occlusion / (5.0 * float(numSamples));
+			occlusion = 1.0 - occlusion / float(numSamples);
 			occlusion = clamp(pow(occlusion, 1.0 + intensity), 0.0, 1.0);
 
 			output.color = vec4(occlusion.xxx, 1.);
@@ -111,6 +111,7 @@ class ScalableAO extends h3d.pass.ScreenFx<SAOShader> {
 		shader.cameraView = camera.mcam;
 		shader.cameraInverseViewProj = camera.getInverseViewProj();
 		shader.screenRatio.set(engine.height / engine.width, 1);
+		shader.fovTan = 1.0 / (2.0 * Math.tan(camera.fovY * (Math.PI / 180) * 0.5));
 		render();
 	}
 

+ 24 - 1
samples/sao/Main.hx

@@ -4,7 +4,7 @@ import hxd.Key in K;
 
 class CustomRenderer extends h3d.scene.Renderer {
 
-	var sao : h3d.pass.ScalableAO;
+	public var sao : h3d.pass.ScalableAO;
 	public var saoBlur : h3d.pass.Blur;
 	var out : h3d.mat.Texture;
 	public var mode = 0;
@@ -14,6 +14,7 @@ class CustomRenderer extends h3d.scene.Renderer {
 		sao = new h3d.pass.ScalableAO();
 		// TODO : use a special Blur that prevents bluring across depths
 		saoBlur = new h3d.pass.Blur(2, 3, 2);
+		sao.shader.sampleRadius	= 0.2;
 	}
 
 	override function process( ctx, passes ) {
@@ -103,6 +104,28 @@ class Main extends hxd.App {
 		if(K.isPressed("B".code))
 			r.saoBlur.passes = r.saoBlur.passes == 0 ? 3 : 0;
 
+		if( K.isDown(K.CTRL) && K.isDown(K.SHIFT) ) {
+			if(K.isDown(K.NUMPAD_ADD))
+				r.sao.shader.bias *= 1.02;
+			if(K.isDown(K.NUMPAD_SUB))
+				r.sao.shader.bias /= 1.02;
+		} else if( K.isDown(K.SHIFT) ) {
+			if(K.isDown(K.NUMPAD_ADD))
+				s3d.camera.fovY *= 1.02;
+			if(K.isDown(K.NUMPAD_SUB))
+				s3d.camera.fovY /= 1.02;
+		} else if( K.isDown(K.CTRL) ) {
+			if(K.isDown(K.NUMPAD_ADD))
+				r.sao.shader.intensity *= 1.02;
+			if(K.isDown(K.NUMPAD_SUB))
+				r.sao.shader.intensity /= 1.02;
+		} else {
+			if(K.isDown(K.NUMPAD_ADD))
+				r.sao.shader.sampleRadius *= 1.02;
+			if(K.isDown(K.NUMPAD_SUB))
+				r.sao.shader.sampleRadius /= 1.02;
+		}
+
 		if(!paused)
 			time += dt * 0.001;
 		s3d.camera.pos.set(camdist * Math.cos(time), camdist * Math.sin(time), camdist * 0.5);