From 86721a55699193e63c76e8a0a7b0ced0416c1cce Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 13 Apr 2021 13:22:02 +0300 Subject: [PATCH] Include only tangent in mesh data and calculate binormal on the fly This saves one vertex attribute. --- blender/io_mspgl/export_mesh.py | 9 ++---- blender/io_mspgl/mesh.py | 48 ++++++++++++----------------- blender/io_mspgl/properties.py | 8 ++--- shaderlib/common.glsl | 2 +- shaderlib/msp_interface.glsl | 9 +++--- source/builders/box.cpp | 7 ++--- source/builders/capsule.cpp | 5 +-- source/builders/cylinder.cpp | 8 ++--- source/builders/geometrybuilder.cpp | 6 ++-- source/builders/geometrybuilder.h | 7 +++-- source/builders/grid.cpp | 5 +-- source/builders/sphere.cpp | 5 +-- source/builders/vertexbuilder.h | 8 ++--- source/core/vertexarray.cpp | 7 +++-- source/core/vertexformat.cpp | 6 +++- source/core/vertexformat.h | 9 +++--- 16 files changed, 64 insertions(+), 85 deletions(-) diff --git a/blender/io_mspgl/export_mesh.py b/blender/io_mspgl/export_mesh.py index 68d93cbc..16f9514a 100644 --- a/blender/io_mspgl/export_mesh.py +++ b/blender/io_mspgl/export_mesh.py @@ -73,9 +73,8 @@ class MeshExporter: st.append(Token("TEXCOORD"+size)) else: st.append(Token("TEXCOORD{}_{}".format(size, u.unit))) - if mesh.tbn_vecs: + if mesh.tangent_vecs: st.append(Token("TANGENT3")) - st.append(Token("BINORMAL3")) if mesh.vertex_groups: st.append(Token("GROUP{}".format(mesh.max_groups_per_vertex))) st.append(Token("WEIGHT{}".format(mesh.max_groups_per_vertex))) @@ -85,7 +84,6 @@ class MeshExporter: color = None uvs = [None]*len(mesh.uv_layers) tan = None - bino = None group = None weight = None for v in mesh.vertices: @@ -102,13 +100,10 @@ class MeshExporter: else: st.sub.append(Statement("multitexcoord", u.unit, *v.uvs[i])) uvs[i] = v.uvs[i] - if mesh.tbn_vecs: + if mesh.tangent_vecs: if v.tan!=tan: st.sub.append(Statement("tangent", *v.tan)) tan = v.tan - if v.bino!=bino: - st.sub.append(Statement("binormal", *v.bino)) - bino = v.bino if mesh.vertex_groups: v_group = [g.group for g in v.groups] v_weight = [g.weight for g in v.groups] diff --git a/blender/io_mspgl/mesh.py b/blender/io_mspgl/mesh.py index 754e6ffc..9741b8dd 100644 --- a/blender/io_mspgl/mesh.py +++ b/blender/io_mspgl/mesh.py @@ -48,11 +48,9 @@ class Vertex: if vertex.__class__==Vertex: self.uvs = vertex.uvs[:] self.tan = vertex.tan - self.bino = vertex.bino else: self.uvs = [] self.tan = None - self.bino = None self.index = vertex.index self.co = mathutils.Vector(vertex.co) self.normal = mathutils.Vector(vertex.normal) @@ -160,8 +158,8 @@ class Mesh: self.winding_test = mesh.winding_test self.smoothing = mesh.smoothing self.use_uv = mesh.use_uv - self.tbn_vecs = mesh.tbn_vecs - self.tbn_uvtex = mesh.tbn_uvtex + self.tangent_vecs = mesh.tangent_vecs + self.tangent_uvtex = mesh.tangent_uvtex self.vertex_groups = mesh.vertex_groups # Clone basic data @@ -447,31 +445,31 @@ class Mesh: prog_count = len(self.uv_layers) prog_step = 0 - # Split by the UV layer used for TBN vectors first so connectivity - # remains intact for TBN vector computation - tbn_layer_index = -1 - if self.tbn_vecs: - if self.tbn_uvtex: + # Split by the UV layer used for tangent vectors first so connectivity + # remains intact for tangent vector computation + tangent_layer_index = -1 + if self.tangent_vecs: + if self.tangent_uvtex: uv_names = [u.name for u in self.uv_layers] - if self.tbn_uvtex in uv_names: - tbn_layer_index = uv_names.index(self.tbn_uvtex) + if self.tangent_uvtex in uv_names: + tangent_layer_index = uv_names.index(self.tangent_uvtex) elif self.uv_layers[0].unit==0: - tbn_layer_index = 0 + tangent_layer_index = 0 - if tbn_layer_index>=0: + if tangent_layer_index>=0: prog_count += 1 - progress.push_task_slice("Computing TBN", 0, prog_count) - self.split_vertices(self.find_uv_group, progress, tbn_layer_index) - progress.set_task_slice(self.tbn_uvtex, 1, prog_count) - self.compute_tbn(tbn_layer_index, progress) + progress.push_task_slice("Computing tangents", 0, prog_count) + self.split_vertices(self.find_uv_group, progress, tangent_layer_index) + progress.set_task_slice(self.tangent_uvtex, 1, prog_count) + self.compute_tangents(tangent_layer_index, progress) progress.pop_task() prog_step = 2 else: - raise Exception("TBN UV layer not found") + raise Exception("Tangent UV layer not found") # Split by the remaining UV layers for i, u in enumerate(self.uv_layers): - if i==tbn_layer_index: + if i==tangent_layer_index: continue progress.push_task_slice(u.name, prog_step, prog_count) @@ -620,14 +618,11 @@ class Mesh: progress.set_progress(i/len(self.vertices)) - def compute_tbn(self, index, progress): - # This function is called at an early stage during UV preparation when - # face UVs are not available yet + def compute_tangents(self, index, progress): layer_uvs = self.uv_layers[index].uvs for i, v in enumerate(self.vertices): v.tan = mathutils.Vector() - v.bino = mathutils.Vector() for f in v.faces: vi = f.pivot_vertex(v) uv0 = layer_uvs[f.loop_indices[vi[0]]] @@ -643,12 +638,9 @@ class Mesh: if div: mul = edge1.angle(edge2)/div v.tan += (edge1*dv2-edge2*dv1)*mul - v.bino += (edge2*du1-edge1*du2)*mul if v.tan.length: v.tan.normalize() - if v.bino.length: - v.bino.normalize() progress.set_progress(i/len(self.vertices)) @@ -817,8 +809,8 @@ def create_mesh_from_object(context, obj, progress, *, material_atlas=None): bmesh.vertex_groups = o.data.vertex_groups bmesh.max_groups_per_vertex = o.data.max_groups_per_vertex bmesh.use_uv = o.data.use_uv - bmesh.tbn_vecs = o.data.tbn_vecs - bmesh.tbn_uvtex = o.data.tbn_uvtex + bmesh.tangent_vecs = o.data.tangent_vecs + bmesh.tangent_uvtex = o.data.tangent_uvtex me = Mesh(bmesh) me.transform(m) diff --git a/blender/io_mspgl/properties.py b/blender/io_mspgl/properties.py index baf9ac95..0d5a6d46 100644 --- a/blender/io_mspgl/properties.py +++ b/blender/io_mspgl/properties.py @@ -30,8 +30,8 @@ class MspGLMeshProperties(bpy.types.Panel): col = self.layout.column() col.label(text="Texturing") col.prop(mesh, "use_uv") - col.prop(mesh, "tbn_vecs") - col.prop(mesh, "tbn_uvtex") + col.prop(mesh, "tangent_vecs") + col.prop(mesh, "tangent_uvtex") class MspGLObjectProperties(bpy.types.Panel): bl_idname = "OBJECT_PT_mspgl_properties" @@ -147,8 +147,8 @@ def register_properties(): items=(("NONE", "None", "Ignore all UV coordinates"), ("UNIT0", "Unit 0", "Use UV coordinates for unit 0"), ("ALL", "All", "Use all UV coordinates"))) - bpy.types.Mesh.tbn_vecs = bpy.props.BoolProperty(name="TBN vectors", description="Compute tangent and binormal vectors for vertices", default=False) - bpy.types.Mesh.tbn_uvtex = bpy.props.StringProperty(name="TBN UV layer", description="UV layer to use as basis for TBN vectors", default="") + bpy.types.Mesh.tangent_vecs = bpy.props.BoolProperty(name="Tangent vectors", description="Compute tangent vectors for vertices", default=False) + bpy.types.Mesh.tangent_uvtex = bpy.props.StringProperty(name="Tangent UV layer", description="UV layer to use as basis for tangent vectors", default="") bpy.types.Object.compound = bpy.props.BoolProperty(name="Compound with parent", description="Join this object to its parent when exporting") bpy.types.Object.lod_for_parent = bpy.props.BoolProperty(name="LoD for parent", description="This object is a level of detail for its parent") diff --git a/shaderlib/common.glsl b/shaderlib/common.glsl index 54d66e60..8bc652fc 100644 --- a/shaderlib/common.glsl +++ b/shaderlib/common.glsl @@ -42,7 +42,7 @@ void standard_transform() out vec3 eye_normal = normal_tf*get_vertex_normal(); vec3 eye_tangent = normal_tf*tangent; - vec3 eye_binormal = normal_tf*binormal; + vec3 eye_binormal = cross(eye_normal, eye_tangent); out mat3 eye_tbn_matrix = mat3(eye_tangent, eye_binormal, eye_normal); out vec3 eye_look_dir = normalize(eye_vertex.xyz); diff --git a/shaderlib/msp_interface.glsl b/shaderlib/msp_interface.glsl index b86d09bb..fbbcec3b 100644 --- a/shaderlib/msp_interface.glsl +++ b/shaderlib/msp_interface.glsl @@ -42,11 +42,10 @@ layout(location=0) in vec4 vertex; layout(location=1) in vec4 color; layout(location=2) in vec3 normal; layout(location=3) in vec3 tangent; -layout(location=4) in vec3 binormal; -layout(location=7) in vec4 texcoord; -layout(location=8) in vec4 texcoord1; -layout(location=9) in vec4 texcoord2; -layout(location=10) in vec4 texcoord3; +layout(location=6) in vec4 texcoord; +layout(location=7) in vec4 texcoord1; +layout(location=8) in vec4 texcoord2; +layout(location=9) in vec4 texcoord3; layout(location=13) in vec4 instance_transform[3]; #pragma MSP stage(fragment) diff --git a/source/builders/box.cpp b/source/builders/box.cpp index 46f1b48e..1435c976 100644 --- a/source/builders/box.cpp +++ b/source/builders/box.cpp @@ -36,17 +36,14 @@ void BoxBuilder::build(PrimitiveBuilder &builder) const void BoxBuilder::build_face(PrimitiveBuilder &builder, const Vector3 &o, const Vector3 &s1, const Vector3 &s2) const { float l1 = 1, l2 = 1; - if(generate_tbn || tex_fit!=STRETCH) + if(generate_tan || tex_fit!=STRETCH) { l1 = s1.norm(); l2 = s2.norm(); } - if(generate_tbn) - { + if(generate_tan) builder.tangent(s1/l1); - builder.binormal(s2/l2); - } float u_size = 1; float v_size = 1; diff --git a/source/builders/capsule.cpp b/source/builders/capsule.cpp index 65a18eb3..a14e4ee5 100644 --- a/source/builders/capsule.cpp +++ b/source/builders/capsule.cpp @@ -43,11 +43,8 @@ void CapsuleBuilder::build(PrimitiveBuilder &builder) const float sc = cos(sa); float ss = sin(sa); builder.normal(rs*sc, rs*ss, -rc); - if(generate_tbn) - { + if(generate_tan) builder.tangent(-ss, sc, 0); - builder.binormal(rc*sc, rc*ss, rs); - } builder.texcoord(j*u_scale, v); builder.vertex(rs*sc*radius, rs*ss*radius, cz-rc*radius); } diff --git a/source/builders/cylinder.cpp b/source/builders/cylinder.cpp index 901a0f4b..e3a8342c 100644 --- a/source/builders/cylinder.cpp +++ b/source/builders/cylinder.cpp @@ -19,14 +19,12 @@ CylinderBuilder::CylinderBuilder(float r, float l, unsigned s): void CylinderBuilder::build(PrimitiveBuilder &builder) const { - if(generate_tbn) - builder.binormal(0, 1, 0); for(unsigned i=0; i<2; ++i) { float z = (i-0.5)*length; builder.normal(0, 0, i*2.0-1.0); builder.texcoord(0.5, 0.5); - if(generate_tbn) + if(generate_tan) builder.tangent((i ? 1 : -1), 0, 0); builder.vertex(0, 0, z); for(unsigned j=0; j + namespace Msp { namespace GL { @@ -18,13 +20,14 @@ public: }; protected: - bool generate_tbn; + bool generate_tan; TextureFit tex_fit; GeometryBuilder(); public: - GeometryBuilder &tbn(bool = true); + DEPRECATED GeometryBuilder &tbn(bool t = true) { return tangents(t); } + GeometryBuilder &tangents(bool = true); GeometryBuilder &texture_fit(TextureFit); protected: void adjust_texture_scale(float &, float &, float, float) const; diff --git a/source/builders/grid.cpp b/source/builders/grid.cpp index 3f4d5e2f..d812a2c2 100644 --- a/source/builders/grid.cpp +++ b/source/builders/grid.cpp @@ -75,11 +75,8 @@ void GridBuilder::build(PrimitiveBuilder &builder) const adjust_texture_scale(u_scale, v_scale, sqrt(l1_sq), l2); builder.normal(norm.x, norm.y, norm.z); - if(generate_tbn) - { + if(generate_tan) builder.tangent(side1); - builder.binormal(binorm); - } for(unsigned j=0; j<=v_div; ++j) { diff --git a/source/builders/sphere.cpp b/source/builders/sphere.cpp index dd27fad4..f7e06eb7 100644 --- a/source/builders/sphere.cpp +++ b/source/builders/sphere.cpp @@ -43,11 +43,8 @@ void UvSphereBuilder::build(PrimitiveBuilder &builder) const builder.normal(cv*cu, cv*su, sv); builder.texcoord(j*u_scale, i*v_scale); - if(generate_tbn) - { + if(generate_tan) builder.tangent(-su, cu, 0); - builder.binormal(-sv*cu, -sv*su, cv); - } builder.vertex(cv*cu*radius, cv*su*radius, sv*radius); } } diff --git a/source/builders/vertexbuilder.h b/source/builders/vertexbuilder.h index 5c297346..82827cb4 100644 --- a/source/builders/vertexbuilder.h +++ b/source/builders/vertexbuilder.h @@ -89,11 +89,11 @@ public: void tangent(const Vector3 &t) { attrib(get_attribute_semantic(TANGENT3), mtx*Vector4(t.x, t.y, t.z, 0)); } - void binormal(float x, float y, float z) - { binormal(Vector3(x, y, z)); } + DEPRECATED void binormal(float, float, float) + { } - void binormal(const Vector3 &b) - { attrib(get_attribute_semantic(BINORMAL3), mtx*Vector4(b.x, b.y, b.z, 0)); } + DEPRECATED void binormal(const Vector3 &) + { } void texcoord(float s) { texcoord(s, 0, 0, 1); } diff --git a/source/core/vertexarray.cpp b/source/core/vertexarray.cpp index da868c79..347e4259 100644 --- a/source/core/vertexarray.cpp +++ b/source/core/vertexarray.cpp @@ -74,8 +74,6 @@ VertexArray::Loader::Loader(VertexArray &a): add("generic", static_cast(&Loader::generic)); add("generic", static_cast(&Loader::generic)); add("generic", static_cast(&Loader::generic)); - add("tangent", static_cast(&Loader::tangent)); - add("binormal", static_cast(&Loader::binormal)); add("group", static_cast(&Loader::group)); add("group", static_cast(&Loader::group)); add("group", static_cast(&Loader::group)); @@ -104,8 +102,13 @@ VertexArray::Loader::Loader(VertexArray &a): add("generic2", static_cast(&Loader::generic)); add("generic3", static_cast(&Loader::generic)); add("generic4", static_cast(&Loader::generic)); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" add("tangent3", static_cast(&Loader::tangent)); add("binormal3", static_cast(&Loader::binormal)); + add("tangent", static_cast(&Loader::tangent)); + add("binormal", static_cast(&Loader::binormal)); +#pragma GCC diagnostic pop } } // namespace GL diff --git a/source/core/vertexformat.cpp b/source/core/vertexformat.cpp index 908da992..e529f4eb 100644 --- a/source/core/vertexformat.cpp +++ b/source/core/vertexformat.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -141,7 +142,10 @@ void operator>>(const LexicalConverter &conv, VertexAttribute &a) else if(str=="TANGENT3") a = TANGENT3; else if(str=="BINORMAL3") - a = BINORMAL3; + { + IO::print(IO::cerr, "BINORMAL3 attribute is deprecated\n"); + a = make_indexed_attribute(GENERIC3, 5); + } else if(!convert_attribute(str, "VERTEX", 2, 4, a, VERTEX2) && !convert_attribute(str, "GROUP", 1, 4, a, GROUP1) && !convert_attribute(str, "WEIGHT", 1, 4, a, WEIGHT1) && diff --git a/source/core/vertexformat.h b/source/core/vertexformat.h index 0dbde9f9..c7a2fcf1 100644 --- a/source/core/vertexformat.h +++ b/source/core/vertexformat.h @@ -26,20 +26,19 @@ enum VertexAttribute COLOR4_FLOAT, NORMAL3 = 18, TANGENT3 = 26, - BINORMAL3 = 34, - GROUP1 = 40, + GROUP1 = 32, GROUP2, GROUP3, GROUP4, - WEIGHT1 = 48, + WEIGHT1 = 40, WEIGHT2, WEIGHT3, WEIGHT4, - TEXCOORD1 = 56, + TEXCOORD1 = 48, TEXCOORD2, TEXCOORD3, TEXCOORD4, - GENERIC1 = 88, + GENERIC1 = 80, GENERIC2, GENERIC3, GENERIC4, -- 2.43.0