Improve tangent export
This commit is contained in:
parent
8098ae931d
commit
886725f42a
|
@ -59,12 +59,13 @@ deltaSubscaleName = ["dxscl", "dyscl", "dzscl"]
|
|||
axisName = ["x", "y", "z"]
|
||||
|
||||
class ExportVertex:
|
||||
__slots__ = ("hash", "vertexIndex", "faceIndex", "position", "normal", "color", "texcoord0", "texcoord1")
|
||||
__slots__ = ("hash", "vertexIndex", "faceIndex", "position", "normal", "color", "texcoord0", "texcoord1", "tangent")
|
||||
|
||||
def __init__(self):
|
||||
self.color = [1.0, 1.0, 1.0]
|
||||
self.texcoord0 = [0.0, 0.0]
|
||||
self.texcoord1 = [0.0, 0.0]
|
||||
self.tangent = [0.0, 0.0, 0.0]
|
||||
|
||||
def __eq__(self, v):
|
||||
if (self.hash != v.hash):
|
||||
|
@ -79,6 +80,8 @@ class ExportVertex:
|
|||
return (False)
|
||||
if (self.texcoord1 != v.texcoord1):
|
||||
return (False)
|
||||
if (self.tangent != v.tangent):
|
||||
return (False)
|
||||
return (True)
|
||||
|
||||
def Hash(self):
|
||||
|
@ -95,6 +98,9 @@ class ExportVertex:
|
|||
h = h * 21737 + hash(self.texcoord0[1])
|
||||
h = h * 21737 + hash(self.texcoord1[0])
|
||||
h = h * 21737 + hash(self.texcoord1[1])
|
||||
h = h * 21737 + hash(self.tangent[0]) # Appended
|
||||
h = h * 21737 + hash(self.tangent[1])
|
||||
h = h * 21737 + hash(self.tangent[2])
|
||||
self.hash = h
|
||||
|
||||
class Object:
|
||||
|
@ -329,7 +335,22 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
|
|||
return ((ArmoryExporter.AnimationKeysDifferent(fcurve)) or (ArmoryExporter.AnimationTangentsNonzero(fcurve)))
|
||||
|
||||
@staticmethod
|
||||
def DeindexMesh(mesh, materialTable):
|
||||
def calc_tangent(v0, v1, v2, uv0, uv1, uv2):
|
||||
deltaPos1 = v1 - v0
|
||||
deltaPos2 = v2 - v0
|
||||
deltaUV1 = uv1 - uv0
|
||||
deltaUV2 = uv2 - uv0
|
||||
|
||||
d = (deltaUV1.x * deltaUV2.y - deltaUV1.y * deltaUV2.x)
|
||||
if d != 0:
|
||||
r = 1.0 / d
|
||||
else:
|
||||
r = 1.0
|
||||
tangent = (deltaPos1 * deltaUV2.y - deltaPos2 * deltaUV1.y) * r
|
||||
return tangent
|
||||
|
||||
@staticmethod
|
||||
def DeindexMesh(mesh, materialTable, export_tangents):
|
||||
# This function deindexes all vertex positions, colors, and texcoords.
|
||||
# Three separate ExportVertex structures are created for each triangle.
|
||||
vertexArray = mesh.vertices
|
||||
|
@ -475,6 +496,63 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
|
|||
vertexIndex += 1
|
||||
|
||||
faceIndex += 1
|
||||
|
||||
if (export_tangents):
|
||||
vertexIndex = 0
|
||||
faceIndex = 0
|
||||
|
||||
for face in mesh.tessfaces:
|
||||
# TODO: Speed up
|
||||
pos = exportVertexArray[vertexIndex].position
|
||||
tc = exportVertexArray[vertexIndex].texcoord0
|
||||
v0 = Vector((pos[0], pos[1], pos[2]))
|
||||
uv0 = Vector((tc[0], tc[1]))
|
||||
|
||||
pos = exportVertexArray[vertexIndex + 1].position
|
||||
tc = exportVertexArray[vertexIndex + 1].texcoord0
|
||||
v1 = Vector((pos[0], pos[1], pos[2]))
|
||||
uv1 = Vector((tc[0], tc[1]))
|
||||
|
||||
pos = exportVertexArray[vertexIndex + 2].position
|
||||
tc = exportVertexArray[vertexIndex + 2].texcoord0
|
||||
v2 = Vector((pos[0], pos[1], pos[2]))
|
||||
uv2 = Vector((tc[0], tc[1]))
|
||||
|
||||
tangent = ArmoryExporter.calc_tangent(v0, v1, v2, uv0, uv1, uv2)
|
||||
|
||||
exportVertexArray[vertexIndex].tangent = tangent
|
||||
vertexIndex += 1
|
||||
exportVertexArray[vertexIndex].tangent = tangent
|
||||
vertexIndex += 1
|
||||
exportVertexArray[vertexIndex].tangent = tangent
|
||||
vertexIndex += 1
|
||||
|
||||
if (len(face.vertices) == 4):
|
||||
pos = exportVertexArray[vertexIndex].position
|
||||
tc = exportVertexArray[vertexIndex].texcoord0
|
||||
v0 = Vector((pos[0], pos[1], pos[2]))
|
||||
uv0 = Vector((tc[0], tc[1]))
|
||||
|
||||
pos = exportVertexArray[vertexIndex + 1].position
|
||||
tc = exportVertexArray[vertexIndex + 1].texcoord0
|
||||
v1 = Vector((pos[0], pos[1], pos[2]))
|
||||
uv1 = Vector((tc[0], tc[1]))
|
||||
|
||||
pos = exportVertexArray[vertexIndex + 2].position
|
||||
tc = exportVertexArray[vertexIndex + 2].texcoord0
|
||||
v2 = Vector((pos[0], pos[1], pos[2]))
|
||||
uv2 = Vector((tc[0], tc[1]))
|
||||
|
||||
tangent = ArmoryExporter.calc_tangent(v0, v1, v2, uv0, uv1, uv2)
|
||||
|
||||
exportVertexArray[vertexIndex].tangent = tangent
|
||||
vertexIndex += 1
|
||||
exportVertexArray[vertexIndex].tangent = tangent
|
||||
vertexIndex += 1
|
||||
exportVertexArray[vertexIndex].tangent = tangent
|
||||
vertexIndex += 1
|
||||
|
||||
faceIndex += 1
|
||||
|
||||
for ev in exportVertexArray:
|
||||
ev.Hash()
|
||||
|
@ -1391,7 +1469,8 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
|
|||
|
||||
# Triangulate mesh and remap vertices to eliminate duplicates.
|
||||
materialTable = []
|
||||
exportVertexArray = ArmoryExporter.DeindexMesh(exportMesh, materialTable)
|
||||
export_tangents = self.get_export_tangents(exportMesh)
|
||||
exportVertexArray = ArmoryExporter.DeindexMesh(exportMesh, materialTable, export_tangents)
|
||||
triangleCount = len(materialTable)
|
||||
|
||||
indexTable = []
|
||||
|
@ -1439,6 +1518,14 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
|
|||
ta2.size = 2
|
||||
ta2.values = self.WriteVertexArray2D(unifiedVertexArray, "texcoord1")
|
||||
om.vertex_arrays.append(ta2)
|
||||
|
||||
# Tangents
|
||||
if (export_tangents):
|
||||
tana = Object()
|
||||
tana.attrib = "tangent"
|
||||
tana.size = 3
|
||||
tana.values = self.WriteVertexArray3D(unifiedVertexArray, "tangent")
|
||||
om.vertex_arrays.append(tana)
|
||||
|
||||
# If there are multiple morph targets, export them here.
|
||||
# if (shapeKeys):
|
||||
|
@ -1523,47 +1610,7 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
|
|||
ia.size = 3
|
||||
ia.values = self.WriteTriangleArray(materialTriangleCount[m], materialIndexTable)
|
||||
ia.material = self.WriteInt(m)
|
||||
om.index_arrays.append(ia)
|
||||
|
||||
# Export tangents
|
||||
# TODO: check for texture coords
|
||||
if (self.get_export_tangents(exportMesh) == True and len(exportMesh.uv_textures) > 0):
|
||||
ia = om.index_arrays[0].values
|
||||
posa = pa.values
|
||||
uva = ta.values
|
||||
tangents = []
|
||||
for i in range(0, int(len(ia) / 3)):
|
||||
i0 = ia[i * 3 + 0]
|
||||
i1 = ia[i * 3 + 1]
|
||||
i2 = ia[i * 3 + 2]
|
||||
# TODO: Speed up
|
||||
v0 = Vector((posa[i0 * 3 + 0], posa[i0 * 3 + 1], posa[i0 * 3 + 2]))
|
||||
v1 = Vector((posa[i1 * 3 + 0], posa[i1 * 3 + 1], posa[i1 * 3 + 2]))
|
||||
v2 = Vector((posa[i2 * 3 + 0], posa[i2 * 3 + 1], posa[i2 * 3 + 2]))
|
||||
uv0 = Vector((uva[i0 * 2 + 0], uva[i0 * 2 + 1]))
|
||||
uv1 = Vector((uva[i1 * 2 + 0], uva[i1 * 2 + 1]))
|
||||
uv2 = Vector((uva[i2 * 2 + 0], uva[i2 * 2 + 1]))
|
||||
|
||||
deltaPos1 = v1 - v0
|
||||
deltaPos2 = v2 - v0
|
||||
deltaUV1 = uv1 - uv0
|
||||
deltaUV2 = uv2 - uv0
|
||||
d = (deltaUV1.x * deltaUV2.y - deltaUV1.y * deltaUV2.x)
|
||||
if d != 0:
|
||||
r = 1.0 / d
|
||||
else:
|
||||
r = 1.0
|
||||
tangent = (deltaPos1 * deltaUV2.y - deltaPos2 * deltaUV1.y) * r
|
||||
|
||||
tangents.append(tangent.x)
|
||||
tangents.append(tangent.y)
|
||||
tangents.append(tangent.z)
|
||||
|
||||
tana = Object()
|
||||
tana.attrib = "tangent"
|
||||
tana.size = 3
|
||||
tana.values = tangents
|
||||
om.vertex_arrays.append(tana)
|
||||
om.index_arrays.append(ia)
|
||||
|
||||
# If the mesh is skinned, export the skinning data here.
|
||||
if (armature):
|
||||
|
|
|
@ -61,7 +61,7 @@ float shadowTest(vec4 lPos, float dotNL) {
|
|||
|
||||
vec4 packedZValue = texture(shadowMap, lPosH.st);
|
||||
float distanceFromLight = packedZValue.z;
|
||||
float bias = clamp(0.005 * tan(acos(dotNL)), 0.0, 0.01);
|
||||
float bias = 0.028;//clamp(0.005 * tan(acos(dotNL)), 0.0, 0.01);
|
||||
// 1.0 = not in shadow, 0.0 = in shadow
|
||||
return float(distanceFromLight > lPosH.z - bias);
|
||||
|
||||
|
@ -193,6 +193,19 @@ void main() {
|
|||
#ifdef _NMTex
|
||||
vec3 n = (texture(snormal, texCoord).rgb * 2.0 - 1.0);
|
||||
n = normalize(TBN * normalize(n));
|
||||
|
||||
// vec3 nn = normalize(normal);
|
||||
// vec3 dp1 = dFdx( position );
|
||||
// vec3 dp2 = dFdy( position );
|
||||
// vec2 duv1 = dFdx( texCoord );
|
||||
// vec2 duv2 = dFdy( texCoord );
|
||||
// vec3 dp2perp = cross( dp2, nn );
|
||||
// vec3 dp1perp = cross( nn, dp1 );
|
||||
// vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
|
||||
// vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
|
||||
// float invmax = inversesqrt( max( dot(T,T), dot(B,B) ) );
|
||||
// mat3 TBN = mat3(T * invmax, B * invmax, nn);
|
||||
// vec3 n = normalize(TBN * nn);
|
||||
#else
|
||||
vec3 n = normalize(normal);
|
||||
#endif
|
||||
|
@ -204,7 +217,7 @@ void main() {
|
|||
if (receiveShadow) {
|
||||
if (lPos.w > 0.0) {
|
||||
visibility = shadowTest(lPos, dotNL);
|
||||
visibility = 1.0;
|
||||
// visibility = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,7 +272,7 @@ void main() {
|
|||
|
||||
vec3 indirect = indirectDiffuse + indirectSpecular;
|
||||
|
||||
outColor = vec4(vec3((direct + indirect) * visibility), 1.0);
|
||||
outColor = vec4(vec3(direct * visibility + indirect), 1.0);
|
||||
|
||||
#ifdef _OMTex
|
||||
vec3 occlusion = texture(som, texCoord).rgb;
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
},
|
||||
{
|
||||
"id": "cull_mode",
|
||||
"value": "clockwise"
|
||||
"value": "counter_clockwise"
|
||||
},
|
||||
{
|
||||
"id": "blend_source",
|
||||
|
|
|
@ -130,6 +130,7 @@ void main() {
|
|||
#endif
|
||||
|
||||
vec3 mPos = vec4(M * sPos).xyz;
|
||||
position = mPos;
|
||||
lightDir = light - mPos;
|
||||
eyeDir = eye - mPos;
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ precision highp float;
|
|||
#endif
|
||||
|
||||
in vec3 pos;
|
||||
in vec3 nor;
|
||||
#ifdef _AMTex
|
||||
in vec2 tex;
|
||||
#endif
|
||||
in vec3 nor;
|
||||
#ifdef _VCols
|
||||
in vec4 col;
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue