Prechádzať zdrojové kódy

World: Add support for normal maps

trethaller 7 rokov pred
rodič
commit
e86a978dc1
1 zmenil súbory, kde vykonal 38 pridanie a 4 odobranie
  1. 38 4
      h3d/scene/World.hx

+ 38 - 4
h3d/scene/World.hx

@@ -45,6 +45,7 @@ class WorldMaterial {
 	public var bits : Int;
 	public var t : h3d.mat.BigTexture.BigTextureElement;
 	public var spec : h3d.mat.BigTexture.BigTextureElement;
+	public var normal : h3d.mat.BigTexture.BigTextureElement;
 	public var mat : hxd.fmt.hmd.Data.Material;
 	public var culling : Bool;
 	public var blend : h3d.mat.BlendMode;
@@ -60,7 +61,13 @@ class WorldMaterial {
 		shaders = [];
 	}
 	public function updateBits() {
-		bits = (t.t == null ? 0 : t.t.id << 8) | (blend.getIndex() << 5) | ((killAlpha == null ? 0 : 1) << 4) | ((lights ? 1 : 0) << 3) | ((shadows ? 1 : 0) << 2) | ((spec == null ? 0 : 1) << 1) | (culling ? 1 : 0);
+		bits = (t.t == null ? 0 : t.t.id    << 8)
+			| ((normal == null ? 0 : 1)     << 5)
+			| ((killAlpha == null ? 0 : 1)  << 4)
+			| ((lights ? 1 : 0)             << 3)
+			| ((shadows ? 1 : 0)            << 2)
+			| ((spec == null ? 0 : 1)       << 1)
+			| (culling ? 1 : 0);
 	}
 }
 
@@ -101,6 +108,10 @@ class World extends Object {
 		For each texture loaded, will call resolveSpecularTexture and have separate spec texture.
 	*/
 	public var enableSpecular = false;
+	/*
+		For each texture loaded, will call resolveNormalMap and have separate normal texture.
+	*/
+	public var enableNormals = false;
 	/*
 		When enableSpecular=true, will store the specular value in the alpha channel instead of a different texture.
 		This will erase alpha value of transparent textures, so should only be used if specular is only on opaque models.
@@ -113,7 +124,7 @@ class World extends Object {
 	var soilColor = 0x408020;
 	var chunks : Array<WorldChunk>;
 	var allChunks : Array<WorldChunk>;
-	var bigTextures : Array<{ diffuse : h3d.mat.BigTexture, spec : h3d.mat.BigTexture }>;
+	var bigTextures : Array<{ diffuse : h3d.mat.BigTexture, spec : h3d.mat.BigTexture, normal : h3d.mat.BigTexture }>;
 	var textures : Map<String, WorldMaterial>;
 
 	public function new( chunkSize : Int, worldSize : Int, ?parent, ?autoCollect = true ) {
@@ -172,6 +183,10 @@ class World extends Object {
 		}
 	}
 
+	function resolveNormalMap( path : String ) : hxd.res.Image {
+		return null;
+	}
+
 	function loadMaterialTexture( r : hxd.res.Model, mat : hxd.fmt.hmd.Data.Material ) : WorldMaterial {
 		var texturePath = resolveTexturePath(r, mat.diffuseTexture);
 		var m = textures.get(texturePath);
@@ -190,7 +205,7 @@ class World extends Object {
 		}
 		if( t == null ) {
 			var b = new h3d.mat.BigTexture(bigTextures.length, bigTextureSize, bigTextureBG);
-			btex = { diffuse : b, spec : null };
+			btex = { diffuse : b, spec : null, normal : null };
 			bigTextures.unshift( btex );
 			t = b.add(rt);
 			if( t == null ) throw "Texture " + texturePath + " is too big";
@@ -214,9 +229,21 @@ class World extends Object {
 			}
 		}
 
+		var normalMap = null;
+		if( enableNormals ) {
+			var res = resolveNormalMap(texturePath);
+			if( btex.normal == null )
+				btex.normal = new h3d.mat.BigTexture(-1, bigTextureSize, bigTextureBG);
+			if( res != null )
+				normalMap = btex.normal.add(res);
+			else
+				@:privateAccess btex.normal.allocPos(t.t.tex.width, t.t.tex.height); // keep UV in-sync
+		}
+
 		var m = new WorldMaterial();
 		m.t = t;
 		m.spec = specTex;
+		m.normal = normalMap;
 		m.blend = getBlend(rt);
 		m.killAlpha = null;
 		m.mat = mat;
@@ -231,6 +258,8 @@ class World extends Object {
 			b.diffuse.done();
 			if(b.spec != null)
 				b.spec.done();
+			if(b.normal != null)
+				b.normal.done();
 		}
 	}
 
@@ -407,7 +436,8 @@ class World extends Object {
 		mesh.material.textureShader.killAlphaThreshold = mat.killAlpha;
 		mesh.material.mainPass.enableLights = mat.lights;
 		mesh.material.shadows = mat.shadows;
-		mesh.material.mainPass.culling = mat.culling ? Back : None;
+		mesh.material.mainPass.culling = Back;
+		mesh.material.mainPass.depthWrite = true;
 
 		for(s in mat.shaders)
 			mesh.material.mainPass.addShader(s);
@@ -420,6 +450,10 @@ class World extends Object {
 				mesh.material.specularTexture = mat.spec.t.tex;
 		} else
 			mesh.material.specularAmount = 0;
+
+		if(mat.normal != null) {
+			mesh.material.normalMap = mat.normal.t.tex;
+		}
 	}
 
 	override function dispose() {