Add and use Max Mesh Position Error to Build Settings for automatic mesh vertex positions storage
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include "ModelBase.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Math/Transform.h"
|
||||
#include "Engine/Core/Config/BuildSettings.h"
|
||||
#include "Engine/Content/WeakAssetReference.h"
|
||||
#include "Engine/Serialization/MemoryReadStream.h"
|
||||
#include "Engine/Profiler/ProfilerMemory.h"
|
||||
@@ -666,11 +667,42 @@ bool ModelBase::SaveLOD(WriteStream& stream, const ModelData& modelData, int32 l
|
||||
return true;
|
||||
}
|
||||
|
||||
// Process mesh data if need to decide vertex buffer on format dynamically
|
||||
auto positionFormat = modelData.PositionFormat;
|
||||
if (positionFormat == ModelData::PositionFormats::Automatic)
|
||||
{
|
||||
const float maxPositionError = BuildSettings::Get()->MaxMeshPositionError; // In world-units
|
||||
const float maxPositionErrorSq = maxPositionError * maxPositionError;
|
||||
if (maxPositionErrorSq > 0.0f)
|
||||
{
|
||||
positionFormat = ModelData::PositionFormats::Float16;
|
||||
const Float3* positions = mesh.Positions.Get();
|
||||
for (int32 i = 0; i < mesh.Positions.Count(); i++)
|
||||
{
|
||||
// Encode to Half3 and decode back to see the position error
|
||||
Float3 position = positions[i];
|
||||
Half3 encoded(position);
|
||||
Float3 decoded = encoded.ToFloat3();
|
||||
if (Float3::DistanceSquared(position, decoded) > maxPositionErrorSq)
|
||||
{
|
||||
// Cannot use lower quality so go back to full precision
|
||||
positionFormat = ModelData::PositionFormats::Float32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Full precision as default
|
||||
positionFormat = ModelData::PositionFormats::Float32;
|
||||
}
|
||||
}
|
||||
|
||||
// Define vertex buffers layout and packing
|
||||
Array<GPUVertexLayout::Elements, FixedAllocation<MODEL_MAX_VB>> vbElements;
|
||||
const bool useSeparatePositions = !isSkinned;
|
||||
const bool useSeparateColors = !isSkinned;
|
||||
PixelFormat positionsFormat = modelData.PositionFormat == ModelData::PositionFormats::Float32 ? PixelFormat::R32G32B32_Float : PixelFormat::R16G16B16A16_Float;
|
||||
PixelFormat positionsFormat = positionFormat == ModelData::PositionFormats::Float32 ? PixelFormat::R32G32B32_Float : PixelFormat::R16G16B16A16_Float;
|
||||
PixelFormat texCoordsFormat = modelData.TexCoordFormat == ModelData::TexCoordFormats::Float16 ? PixelFormat::R16G16_Float : PixelFormat::R8G8_UNorm;
|
||||
PixelFormat blendIndicesFormat = PixelFormat::R8G8B8A8_UInt;
|
||||
PixelFormat blendWeightsFormat = PixelFormat::R8G8B8A8_UNorm;
|
||||
@@ -684,7 +716,6 @@ bool ModelBase::SaveLOD(WriteStream& stream, const ModelData& modelData, int32 l
|
||||
}
|
||||
{
|
||||
byte vbIndex = 0;
|
||||
// TODO: add option to quantize vertex attributes (eg. 8-bit blend weights, 8-bit texcoords)
|
||||
|
||||
// Position
|
||||
if (useSeparatePositions)
|
||||
|
||||
Reference in New Issue
Block a user