فهرست منبع

Added depth clamp in GL and DX12. Stabilized cascaded shadow map and fix sampling.

TothBenoit 1 سال پیش
والد
کامیت
55f1a1fdaa
5فایلهای تغییر یافته به همراه37 افزوده شده و 15 حذف شده
  1. 7 1
      h3d/impl/DX12Driver.hx
  2. 11 0
      h3d/impl/GlDriver.hx
  3. 1 0
      h3d/mat/Texture.hx
  4. 17 13
      h3d/pass/CascadeShadowMap.hx
  5. 1 1
      h3d/shader/CascadeShadow.hx

+ 7 - 1
h3d/impl/DX12Driver.hx

@@ -310,7 +310,8 @@ class DX12Driver extends h3d.impl.Driver {
 	static inline var PSIGN_COLOR_MASK = PSIGN_MATID + 4;
 	static inline var PSIGN_DEPTH_BIAS = PSIGN_COLOR_MASK + 4;
 	static inline var PSIGN_SLOPE_SCALED_DEPTH_BIAS = PSIGN_DEPTH_BIAS + 4;
-	static inline var PSIGN_STENCIL_MASK = PSIGN_SLOPE_SCALED_DEPTH_BIAS + 4;
+	static inline var PSIGN_DEPTH_CLIP = PSIGN_SLOPE_SCALED_DEPTH_BIAS + 4;
+	static inline var PSIGN_STENCIL_MASK = PSIGN_DEPTH_CLIP + 1;
 	static inline var PSIGN_STENCIL_OPS = PSIGN_STENCIL_MASK + 2;
 	static inline var PSIGN_RENDER_TARGETS = PSIGN_STENCIL_OPS + 4;
 	static inline var PSIGN_DEPTH_TARGET_FORMAT = PSIGN_RENDER_TARGETS + 1;
@@ -800,6 +801,7 @@ class DX12Driver extends h3d.impl.Driver {
 		pipelineSignature.setI32(PSIGN_DEPTH_TARGET_FORMAT, depthFormat.toInt());
 		pipelineSignature.setI32(PSIGN_DEPTH_BIAS, depthBufferIsNotNull ? Std.int(tex.depthBuffer.depthBias) : 0);
 		pipelineSignature.setF32(PSIGN_SLOPE_SCALED_DEPTH_BIAS, depthBufferIsNotNull ? tex.depthBuffer.slopeScaledBias : 0);
+		pipelineSignature.setUI8(PSIGN_DEPTH_CLIP, depthBufferIsNotNull ? ( tex.depthBuffer.depthClamp ? 0 : 1 ) : 1 );
 		needPipelineFlush = true;
 	}
 
@@ -858,6 +860,7 @@ class DX12Driver extends h3d.impl.Driver {
 		pipelineSignature.setI32(PSIGN_DEPTH_TARGET_FORMAT, depthFormat.toInt());
 		pipelineSignature.setI32(PSIGN_DEPTH_BIAS, depthEnabled && depthBufferIsNotNull ? Std.int(t0.depthBuffer.depthBias) : 0);
 		pipelineSignature.setF32(PSIGN_SLOPE_SCALED_DEPTH_BIAS, depthEnabled && depthBufferIsNotNull ? cast(t0.depthBuffer.slopeScaledBias) : 0);
+		pipelineSignature.setUI8(PSIGN_DEPTH_CLIP, depthEnabled && depthBufferIsNotNull ? ( t0.depthBuffer.depthClamp ? 0 : 1 ) : 1 );
 
 		needPipelineFlush = true;
 	}
@@ -877,6 +880,7 @@ class DX12Driver extends h3d.impl.Driver {
 		pipelineSignature.setI32(PSIGN_DEPTH_TARGET_FORMAT, depthFormat.toInt());
 		pipelineSignature.setI32(PSIGN_DEPTH_BIAS, ( depthEnabled && (depthBuffer != null) ) ? Std.int(depthBuffer.depthBias) : 0);
 		pipelineSignature.setF32(PSIGN_SLOPE_SCALED_DEPTH_BIAS, ( depthEnabled && (depthBuffer != null) ) ? depthBuffer.slopeScaledBias : 0);
+		pipelineSignature.setUI8(PSIGN_DEPTH_CLIP, ( depthEnabled && (depthBuffer != null) ) ? ( depthBuffer.depthClamp ? 0 : 1 ) : 1 );
 		needPipelineFlush = true;
 	}
 
@@ -2110,6 +2114,7 @@ class DX12Driver extends h3d.impl.Driver {
 		var colorMask = pipelineSignature.getUI8(PSIGN_COLOR_MASK);
 		var depthBias = pipelineSignature.getI32(PSIGN_DEPTH_BIAS);
 		var slopeScaledDepthBias = pipelineSignature.getF32(PSIGN_SLOPE_SCALED_DEPTH_BIAS);
+		var depthClip = pipelineSignature.getUI8(PSIGN_DEPTH_CLIP) > 0;
 		var stencilMask = pipelineSignature.getUI16(PSIGN_STENCIL_MASK);
 		var stencilOp = pipelineSignature.getI32(PSIGN_STENCIL_OPS);
 
@@ -2133,6 +2138,7 @@ class DX12Driver extends h3d.impl.Driver {
 		p.rasterizerState.fillMode = wire == 0 ? SOLID : WIREFRAME;
 		p.rasterizerState.depthBias = depthBias;
 		p.rasterizerState.slopeScaledDepthBias = slopeScaledDepthBias;
+		p.rasterizerState.depthClipEnable = depthClip;
 		p.depthStencilDesc.depthEnable = cmp != 0;
 		p.depthStencilDesc.depthWriteMask = dw == 0 || !depthEnabled ? ZERO : ALL;
 		p.depthStencilDesc.depthFunc = COMP[cmp];

+ 11 - 0
h3d/impl/GlDriver.hx

@@ -1707,6 +1707,7 @@ class GlDriver extends Driver {
 			gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, tex.flags.has(Cube) ? CUBE_FACES[layer] : GL.TEXTURE_2D, tex.t.t, mipLevel);
 
 		setPolygonOffset( tex.depthBuffer );
+		setDepthClamp( tex.depthBuffer );
 
 		if( tex.depthBuffer != null && depthBinding != NotBound ) {
 			// Depthbuffer and stencilbuffer are combined in one buffer, created with GL.DEPTH_STENCIL
@@ -1786,6 +1787,7 @@ class GlDriver extends Driver {
 		gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.TEXTURE_2D, null, 0);
 
 		setPolygonOffset( depthBuffer );
+		setDepthClamp( depthBuffer );
 
 		if(depthBuffer.hasStencil() && depthBuffer.format == Depth24Stencil8) {
 			gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.TEXTURE_2D,@:privateAccess depthBuffer.t.t, 0);
@@ -1824,6 +1826,15 @@ class GlDriver extends Driver {
 			gl.disable(GL.POLYGON_OFFSET_FILL);
 	}
 
+	function setDepthClamp( dephTexture : h3d.mat.Texture ) {
+		#if !js
+		if ( dephTexture != null && dephTexture.depthClamp )
+			gl.enable(GL.DEPTH_CLAMP);
+		else
+			gl.disable(GL.DEPTH_CLAMP);
+		#end
+	}
+
 	override function init( onCreate : Bool -> Void, forceSoftware = false ) {
 		#if js
 		// wait until all assets have properly load

+ 1 - 0
h3d/mat/Texture.hx

@@ -44,6 +44,7 @@ class Texture {
 	public var mipLevels(get, never) : Int;
 	public var depthBias : Float = 0.;
 	public var slopeScaledBias : Float = 0.;
+	public var depthClamp : Bool = false;
 	var customMipLevels : Int;
 
 	/**

+ 17 - 13
h3d/pass/CascadeShadowMap.hx

@@ -74,26 +74,28 @@ class CascadeShadowMap extends DirShadowMap {
 			var cascadeBounds = lightCameras[i].orthoBounds;
 			cascadeBounds.empty();
 
-			inline function addCorner(x : Float, y : Float, d : Float, i : Int) {
-				var pt = tmpCorners[i];
+			inline function computeCorner(x : Float, y : Float, d : Float, pt : h3d.Vector) {
 				pt.set( x * (d * sInvG), y * ( d * invG ), d );
-				pt.transform( invCamera );
-				pt.transform( lightCamera.mcam );
-				cascadeBounds.addPos(pt.x, pt.y, pt.z);
 			}
-			inline function addCorners(d, i) {
-				addCorner(-1.0, -1.0, d, i);
-				addCorner(-1.0,  1.0, d, i + 1);
-				addCorner( 1.0, -1.0, d, i + 2);
-				addCorner( 1.0,  1.0, d, i + 3);
+			inline function computeCorners(d, i) {
+				computeCorner(-1.0, -1.0, d, tmpCorners[i]);
+				computeCorner(-1.0,  1.0, d, tmpCorners[i + 1]);
+				computeCorner( 1.0, -1.0, d, tmpCorners[i + 2]);
+				computeCorner( 1.0,  1.0, d, tmpCorners[i + 3]);
 			}
 
 			var nearFar = computeNearFar(i);
-			addCorners(nearFar.near, 0);
-			addCorners(nearFar.far, 4);
-			cascadeBounds.zMin = cascadeBounds.zMax - maxDist;
+			computeCorners(nearFar.near, 0);
+			computeCorners(nearFar.far, 4);
 
 			var d = hxd.Math.ceil( hxd.Math.max( tmpCorners[0].distance(tmpCorners[7]), tmpCorners[4].distance(tmpCorners[7]) ) );
+
+			for ( pt in tmpCorners ) {
+				pt.transform( invCamera );
+				pt.transform( lightCamera.mcam );
+				cascadeBounds.addPos(pt.x, pt.y, pt.z);
+			}
+
 			var t = d / size;
 			var t2 = t * 2.0;
 			var lightPos = new h3d.Vector(
@@ -225,6 +227,7 @@ class CascadeShadowMap extends DirShadowMap {
 			var param = params[cascade - 1 - i];
 			texture.depthBias = (param != null) ? param.depthBias : 0;
 			texture.slopeScaledBias = (param != null) ? param.slopeBias : 0;
+			texture.depthClamp = true;
 
 			var lc = lightCameras[i];
 			var dimension = Math.max(lc.orthoBounds.xMax - lc.orthoBounds.xMin,	lc.orthoBounds.yMax - lc.orthoBounds.yMin);
@@ -234,6 +237,7 @@ class CascadeShadowMap extends DirShadowMap {
 				dimension = 0.0;
 			var p = passes.save();
 			tmpFrustum.loadMatrix(lc.viewProj);
+			tmpFrustum.checkNearFar = false;
 			if ( dimension > 0.0 )
 				cullPassesSize(passes, tmpFrustum, dimension);
 			else

+ 1 - 1
h3d/shader/CascadeShadow.hx

@@ -13,7 +13,7 @@ class CascadeShadow extends DirShadow {
 		@param var cascadeDebugs : Array<Vec4, CASCADE_COUNT>;
 
 		function inside(pos : Vec3) : Bool {
-			if ( abs(pos.x) < 1.0 && abs(pos.y) < 1.0 && abs(pos.z) < 1.0 ) {
+			if ( abs(pos.x) < 1.0 && abs(pos.y) < 1.0 && ( pos.z < 1.0 && pos.z > 0.0 ) ) {
 				return true;
 			} else {
 				return false;