Browse Source

Depth textures: - Default CSM to Depth16 format - Added Depth32 format - Added depth bias and slope scaled bias in texture for depth texture (used in GL and DX12 only)
- Added Depth32 format
- Added depthBias and slopeScaledBias for depth texture in GL and DX12

TothBenoit 1 năm trước cách đây
mục cha
commit
61a313923a
6 tập tin đã thay đổi với 84 bổ sung17 xóa
  1. 55 12
      h3d/impl/DX12Driver.hx
  2. 15 0
      h3d/impl/GlDriver.hx
  3. 3 1
      h3d/mat/Texture.hx
  4. 8 2
      h3d/pass/CascadeShadowMap.hx
  5. 1 0
      hxd/PixelFormat.hx
  6. 2 2
      hxd/Pixels.hx

+ 55 - 12
h3d/impl/DX12Driver.hx

@@ -308,11 +308,13 @@ class DX12Driver extends h3d.impl.Driver {
 
 	static inline var PSIGN_MATID = 0;
 	static inline var PSIGN_COLOR_MASK = PSIGN_MATID + 4;
-	static inline var PSIGN_UNUSED = PSIGN_COLOR_MASK + 1;
-	static inline var PSIGN_STENCIL_MASK = PSIGN_UNUSED + 1;
+	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_STENCIL_OPS = PSIGN_STENCIL_MASK + 2;
 	static inline var PSIGN_RENDER_TARGETS = PSIGN_STENCIL_OPS + 4;
-	static inline var PSIGN_LAYOUT = PSIGN_RENDER_TARGETS + 1;
+	static inline var PSIGN_DEPTH_TARGET_FORMAT = PSIGN_RENDER_TARGETS + 1;
+	static inline var PSIGN_LAYOUT = PSIGN_DEPTH_TARGET_FORMAT + 4;
 
 	var pipelineSignature = new hl.Bytes(64);
 	var adlerOut = new hl.Bytes(4);
@@ -388,7 +390,7 @@ class DX12Driver extends h3d.impl.Driver {
 			f.allocator = new CommandAllocator(DIRECT);
 			f.commandList = new CommandList(DIRECT, f.allocator, null);
 			f.commandList.close();
-			f.shaderResourceCache = new ManagedHeapArray(CBV_SRV_UAV, 1024);
+			f.shaderResourceCache = new ManagedHeapArray(CBV_SRV_UAV, 32784);
 			f.samplerCache = new ManagedHeapArray(SAMPLER, 1024);
 			frames.push(f);
 		}
@@ -704,7 +706,7 @@ class DX12Driver extends h3d.impl.Driver {
 		viewDesc.arraySize = 1;
 		viewDesc.mipSlice = 0;
 		viewDesc.firstArraySlice = 0;
-		viewDesc.format = D24_UNORM_S8_UINT;
+		viewDesc.format = (depthBuffer == null) ? D24_UNORM_S8_UINT : toDxgiDepthFormat(depthBuffer.format);
 		viewDesc.viewDimension = TEXTURE2D;
 		if ( readOnly ) {
 			viewDesc.flags.set(READ_ONLY_DEPTH);
@@ -792,10 +794,28 @@ class DX12Driver extends h3d.impl.Driver {
 		if( w == 0 ) w = 1;
 		if( h == 0 ) h = 1;
 		initViewport(w, h);
-		pipelineSignature.setUI8(PSIGN_RENDER_TARGETS, tex == null ? 0 : getRTBits(tex) | (depthEnabled ? 0x80 : 0));
+		pipelineSignature.setUI8(PSIGN_RENDER_TARGETS, tex == null ? 0 : getRTBits(tex));
+		var depthBufferIsNotNull = tex != null && tex.depthBuffer != null;
+		var depthFormat = depthEnabled ? ( depthBufferIsNotNull ? toDxgiDepthFormat(tex.depthBuffer.format) : D24_UNORM_S8_UINT ) : dx.DxgiFormat.UNKNOWN;
+		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);
 		needPipelineFlush = true;
 	}
 
+	function toDxgiDepthFormat( format : hxd.PixelFormat ) {
+		switch( format ) {
+			case Depth16:
+				return  D16_UNORM;
+			case Depth24Stencil8, Depth24:
+				return  D24_UNORM_S8_UINT;
+			case Depth32:
+				return  D32_FLOAT;
+			default:
+				throw "Unsupported depth format "+ format;
+		}
+	}
+
 	override function setRenderTargets(textures:Array<h3d.mat.Texture>, depthBinding : h3d.Engine.DepthBinding = ReadWrite) {
 		while( currentRenderTargets.length > textures.length )
 			currentRenderTargets.pop();
@@ -832,7 +852,13 @@ class DX12Driver extends h3d.impl.Driver {
 		frame.commandList.omSetRenderTargets(textures.length, tmp.renderTargets, true, depthEnabled ? getDepthViewFromTexture(t0, depthBinding == ReadOnly) : null);
 		initViewport(t0.width, t0.height);
 
-		pipelineSignature.setUI8(PSIGN_RENDER_TARGETS, bits | (depthEnabled ? 0x80 : 0));
+		pipelineSignature.setUI8(PSIGN_RENDER_TARGETS, bits);
+		var depthBufferIsNotNull = ( t0 != null && t0.depthBuffer != null );
+		var depthFormat = depthEnabled ? ( depthBufferIsNotNull ? toDxgiDepthFormat(t0.depthBuffer.format) : D24_UNORM_S8_UINT ) : dx.DxgiFormat.UNKNOWN;
+		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);
+
 		needPipelineFlush = true;
 	}
 
@@ -846,7 +872,11 @@ class DX12Driver extends h3d.impl.Driver {
 
 		initViewport(depthBuffer.width, depthBuffer.height);
 
-		pipelineSignature.setUI8(PSIGN_RENDER_TARGETS, 0x80);
+		pipelineSignature.setUI8(PSIGN_RENDER_TARGETS, 0);
+		var depthFormat = ( depthBuffer != null ) ? toDxgiDepthFormat(depthBuffer.format) : D24_UNORM_S8_UINT;
+		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);
 		needPipelineFlush = true;
 	}
 
@@ -1515,14 +1545,14 @@ class DX12Driver extends h3d.impl.Driver {
 		desc.depthOrArraySize = 1;
 		desc.mipLevels = 1;
 		desc.sampleDesc.count = 1;
-		desc.format = R24G8_TYPELESS;
+		desc.format = toDxgiDepthFormat(b.format);
 		desc.flags.set(ALLOW_DEPTH_STENCIL);
 		#if console
 		desc.flags = new haxe.EnumFlags<ResourceFlag>( desc.flags.toInt() | 0x00800000 ); // FORCE_TEXTURE_COMPATIBILITY
 		#end
 		tmp.heap.type = DEFAULT;
 
-		tmp.clearValue.format = D24_UNORM_S8_UINT;
+		tmp.clearValue.format = desc.format;
 		tmp.clearValue.depth = 1;
 		tmp.clearValue.stencil= 0;
 		td.state = td.targetState = DEPTH_WRITE;
@@ -1723,7 +1753,16 @@ class DX12Driver extends h3d.impl.Driver {
 			var desc = srvArgs.resourceDesc;
 			desc.dimension = TEXTURE2D;
 			desc.mipLevels = -1;
-			desc.format = R24_UNORM_X8_TYPELESS;
+			switch (t.format) {
+				case Depth16:
+					desc.format = R16_UNORM;
+				case Depth24, Depth24Stencil8:
+					desc.format = R24_UNORM_X8_TYPELESS;
+				case Depth32:
+					desc.format = R32_FLOAT;
+				default:
+					throw "Unsupported depth format "+ t.format;
+			}
 			desc.mostDetailedMip = t.startingMip;
 			desc.shader4ComponentMapping = ShaderComponentMapping.DEFAULT;
 		} else {
@@ -2027,6 +2066,8 @@ class DX12Driver extends h3d.impl.Driver {
 		var p = shader.pipeline;
 		var passBits = pipelineSignature.getI32(PSIGN_MATID);
 		var colorMask = pipelineSignature.getUI8(PSIGN_COLOR_MASK);
+		var depthBias = pipelineSignature.getI32(PSIGN_DEPTH_BIAS);
+		var slopeScaledDepthBias = pipelineSignature.getF32(PSIGN_SLOPE_SCALED_DEPTH_BIAS);
 		var stencilMask = pipelineSignature.getUI16(PSIGN_STENCIL_MASK);
 		var stencilOp = pipelineSignature.getI32(PSIGN_STENCIL_OPS);
 
@@ -2048,6 +2089,8 @@ class DX12Driver extends h3d.impl.Driver {
 		p.numRenderTargets = rtCount;
 		p.rasterizerState.cullMode = CULL[cull];
 		p.rasterizerState.fillMode = wire == 0 ? SOLID : WIREFRAME;
+		p.rasterizerState.depthBias = depthBias;
+		p.rasterizerState.slopeScaledDepthBias = slopeScaledDepthBias;
 		p.depthStencilDesc.depthEnable = cmp != 0;
 		p.depthStencilDesc.depthWriteMask = dw == 0 || !depthEnabled ? ZERO : ALL;
 		p.depthStencilDesc.depthFunc = COMP[cmp];
@@ -2067,7 +2110,7 @@ class DX12Driver extends h3d.impl.Driver {
 			var t = currentRenderTargets[i];
 			p.rtvFormats[i] = t == null ? R8G8B8A8_UNORM : t.t.format;
 		}
-		p.dsvFormat = depthEnabled ? D24_UNORM_S8_UINT : UNKNOWN;
+		p.dsvFormat = cast pipelineSignature.getI32(PSIGN_DEPTH_TARGET_FORMAT);
 
 		for( i in 0...shader.inputCount ) {
 			var d = shader.inputLayout[i];

+ 15 - 0
h3d/impl/GlDriver.hx

@@ -1157,6 +1157,8 @@ class GlDriver extends Driver {
 			tt.internalFmt = GL.DEPTH24_STENCIL8;
 			tt.pixelFmt = GL.UNSIGNED_INT_24_8;
 			fmt = GL.DEPTH_STENCIL;
+		case Depth32:
+			tt.internalFmt = GL.DEPTH_COMPONENT32F;
 		default:
 			throw "Unsupported depth format "+	t.format;
 		}
@@ -1693,6 +1695,8 @@ class GlDriver extends Driver {
 		else
 			gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, tex.flags.has(Cube) ? CUBE_FACES[layer] : GL.TEXTURE_2D, tex.t.t, mipLevel);
 
+		setPolygonOffset( tex.depthBuffer );
+
 		if( tex.depthBuffer != null && depthBinding != NotBound ) {
 			// Depthbuffer and stencilbuffer are combined in one buffer, created with GL.DEPTH_STENCIL
 			if(tex.depthBuffer.hasStencil() && tex.depthBuffer.format == Depth24Stencil8) {
@@ -1770,6 +1774,8 @@ class GlDriver extends Driver {
 
 		gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.TEXTURE_2D, null, 0);
 
+		setPolygonOffset( depthBuffer );
+
 		if(depthBuffer.hasStencil() && depthBuffer.format == Depth24Stencil8) {
 			gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.TEXTURE_2D,@:privateAccess depthBuffer.t.t, 0);
 		} else {
@@ -1798,6 +1804,15 @@ class GlDriver extends Driver {
 		#end
 	}
 
+	function setPolygonOffset( depthTexture : h3d.mat.Texture ) {
+		if ( depthTexture != null && ( depthTexture.depthBias != 0 || depthTexture.slopeScaledBias != 0 ) ) {
+			gl.enable(GL.POLYGON_OFFSET_FILL);
+			gl.polygonOffset(depthTexture.slopeScaledBias, depthTexture.depthBias);
+		}
+		else
+			gl.disable(GL.POLYGON_OFFSET_FILL);
+	}
+
 	override function init( onCreate : Bool -> Void, forceSoftware = false ) {
 		#if js
 		// wait until all assets have properly load

+ 3 - 1
h3d/mat/Texture.hx

@@ -42,6 +42,8 @@ class Texture {
 	public var startingMip : Int = 0;
 	public var lodBias : Float = 0.;
 	public var mipLevels(get, never) : Int;
+	public var depthBias : Float = 0.;
+	public var slopeScaledBias : Float = 0.;
 	var customMipLevels : Int;
 
 	/**
@@ -510,7 +512,7 @@ class Texture {
 
 	public function isDepth() {
 		return switch( format ) {
-		case Depth16, Depth24, Depth24Stencil8: true;
+		case Depth16, Depth24, Depth24Stencil8, Depth32: true;
 		default: false;
 		}
 	}

+ 8 - 2
h3d/pass/CascadeShadowMap.hx

@@ -2,6 +2,8 @@ package h3d.pass;
 
 typedef CascadeParams = {
 	var bias : Float;
+	var depthBias : Float;
+	var slopeBias : Float;
 }
 
 class CascadeShadowMap extends DirShadowMap {
@@ -186,16 +188,20 @@ class CascadeShadowMap extends DirShadowMap {
 			}
 			texture.depthBuffer = depth;
 			#else
-			var texture = ctx.textures.allocTarget("cascadeShadowMap_"+i, size, size, false, Depth24Stencil8);
+			var texture = ctx.textures.allocTarget("cascadeShadowMap_"+i, size, size, false, Depth16);
 			#end
+			// Bilinear depth only make sense if we use sample compare to get weighted shadow occlusion which we doesn't support yet.
+			texture.filter = Nearest;
 
 			currentCascadeIndex = i;
 			var p = passes.save();
 			cullPasses(passes,function(col) return col.inFrustum(lightCameras[i].frustum));
+			var param = params[cascade - 1 - i];			
+			texture.depthBias = (param != null) ? param.depthBias : 0;
+			texture.slopeScaledBias = (param != null) ? param.slopeBias : 0;			
 			texture = processShadowMap( passes, texture, sort);
 			textures.push(texture);
 			passes.load(p);
-
 		}
 		syncCascadeShader(textures);
 

+ 1 - 0
hxd/PixelFormat.hx

@@ -27,4 +27,5 @@ enum PixelFormat {
 	Depth16;
 	Depth24;
 	Depth24Stencil8;
+	Depth32;
 }

+ 2 - 2
hxd/Pixels.hx

@@ -564,7 +564,7 @@ class Pixels {
 			if( n == 1 || n == 4 )
 				return blocks << 1;
 			return blocks << 2;
-		case Depth16, Depth24, Depth24Stencil8:
+		case Depth16, Depth24, Depth24Stencil8, Depth32:
 			throw "Not a pixel format";
 		}
 	}
@@ -604,7 +604,7 @@ class Pixels {
 			channel.toInt() * 4;
 		case RGB10A2, RG11B10UF:
 			throw "Bit packed format";
-		case S3TC(_), Depth16, Depth24, Depth24Stencil8:
+		case S3TC(_), Depth16, Depth24, Depth24Stencil8, Depth32:
 			throw "Not supported";
 		}
 	}