Selaa lähdekoodia

added stencil support to pbr

ncannasse 7 vuotta sitten
vanhempi
commit
36ea11b689
4 muutettua tiedostoa jossa 33 lisäystä ja 6 poistoa
  1. 1 1
      h3d/impl/DirectXDriver.hx
  2. 15 3
      h3d/impl/GlDriver.hx
  3. 16 1
      h3d/mat/DepthBuffer.hx
  4. 1 1
      h3d/scene/pbr/Renderer.hx

+ 1 - 1
h3d/impl/DirectXDriver.hx

@@ -537,7 +537,7 @@ class DirectXDriver extends h3d.impl.Driver {
 		currentMaterialBits = bits;
 
 		var depthBits = bits & (Pass.depthWrite_mask | Pass.depthTest_mask);
-		if( pass.stencil != null ) throw "TODO";
+		if( pass.stencil != null ) throw "TODO: Stencil support";
 		var depth = depthStates.get(depthBits);
 		if( depth == null ) {
 			var cmp = Pass.getDepthTest(bits);

+ 15 - 3
h3d/impl/GlDriver.hx

@@ -731,8 +731,17 @@ class GlDriver extends Driver {
 
 	override function allocDepthBuffer( b : h3d.mat.DepthBuffer ) : DepthBuffer {
 		var r = gl.createRenderbuffer();
+		if( b.format == null )
+			@:privateAccess b.format = #if js (glES >= 3 ? Depth24Stencil8 : Depth16) #else Depth24Stencil8 #end;
+		var format = switch( b.format ) {
+		case Depth16: GL.DEPTH_COMPONENT16;
+		case Depth24 #if js if( glES >= 3 ) #end: GL2.DEPTH_COMPONENT24;
+		case Depth24Stencil8: GL.DEPTH_STENCIL;
+		default:
+			throw "Unsupported depth format "+b.format;
+		}
 		gl.bindRenderbuffer(GL.RENDERBUFFER, r);
-		gl.renderbufferStorage(GL.RENDERBUFFER, #if js glES >= 3 ? GL2.DEPTH_COMPONENT24 : GL.DEPTH_COMPONENT16 #else GL.DEPTH_COMPONENT24 #end, b.width, b.height);
+		gl.renderbufferStorage(GL.RENDERBUFFER, format, b.width, b.height);
 		gl.bindRenderbuffer(GL.RENDERBUFFER, null);
 		return { r : r #if multidriver, driver : this #end };
 	}
@@ -1156,10 +1165,13 @@ class GlDriver extends Driver {
 		#end
 		gl.bindFramebuffer(GL.FRAMEBUFFER, commonFB);
 		gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, tex.flags.has(Cube) ? CUBE_FACES[face] : GL.TEXTURE_2D, tex.t.t, mipLevel);
-		if( tex.depthBuffer != null )
+		if( tex.depthBuffer != null ) {
 			gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.RENDERBUFFER, @:privateAccess tex.depthBuffer.b.r);
-		else
+			gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.STENCIL_ATTACHMENT, GL.RENDERBUFFER, tex.depthBuffer.hasStencil() ? @:privateAccess tex.depthBuffer.b.r : null);
+		} else {
 			gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.RENDERBUFFER, null);
+			gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.STENCIL_ATTACHMENT, GL.RENDERBUFFER, null);
+		}
 		gl.viewport(0, 0, tex.width >> mipLevel, tex.height >> mipLevel);
 		for( i in 0...boundTextures.length )
 			boundTextures[i] = null;

+ 16 - 1
h3d/mat/DepthBuffer.hx

@@ -1,5 +1,11 @@
 package h3d.mat;
 
+enum DepthFormat {
+	Depth16;
+	Depth24;
+	Depth24Stencil8;
+}
+
 /**
 	Depth buffer are used to store per pixel depth information when rendering a scene (also called Z-buffer)
 **/
@@ -9,16 +15,25 @@ class DepthBuffer {
 	var b : h3d.impl.Driver.DepthBuffer;
 	public var width(default, null) : Int;
 	public var height(default, null) : Int;
+	public var format(default, null) : DepthFormat;
 
 	/**
 		Creates a new depth buffer, it can be attached to one or several render target Texture by setting their `depthBuffer` property.
 	**/
-	public function new( width : Int, height : Int ) {
+	public function new( width : Int, height : Int, ?format : DepthFormat ) {
 		this.width = width;
 		this.height = height;
+		this.format = format;
 		if( width > 0 ) alloc();
 	}
 
+	public function hasStencil() {
+		return switch( format ) {
+		case Depth16, Depth24: false;
+		case Depth24Stencil8: true;
+		}
+	}
+
 	function alloc() {
 		h3d.Engine.getCurrent().mem.allocDepth(this);
 	}

+ 1 - 1
h3d/scene/pbr/Renderer.hx

@@ -108,7 +108,7 @@ class Renderer extends h3d.scene.Renderer {
 		var normal = allocTarget("normalDepth",0,false,RGBA32F);
 		var pbr = allocTarget("pbr",0,false);
 		setTargets([albedo,normal,pbr]);
-		clear(0, 1);
+		clear(0, 1, 0);
 		output.draw(getSort("default", true));
 		output.draw(getSort("alpha"));
 		output.draw(get("additive"));