Bladeren bron

fixed pbr sampler on directX : more cube texture support

ncannasse 7 jaren geleden
bovenliggende
commit
9ab5710544
4 gewijzigde bestanden met toevoegingen van 66 en 26 verwijderingen
  1. 37 18
      h3d/impl/DirectXDriver.hx
  2. 1 1
      h3d/impl/Driver.hx
  3. 17 3
      hxsl/HlslOut.hx
  4. 11 4
      samples/Pbr.hx

+ 37 - 18
h3d/impl/DirectXDriver.hx

@@ -11,6 +11,7 @@ private class ShaderContext {
 	public var globalsSize : Int;
 	public var paramsSize : Int;
 	public var texturesCount : Int;
+	public var textures2DCount : Int;
 	public var paramsContent : hl.Bytes;
 	public var globals : dx.Resource;
 	public var params : dx.Resource;
@@ -328,8 +329,7 @@ class DirectXDriver extends h3d.impl.Driver {
 		vdesc.start = 0; // top mip level
 		vdesc.count = -1; // all mip levels
 		var view = Driver.createShaderResourceView(tex, vdesc);
-		var rtView = rt ? Driver.createRenderTargetView(tex) : null;
-		return { res : tex, view : view, rt : rtView, mips : mips };
+		return { res : tex, view : view, rt : rt ? [] : null, mips : mips };
 	}
 
 	override function disposeTexture( t : h3d.mat.Texture ) {
@@ -338,7 +338,10 @@ class DirectXDriver extends h3d.impl.Driver {
 		t.t = null;
 		tt.view.release();
 		tt.res.release();
-		if( tt.rt != null ) tt.rt.release();
+		if( tt.rt != null )
+			for( rt in tt.rt )
+				if( rt != null )
+					rt.release();
 	}
 
 	override function disposeVertexes(v:VertexBuffer) {
@@ -516,6 +519,7 @@ class DirectXDriver extends h3d.impl.Driver {
 		ctx.paramsContent = new hl.Bytes(shader.paramsSize * 16);
 		ctx.paramsContent.fill(0, shader.paramsSize * 16, 0xDD);
 		ctx.texturesCount = shader.textures2DCount + shader.texturesCubeCount;
+		ctx.textures2DCount = shader.textures2DCount;
 		ctx.globals = dx.Driver.createBuffer(shader.globalsSize * 16, Dynamic, ConstantBuffer, CpuWrite, None, 0, null);
 		ctx.params = dx.Driver.createBuffer(shader.paramsSize * 16, Dynamic, ConstantBuffer, CpuWrite, None, 0, null);
 		#if debug
@@ -552,8 +556,6 @@ class DirectXDriver extends h3d.impl.Driver {
 
 	var tmpTextures = new Array<h3d.mat.Texture>();
 	override function setRenderTarget(tex:Null<h3d.mat.Texture>, face = 0, mipLevel = 0) {
-		if( face != 0 || mipLevel != 0 )
-			throw "TODO";
 		if( tex == null ) {
 			curTexture = null;
 			currentDepth = defaultDepth;
@@ -566,7 +568,7 @@ class DirectXDriver extends h3d.impl.Driver {
 			return;
 		}
 		tmpTextures[0] = tex;
-		setRenderTargets(tmpTextures);
+		_setRenderTargets(tmpTextures, face, mipLevel);
 	}
 
 	function unbind( res ) {
@@ -583,6 +585,10 @@ class DirectXDriver extends h3d.impl.Driver {
 	}
 
 	override function setRenderTargets(textures:Array<h3d.mat.Texture>) {
+		_setRenderTargets(textures, 0, 0);
+	}
+
+	function _setRenderTargets( textures:Array<h3d.mat.Texture>, face : Int, mipLevel : Int ) {
 		if( textures.length == 0 ) {
 			setRenderTarget(null);
 			return;
@@ -598,19 +604,30 @@ class DirectXDriver extends h3d.impl.Driver {
 				tex.alloc();
 			if( tex.t.rt == null )
 				throw "Can't render to texture which is not allocated with Target flag";
+			var index = mipLevel * 6 + face;
+			var rt = tex.t.rt[index];
+			if( rt == null ) {
+				var cube = tex.flags.has(Cube);
+				var v = new dx.Driver.RenderTargetDesc(getTextureFormat(tex), cube ? Texture2DArray : Texture2D);
+				v.mipMap = mipLevel;
+				v.firstSlice = face;
+				v.sliceCount = 1;
+				rt = Driver.createRenderTargetView(tex.t.res, v);
+				tex.t.rt[index] = rt;
+			}
 			tex.lastFrame = frame;
-			currentTargets[i] = tex.t.rt;
+			currentTargets[i] = rt;
 			unbind(tex.t.view);
 			// prevent garbage
 			if( !tex.flags.has(WasCleared) ) {
 				tex.flags.set(WasCleared);
-				Driver.clearColor(tex.t.rt, 0, 0, 0, 0);
+				Driver.clearColor(rt, 0, 0, 0, 0);
 			}
 		}
 		Driver.omSetRenderTargets(textures.length, currentTargets, currentDepth == null ? null : currentDepth.view);
 
-		viewport[2] = tex.width;
-		viewport[3] = tex.height;
+		viewport[2] = tex.width >> mipLevel;
+		viewport[3] = tex.height >> mipLevel;
 		viewport[5] = 1.;
 		Driver.rsSetViewports(1, viewport);
 	}
@@ -789,8 +806,12 @@ class DirectXDriver extends h3d.impl.Driver {
 			for( i in 0...shader.texturesCount ) {
 				var t = buffers.tex[i];
 				if( t == null || t.isDisposed() ) {
-					var color = h3d.mat.Defaults.loadingTextureColor;
-					t = h3d.mat.Texture.fromColor(color,(color>>>24)/255);
+					if( i < shader.textures2DCount ) {
+						var color = h3d.mat.Defaults.loadingTextureColor;
+						t = h3d.mat.Texture.fromColor(color, (color >>> 24) / 255);
+					} else {
+						t = h3d.mat.Texture.defaultCubeTexture();
+					}
 				}
 				if( t != null && t.t == null && t.realloc != null ) {
 					t.alloc();
@@ -812,12 +833,10 @@ class DirectXDriver extends h3d.impl.Driver {
 						var desc = new SamplerDesc();
 						desc.filter = FILTER[t.mipMap.getIndex()][t.filter.getIndex()];
 						desc.addressU = desc.addressV = desc.addressW = WRAP[t.wrap.getIndex()];
-						if( t.mipMap == None ) {
-							desc.minLod = desc.maxLod = 0;
-						} else {
-							desc.minLod = 0;
-							desc.maxLod = 1e30;
-						}
+						// if mipMap = None && hasMipmaps : don't set per-sampler maxLod !
+						// only the first sampler maxLod seems to be taken into account :'(
+						desc.minLod = 0;
+						desc.maxLod = 1e30;
 						ss = Driver.createSamplerState(desc);
 						samplerStates.set(bits, ss);
 					}

+ 1 - 1
h3d/impl/Driver.hx

@@ -39,7 +39,7 @@ typedef Query = { q : haxe.GLTypes.Query, kind : QueryKind };
 #elseif hldx
 typedef IndexBuffer = { res : dx.Resource, count : Int };
 typedef VertexBuffer = { res : dx.Resource, count : Int, stride : Int };
-typedef Texture = { res : dx.Resource, view : dx.Driver.ShaderResourceView, rt : dx.Driver.RenderTargetView, mips : Int };
+typedef Texture = { res : dx.Resource, view : dx.Driver.ShaderResourceView, rt : Array<dx.Driver.RenderTargetView>, mips : Int };
 typedef DepthBuffer = { res : dx.Resource, view : dx.Driver.DepthStencilView };
 typedef Query = {};
 #else

+ 17 - 3
hxsl/HlslOut.hx

@@ -211,9 +211,16 @@ class HlslOut {
 			var acc = varAccess.get(v.id);
 			if( acc != null ) add(acc);
 			ident(v);
-		case TCall({ e : TGlobal(Texture2D | TextureCube) }, args):
-			addValue(args[0],tabs);
-			add(".Sample(");
+		case TCall({ e : TGlobal(g = (Texture2D | TextureCube | Texture2DLod | TextureCubeLod)) }, args):
+			addValue(args[0], tabs);
+			switch( g ) {
+			case Texture2D, TextureCube:
+				add(".Sample(");
+			case Texture2DLod, TextureCubeLod:
+				add(".SampleLevel(");
+			default:
+				throw "assert";
+			}
 			switch( args[0].e ) {
 			case TArray(e,index):
 				addValue(e, tabs);
@@ -325,6 +332,13 @@ class HlslOut {
 				add(",");
 				addValue(e2, tabs);
 				add(")");
+			case [OpUShr, _, _]:
+				decl("int _ushr( int a, int b) { return (int)(((unsigned int)a) >> b); }");
+				add("_ushr(");
+				addValue(e1, tabs);
+				add(",");
+				addValue(e2, tabs);
+				add(")");
 			default:
 				addValue(e1, tabs);
 				add(" ");

+ 11 - 4
samples/Pbr.hx

@@ -339,6 +339,9 @@ class Irradiance extends IrradBase {
 				// https://seblagarde.wordpress.com/2012/06/10/amd-cubemapgen-for-physically-based-rendering/
 				d += cubeScaleFactor * (d * d * d);
 			}
+			#if hldx
+			d.y *= -1;
+			#end
 			var n : Vec3;
 			switch( face ) {
 			case 0: n = vec3(1, d.y, -d.x);
@@ -475,6 +478,7 @@ class Pbr extends hxd.App {
 		fui.isVertical = true;
 
 		envMap = new h3d.mat.Texture(512, 512, [Cube]);
+		envMap.name = "envMap";
 		inline function set(face:Int, res:hxd.res.Image) {
 			#if flash
 			// all mipmap levels required
@@ -530,8 +534,10 @@ class Pbr extends hxd.App {
 
 		computeIrradLut();
 
-		irradDiffuse = new h3d.mat.Texture(size, size, [Cube]);
-		irradSpecular = new h3d.mat.Texture(ssize, ssize, [Cube, MipMapped]);
+		irradDiffuse = new h3d.mat.Texture(size, size, [Cube, Target]);
+		irradDiffuse.name = "irradDiffuse";
+		irradSpecular = new h3d.mat.Texture(ssize, ssize, [Cube, Target, MipMapped, ManualMipMapGen]);
+		irradSpecular.name = "irradSpecular";
 		irradSpecular.mipMap = Linear;
 		computeIrradiance();
 
@@ -642,7 +648,8 @@ class Pbr extends hxd.App {
 	}
 
 	function computeIrradLut() {
-		var irradLut = new h3d.mat.Texture(128, 128, #if js RGBA32F #else RGBA16F #end);
+		var irradLut = new h3d.mat.Texture(128, 128, [Target], #if js RGBA32F #else RGBA16F #end);
+		irradLut.name = "irradLut";
 		var screen = new h3d.pass.ScreenFx(new IrradianceLut());
 		screen.shader.samplesBits = sampleBits;
 		#if (js || flash)
@@ -681,7 +688,7 @@ class Pbr extends hxd.App {
 		while( irradSpecular.width > 1 << (mipLevels - 1) )
 			mipLevels++;
 
-		shader.irrSpecularLevels = mipLevels - 4;
+		shader.irrSpecularLevels = mipLevels - 5;
 
 		for( i in 0...6 ) {
 			screen.shader.face = i;