Explorar o código

added hmd tangents and normal map shader

ncannasse %!s(int64=7) %!d(string=hai) anos
pai
achega
5b72da155e
Modificáronse 5 ficheiros con 97 adicións e 5 borrados
  1. 22 1
      h3d/mat/Material.hx
  2. 49 0
      h3d/shader/NormalMap.hx
  3. 2 0
      hxd/fmt/fbx/BaseLibrary.hx
  4. 12 2
      hxd/fmt/fbx/Geometry.hx
  5. 12 2
      hxd/fmt/fbx/HMDOut.hx

+ 22 - 1
h3d/mat/Material.hx

@@ -3,6 +3,7 @@ package h3d.mat;
 class Material extends BaseMaterial {
 
 	var mshader : h3d.shader.BaseMesh;
+	var normalShader : h3d.shader.NormalMap;
 
 	public var props(default, set) : Any;
 	public var model : hxd.res.Resource;
@@ -15,7 +16,7 @@ class Material extends BaseMaterial {
 	public var specularShader(default, null) : h3d.shader.SpecularTexture;
 	public var texture(get, set) : h3d.mat.Texture;
 	public var specularTexture(get, set) : h3d.mat.Texture;
-	public var normalMap : h3d.mat.Texture;
+	public var normalMap(get,set) : h3d.mat.Texture;
 
 	public var color(get, set) : Vector;
 	public var specularAmount(get, set) : Float;
@@ -158,6 +159,26 @@ class Material extends BaseMaterial {
 		return t;
 	}
 
+	function get_normalMap() {
+		return normalShader == null ? null : normalShader.texture;
+	}
+
+	function set_normalMap(t) {
+		if( t == null ) {
+			if( normalShader != null ) {
+				mainPass.removeShader(normalShader);
+				normalShader = null;
+			}
+		} else {
+			if( normalShader == null ) {
+				normalShader = new h3d.shader.NormalMap();
+				mainPass.addShader(normalShader);
+			}
+			normalShader.texture = t;
+		}
+		return t;
+	}
+
 	function set_specularTexture(t) {
 		if( t == null ) {
 			if( specularShader != null ) {

+ 49 - 0
h3d/shader/NormalMap.hx

@@ -0,0 +1,49 @@
+package h3d.shader;
+
+class NormalMap extends hxsl.Shader {
+
+    static var SRC = {
+
+		@global var camera : {
+			var position : Vec3;
+			@var var dir : Vec3;
+		};
+
+        @global var global : {
+            @perObject var modelView : Mat4;
+        };
+
+        @input var input : {
+            var normal : Vec3;
+			var tangent : Vec3;
+        };
+
+        @param var texture : Sampler2D;
+
+        var calculatedUV : Vec2;
+		var transformedPosition : Vec3;
+        var transformedNormal : Vec3;
+
+		@var var transformedTangent : Vec3;
+
+		function vertex() {
+			transformedTangent = input.tangent * global.modelView.mat3();
+		}
+
+		function fragment() {
+			var n = transformedNormal;
+			var nf = unpackNormal(texture.get(calculatedUV));
+			var tanX = transformedTangent.normalize();
+			tanX.x *= -1;
+			var tanY = n.cross(tanX);
+			transformedNormal = (nf.x * tanX - nf.y * tanY + nf.z * n).normalize();
+        }
+    };
+
+    public function new(?texture) {
+        super();
+        this.texture = texture;
+		h3d.Engine.getCurrent().driver.hasFeature(StandardDerivatives);
+    }
+
+}

+ 2 - 0
hxd/fmt/fbx/BaseLibrary.hx

@@ -198,6 +198,8 @@ class BaseLibrary {
 				convertPoints(v.getFloats());
 			for( v in g.getAll("LayerElementNormal.Normals") )
 				convertPoints(v.getFloats());
+			for( v in g.getAll("LayerElementNormal.Tangents") )
+				convertPoints(v.getFloats());
 		}
 	}
 

+ 12 - 2
hxd/fmt/fbx/Geometry.hx

@@ -170,10 +170,20 @@ class Geometry {
 	}
 
 	public function getNormals() {
-		var nrm = root.get("LayerElementNormal.Normals").getFloats();
+		return processVectors("LayerElementNormal", "Normals");
+	}
+
+	public function getTangents( opt = false ) {
+		return processVectors("LayerElementTangent", "Tangents", opt);
+	}
+
+	function processVectors( layer, name, opt = false ) {
+		var vect = root.get(layer + "." + name, opt);
+		if( vect == null ) return null;
+		var nrm = vect.getFloats();
 		// if by-vertice (Maya in some cases, unless maybe "Split per-Vertex Normals" is checked)
 		// let's reindex based on polygon indexes
-		if( root.get("LayerElementNormal.MappingInformationType").props[0].toString() == "ByVertice" ) {
+		if( root.get(layer+".MappingInformationType").props[0].toString() == "ByVertice" ) {
 			var nout = [];
 			for( i in getPolygons() ) {
 				var vid = i;

+ 12 - 2
hxd/fmt/fbx/HMDOut.hx

@@ -42,6 +42,7 @@ class HMDOut extends BaseLibrary {
 		var uvs = geom.getUVs();
 		var colors = geom.getColors();
 		var mats = geom.getMaterials();
+		var tangents = geom.getTangents(true);
 
 		// remove empty color data
 		if( colors != null ) {
@@ -61,18 +62,21 @@ class HMDOut extends BaseLibrary {
 		];
 		if( normals != null )
 			g.vertexFormat.push(new GeometryFormat("normal", DVec3));
+		if( tangents != null )
+			g.vertexFormat.push(new GeometryFormat("tangent", DVec3));
 		for( i in 0...uvs.length )
 			g.vertexFormat.push(new GeometryFormat("uv" + (i == 0 ? "" : "" + (i + 1)), DVec2));
 		if( colors != null )
 			g.vertexFormat.push(new GeometryFormat("color", DVec3));
 
-		var stride = 3 + (normals == null ? 0 : 3) + uvs.length * 2 + (colors == null ? 0 : 3);
 		if( skin != null ) {
 			if( bonesPerVertex <= 0 || bonesPerVertex > 4 ) throw "assert";
 			g.vertexFormat.push(new GeometryFormat("weights", [DFloat, DVec2, DVec3, DVec4][bonesPerVertex-1]));
 			g.vertexFormat.push(new GeometryFormat("indexes", floatSkinIndexes ? [DFloat, DVec2, DVec3, DVec4][bonesPerVertex-1] : DBytes4));
-			stride += bonesPerVertex + (floatSkinIndexes ? bonesPerVertex : 1);
 		}
+		var stride = 0;
+		for( f in g.vertexFormat )
+			stride += f.format.getSize();
 		g.vertexStride = stride;
 		g.vertexCount = 0;
 
@@ -127,6 +131,12 @@ class HMDOut extends BaseLibrary {
 					tmpBuf[p++] = nz;
 				}
 
+				if( tangents != null ) {
+					tmpBuf[p++] = tangents[k * 3];
+					tmpBuf[p++] = tangents[k * 3 + 1];
+					tmpBuf[p++] = tangents[k * 3 + 2];
+				}
+
 				for( tuvs in uvs ) {
 					var iuv = tuvs.index[k];
 					tmpBuf[p++] = tuvs.values[iuv * 2];