per used material render call

This commit is contained in:
4sval 2022-10-27 20:44:03 +02:00
parent 12eba5e730
commit 3d1d125e40
6 changed files with 36 additions and 33 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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);
}