Add support for up to 4 texture channels when importing meshes

#2667
This commit is contained in:
Wojtek Figat
2025-01-11 22:40:20 +01:00
parent 756ba0a533
commit a1c46d2e6e
31 changed files with 427 additions and 475 deletions

View File

@@ -562,11 +562,13 @@ bool ModelBase::SaveLOD(WriteStream& stream, const ModelData& modelData, int32 l
LOG(Warning, "Cannot save model with empty meshes.");
return true;
}
bool hasUVs = mesh.UVs.HasItems();
if (hasUVs && (uint32)mesh.UVs.Count() != vertices)
for (auto& channel : mesh.UVs)
{
LOG(Error, "Invalid size of {0} stream.", TEXT("UVs"));
return true;
if ((uint32)channel.Count() != vertices)
{
LOG(Error, "Invalid size of {0} stream.", TEXT("UVs"));
return true;
}
}
bool hasNormals = mesh.Normals.HasItems();
if (hasNormals && (uint32)mesh.Normals.Count() != vertices)
@@ -586,12 +588,6 @@ bool ModelBase::SaveLOD(WriteStream& stream, const ModelData& modelData, int32 l
LOG(Error, "Invalid size of {0} stream.", TEXT("BitangentSigns"));
return true;
}
bool hasLightmapUVs = mesh.LightmapUVs.HasItems();
if (hasLightmapUVs && (uint32)mesh.LightmapUVs.Count() != vertices)
{
LOG(Error, "Invalid size of {0} stream.", TEXT("LightmapUVs"));
return true;
}
bool hasColors = mesh.Colors.HasItems();
if (hasColors && (uint32)mesh.Colors.Count() != vertices)
{
@@ -626,7 +622,6 @@ bool ModelBase::SaveLOD(WriteStream& stream, const ModelData& modelData, int32 l
byte vbIndex = 0;
// TODO: add option to quantize vertex positions (eg. 16-bit)
// TODO: add option to quantize vertex attributes (eg. 8-bit blend weights, 8-bit texcoords)
// TODO: add support for 16-bit blend indices (up to 65535 bones)
// Position
if (useSeparatePositions)
@@ -641,10 +636,14 @@ bool ModelBase::SaveLOD(WriteStream& stream, const ModelData& modelData, int32 l
auto& vb = vbElements.AddOne();
if (!useSeparatePositions)
vb.Add({ VertexElement::Types::Position, vbIndex, 0, 0, PixelFormat::R32G32B32_Float });
if (hasUVs)
vb.Add({ VertexElement::Types::TexCoord, vbIndex, 0, 0, PixelFormat::R16G16_Float });
if (hasLightmapUVs)
vb.Add({ VertexElement::Types::TexCoord1, vbIndex, 0, 0, PixelFormat::R16G16_Float });
for (int32 channelIdx = 0; channelIdx < mesh.UVs.Count(); channelIdx++)
{
auto& channel = mesh.UVs.Get()[channelIdx];
if (channel.HasItems())
{
vb.Add({ (VertexElement::Types)((int32)VertexElement::Types::TexCoord0 + channelIdx), vbIndex, 0, 0, PixelFormat::R16G16_Float });
}
}
vb.Add({ VertexElement::Types::Normal, vbIndex, 0, 0, PixelFormat::R10G10B10A2_UNorm });
vb.Add({ VertexElement::Types::Tangent, vbIndex, 0, 0, PixelFormat::R10G10B10A2_UNorm });
if (isSkinned)
@@ -745,20 +744,16 @@ bool ModelBase::SaveLOD(WriteStream& stream, const ModelData& modelData, int32 l
break;
}
case VertexElement::Types::TexCoord0:
case VertexElement::Types::TexCoord1:
case VertexElement::Types::TexCoord2:
case VertexElement::Types::TexCoord3:
{
const Float2 uv = hasUVs ? mesh.UVs.Get()[vertex] : Float2::Zero;
const int32 channelIdx = (int32)element.Type - (int32)VertexElement::Types::TexCoord0;
const Float2 uv = mesh.UVs.Get()[channelIdx].Get()[vertex];
const Half2 uvEnc(uv);
stream.Write(uvEnc);
break;
}
case VertexElement::Types::TexCoord1:
{
// TODO: refactor LightmapUVs into a generic TexCoord channel and support up to 4 UVs
const Float2 lightmapUV = hasLightmapUVs ? mesh.LightmapUVs.Get()[vertex] : Float2::Zero;
const Half2 lightmapUVEnc(lightmapUV);
stream.Write(lightmapUVEnc);
break;
}
default:
LOG(Error, "Unsupported vertex element: {}", element.ToString());
return true;

View File

@@ -6,17 +6,17 @@
#include "Engine/Engine/Engine.h"
#include "Engine/Serialization/MemoryReadStream.h"
#include "Engine/Streaming/StreamingGroup.h"
#include "Engine/Threading/ThreadPoolTask.h"
#include "Engine/Threading/Threading.h"
#include "Engine/Graphics/RenderTools.h"
#include "Engine/Graphics/RenderTask.h"
#include "Engine/Graphics/Models/ModelInstanceEntry.h"
#include "Engine/Graphics/Models/Config.h"
#include "Engine/Graphics/Models/MeshDeformation.h"
#include "Engine/Graphics/Models/ModelInstanceEntry.h"
#include "Engine/Graphics/Shaders/GPUVertexLayout.h"
#include "Engine/Content/Content.h"
#include "Engine/Content/Factories/BinaryAssetFactory.h"
#include "Engine/Content/Upgraders/SkinnedModelAssetUpgrader.h"
#include "Engine/Debug/Exceptions/ArgumentOutOfRangeException.h"
#include "Engine/Graphics/Models/MeshDeformation.h"
#include "Engine/Profiler/ProfilerCPU.h"
#include "Engine/Renderer/DrawCall.h"
#if USE_EDITOR