From 08eb93e42aee37b307abeb0c52517acbe98827f4 Mon Sep 17 00:00:00 2001 From: Andreas Atteneder Date: Tue, 25 Feb 2020 01:19:38 +0100 Subject: [PATCH] Improvement: Normals and tangents (if not present) are only calculated if the assigned material actually requires them. --- ChangeLog.md | 4 ++++ Runtime/Scripts/GltFast.cs | 3 +++ Runtime/Scripts/PrimitiveCreateContext.cs | 9 ++++----- Runtime/Scripts/PrimitiveCreateContextBase.cs | 2 ++ Runtime/Scripts/PrimitiveDracoCreateContext.cs | 4 ++-- Runtime/Scripts/Schema/Material.cs | 12 ++++++++++++ Runtime/Scripts/Schema/MeshPrimitive.cs | 2 +- 7 files changed, 28 insertions(+), 8 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 4c349fe0..ba1b7f90 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Changed +- Normals and tangents (if not present) are only calculated if the assigned material actually requires them. + ## [0.10.1] - 2020-02-24 ### Added - Experimental KTX / Basis Universal support was merged (off by default) diff --git a/Runtime/Scripts/GltFast.cs b/Runtime/Scripts/GltFast.cs index 9af4b010..d2215f51 100644 --- a/Runtime/Scripts/GltFast.cs +++ b/Runtime/Scripts/GltFast.cs @@ -1127,6 +1127,9 @@ void CreatePrimitiveContexts( Root gltf ) { } context.primtiveIndex = i; context.materials[primIndex] = primitive.material; + + context.needsNormals |= primitive.material<0 || gltf.materials[primitive.material].requiresNormals; + context.needsTangents |= primitive.material>=0 && gltf.materials[primitive.material].requiresTangents; } primitiveContexts[i] = context; diff --git a/Runtime/Scripts/PrimitiveCreateContext.cs b/Runtime/Scripts/PrimitiveCreateContext.cs index 66f4703d..d5a646ca 100644 --- a/Runtime/Scripts/PrimitiveCreateContext.cs +++ b/Runtime/Scripts/PrimitiveCreateContext.cs @@ -72,8 +72,10 @@ public override bool IsCompleted { if(normals!=null) { msh.normals = normals; } else - if(topology==MeshTopology.Triangles || topology==MeshTopology.Quads) { + if( needsNormals && ( topology==MeshTopology.Triangles || topology==MeshTopology.Quads ) ) { + Profiler.BeginSample("RecalculateNormals"); msh.RecalculateNormals(); + Profiler.EndSample(); } Profiler.EndSample(); Profiler.BeginSample("SetColor"); @@ -87,15 +89,12 @@ public override bool IsCompleted { if(tangents!=null) { msh.tangents = tangents; } else - if(topology==MeshTopology.Triangles || topology==MeshTopology.Quads) { - // TODO: Improvement idea: by only calculating tangents, if they are actually needed + if( needsTangents && uvs0!=null && (topology==MeshTopology.Triangles || topology==MeshTopology.Quads) ) { Profiler.BeginSample("RecalculateTangents"); msh.RecalculateTangents(); Profiler.EndSample(); } Profiler.EndSample(); - // primitives[c.primtiveIndex] = new Primitive(msh,c.primitive.material); - // resources.Add(msh); Profiler.BeginSample("Dispose"); Dispose(); diff --git a/Runtime/Scripts/PrimitiveCreateContextBase.cs b/Runtime/Scripts/PrimitiveCreateContextBase.cs index a9b14ef8..3a9c2726 100644 --- a/Runtime/Scripts/PrimitiveCreateContextBase.cs +++ b/Runtime/Scripts/PrimitiveCreateContextBase.cs @@ -7,6 +7,8 @@ namespace GLTFast { abstract class PrimitiveCreateContextBase { public int primtiveIndex; public int[] materials; + public bool needsNormals; + public bool needsTangents; public abstract bool IsCompleted {get;} public abstract Primitive? CreatePrimitive(); } diff --git a/Runtime/Scripts/PrimitiveDracoCreateContext.cs b/Runtime/Scripts/PrimitiveDracoCreateContext.cs index 4a306137..a6cb4c6d 100644 --- a/Runtime/Scripts/PrimitiveDracoCreateContext.cs +++ b/Runtime/Scripts/PrimitiveDracoCreateContext.cs @@ -38,13 +38,13 @@ public override bool IsCompleted { var mesh = DracoMeshLoader.CreateMesh(dracoMesh, out hasNormals, out hasTexcoords); Profiler.EndSample(); - if(!hasNormals) { + if(needsNormals && !hasNormals) { Profiler.BeginSample("Draco.RecalculateNormals"); // TODO: Make optional. Only calculate if actually needed mesh.RecalculateNormals(); Profiler.EndSample(); } - if(hasTexcoords) { + if(needsTangents && hasTexcoords) { Profiler.BeginSample("Draco.RecalculateTangents"); // TODO: Make optional. Only calculate if actually needed mesh.RecalculateTangents(); diff --git a/Runtime/Scripts/Schema/Material.cs b/Runtime/Scripts/Schema/Material.cs index c04e9c77..632a5bed 100644 --- a/Runtime/Scripts/Schema/Material.cs +++ b/Runtime/Scripts/Schema/Material.cs @@ -115,5 +115,17 @@ public AlphaMode alphaModeEnum { /// lighting equation is evaluated. /// public bool doubleSided = false; + + public bool requiresNormals { + get { + return extensions==null || extensions.KHR_materials_unlit==null; + } + } + + public bool requiresTangents { + get { + return normalTexture!=null && normalTexture.index>=0; + } + } } } \ No newline at end of file diff --git a/Runtime/Scripts/Schema/MeshPrimitive.cs b/Runtime/Scripts/Schema/MeshPrimitive.cs index 5829b29a..ea4087f6 100644 --- a/Runtime/Scripts/Schema/MeshPrimitive.cs +++ b/Runtime/Scripts/Schema/MeshPrimitive.cs @@ -36,7 +36,7 @@ public class MeshPrimitive { /// /// The index of the material to apply to this primitive when rendering. /// - public int material; + public int material = -1; /// /// The type of primitives to render. All valid values correspond to WebGL enums.