diff --git a/FModel/Resources/default.frag b/FModel/Resources/default.frag index 458fa27f..7603e37f 100644 --- a/FModel/Resources/default.frag +++ b/FModel/Resources/default.frag @@ -99,8 +99,8 @@ void main() vec3 reflect_direction = reflect(-n_light_direction, n_normal_map); float metallic = pow(max(dot(n_view_direction, reflect_direction), 0.0f), material.metallic_value); vec3 specular_map = vec3(getValueFromSamplerArray(material.specularMap)); - result += specular_map.r * light.specular * (metallic * specular_map.b); - result += material.roughness_value * specular_map.g; + result += specular_map.r * light.specular * (metallic * specular_map.g); + result += material.roughness_value * specular_map.b; } // emission diff --git a/FModel/Views/Snooper/Cube.cs b/FModel/Views/Snooper/Cube.cs index 4f315085..8b8674a2 100644 --- a/FModel/Views/Snooper/Cube.cs +++ b/FModel/Views/Snooper/Cube.cs @@ -62,10 +62,10 @@ public class Cube : Model }; Materials = new Material[1]; - Materials[0] = new Material(1, unrealMaterial); + Materials[0] = new Material(1, unrealMaterial) { IsUsed = true }; Sections = new Section[1]; - Sections[0] = new Section(0, Indices.Length, 0, Materials[0]); + Sections[0] = new Section(0, Indices.Length, 0); AddInstance(Transform.Identity); } diff --git a/FModel/Views/Snooper/Material.cs b/FModel/Views/Snooper/Material.cs index 459cfe79..8b5f4c72 100644 --- a/FModel/Views/Snooper/Material.cs +++ b/FModel/Views/Snooper/Material.cs @@ -16,6 +16,7 @@ public class Material : IDisposable public readonly CMaterialParams2 Parameters; public readonly int UvNumber; + public bool IsUsed; public Texture[] Diffuse; public Texture[] Normals; @@ -29,14 +30,15 @@ public class Material : IDisposable public Material() { + Parameters = new CMaterialParams2(); DiffuseColor = Vector4.Zero; EmissionColor = Vector4.Zero; + IsUsed = false; } public Material(int numUvs, UMaterialInterface unrealMaterial) : this() { UvNumber = numUvs; - Parameters = new CMaterialParams2(); SwapMaterial(unrealMaterial); } diff --git a/FModel/Views/Snooper/Model.cs b/FModel/Views/Snooper/Model.cs index f9c9f24a..5dee6086 100644 --- a/FModel/Views/Snooper/Model.cs +++ b/FModel/Views/Snooper/Model.cs @@ -78,8 +78,9 @@ public class Model : IDisposable Materials = new Material[materials.Length]; for (int m = 0; m < Materials.Length; m++) { - if (materials[m].TryLoad(out var material) && material is UMaterialInterface unrealMaterial) - Materials[m] = new Material(lod.NumTexCoords, unrealMaterial); // lod.NumTexCoords + if ((materials[m]?.TryLoad(out var material) ?? false) && material is UMaterialInterface unrealMaterial) + Materials[m] = new Material(lod.NumTexCoords, unrealMaterial); + else Materials[m] = new Material(); } if (lod.VertexColors is { Length: > 0}) @@ -103,7 +104,8 @@ public class Model : IDisposable for (var s = 0; s < sections.Length; s++) { var section = sections[s]; - Sections[s] = new Section(section.MaterialIndex, section.NumFaces * _faceSize, section.FirstIndex, Materials[section.MaterialIndex]); + Materials[section.MaterialIndex].IsUsed = true; + Sections[s] = new Section(section.MaterialIndex, section.NumFaces * _faceSize, section.FirstIndex); for (uint face = 0; face < section.NumFaces; face++) { foreach (var f in _facesIndex) @@ -202,6 +204,7 @@ public class Model : IDisposable { // setup all materials for use in different UV channels for (var i = 0; i < Materials.Length; i++) { + if (!Materials[i].IsUsed) continue; Materials[i].Setup(cache); } } @@ -221,7 +224,7 @@ public class Model : IDisposable for (int section = 0; section < Sections.Length; section++) { - Sections[section].Setup(cache); + Sections[section].Setup(); } IsSetup = true; @@ -235,12 +238,18 @@ public class Model : IDisposable GL.StencilFunc(StencilFunction.Always, 1, 0xFF); } + for (var i = 0; i < Materials.Length; i++) + { + if (!Materials[i].IsUsed) continue; + Materials[i].Render(shader); + } + _vao.Bind(); shader.SetUniform("uMorphTime", MorphTime); shader.SetUniform("display_vertex_colors", DisplayVertexColors); for (int section = 0; section < Sections.Length; section++) { - Sections[section].Render(shader, TransformsCount); + Sections[section].Render(TransformsCount); } _vao.Unbind(); diff --git a/FModel/Views/Snooper/Renderer.cs b/FModel/Views/Snooper/Renderer.cs index c28f889b..c827ed45 100644 --- a/FModel/Views/Snooper/Renderer.cs +++ b/FModel/Views/Snooper/Renderer.cs @@ -46,7 +46,7 @@ public class Renderer : IDisposable if (!Cache.TryGetModel(Settings.SelectedModel, out var model) || !Settings.TryGetSection(model, out var section)) return; - section.Material.SwapMaterial(unrealMaterial); + model.Materials[section.MaterialIndex].SwapMaterial(unrealMaterial); Settings.SwapMaterial(false); } @@ -181,22 +181,23 @@ public class Renderer : IDisposable { for (int j = 0; j < textureData.Length; j++) { - if (textureData[j].Load() is not { } textureDataIdx) + if (!model.Materials[model.Sections[j].MaterialIndex].IsUsed || + textureData[j].Load() is not { } textureDataIdx) continue; if (textureDataIdx.TryGetValue(out FPackageIndex overrideMaterial, "OverrideMaterial") && overrideMaterial.TryLoad(out var material) && material is UMaterialInterface unrealMaterial) - unrealMaterial.GetParams(model.Sections[j].Material.Parameters); + model.Materials[model.Sections[j].MaterialIndex].SwapMaterial(unrealMaterial); if (textureDataIdx.TryGetValue(out FPackageIndex diffuse, "Diffuse") && diffuse.Load() is UTexture2D diffuseTexture) - model.Sections[j].Material.Parameters.Textures[CMaterialParams2.Diffuse[0]] = diffuseTexture; + model.Materials[model.Sections[j].MaterialIndex].Parameters.Textures[CMaterialParams2.Diffuse[0]] = diffuseTexture; if (textureDataIdx.TryGetValue(out FPackageIndex normal, "Normal") && normal.Load() is UTexture2D normalTexture) - model.Sections[j].Material.Parameters.Textures[CMaterialParams2.Normals[0]] = normalTexture; + model.Materials[model.Sections[j].MaterialIndex].Parameters.Textures[CMaterialParams2.Normals[0]] = normalTexture; if (textureDataIdx.TryGetValue(out FPackageIndex specular, "Specular") && specular.Load() is UTexture2D specularTexture) - model.Sections[j].Material.Parameters.Textures[CMaterialParams2.SpecularMasks[0]] = specularTexture; + model.Materials[model.Sections[j].MaterialIndex].Parameters.Textures[CMaterialParams2.SpecularMasks[0]] = specularTexture; } } if (staticMeshComp.TryGetValue(out FPackageIndex[] overrideMaterials, "OverrideMaterials")) @@ -205,8 +206,9 @@ public class Renderer : IDisposable for (var j = 0; j < overrideMaterials.Length; j++) { if (j > max) break; - if (overrideMaterials[j].Load() is not UMaterialInterface unrealMaterial) continue; - model.Sections[j].Material.SwapMaterial(unrealMaterial); + if (!model.Materials[model.Sections[j].MaterialIndex].IsUsed || + overrideMaterials[j].Load() is not UMaterialInterface unrealMaterial) continue; + model.Materials[model.Sections[j].MaterialIndex].SwapMaterial(unrealMaterial); } } diff --git a/FModel/Views/Snooper/Section.cs b/FModel/Views/Snooper/Section.cs index 0c0475e0..b53dfc3b 100644 --- a/FModel/Views/Snooper/Section.cs +++ b/FModel/Views/Snooper/Section.cs @@ -7,38 +7,28 @@ public class Section : IDisposable { private int _handle; - public readonly int Index; + public readonly int MaterialIndex; public readonly int FacesCount; public readonly int FirstFaceIndex; - public readonly Material Material; public bool Show; public bool Wireframe; - private Section(int index, int facesCount, int firstFaceIndex) + public Section(int index, int facesCount, int firstFaceIndex) { - Index = index; + MaterialIndex = index; FacesCount = facesCount; FirstFaceIndex = firstFaceIndex; Show = true; } - public Section(int index, int facesCount, int firstFaceIndex, Material material) : this(index, facesCount, firstFaceIndex) - { - Material = material; - } - - public void Setup(Cache cache) + public void Setup() { _handle = GL.CreateProgram(); - - Material.Setup(cache); } - public void Render(Shader shader, int instanceCount) + public void Render(int instanceCount) { - Material.Render(shader); - GL.PolygonMode(MaterialFace.FrontAndBack, Wireframe ? PolygonMode.Line : PolygonMode.Fill); if (Show) GL.DrawArraysInstanced(PrimitiveType.Triangles, FirstFaceIndex, FacesCount, instanceCount); }