Add RenderTools::CalculateTangentFrame utility

This commit is contained in:
Wojtek Figat
2023-07-16 11:57:21 +02:00
parent 2645b69ec0
commit f0496d53e8
4 changed files with 43 additions and 55 deletions

View File

@@ -9,6 +9,7 @@
#include "Engine/Graphics/GPUContext.h"
#include "Engine/Graphics/GPUDevice.h"
#include "Engine/Graphics/RenderTask.h"
#include "Engine/Graphics/RenderTools.h"
#include "Engine/Level/Scene/Scene.h"
#include "Engine/Renderer/RenderList.h"
#include "Engine/Serialization/MemoryReadStream.h"
@@ -389,9 +390,7 @@ bool UpdateMesh(SkinnedMesh* mesh, MArray* verticesObj, MArray* trianglesObj, MA
Array<VB0SkinnedElementType> vb;
vb.Resize(vertexCount);
for (uint32 i = 0; i < vertexCount; i++)
{
vb[i].Position = vertices[i];
}
vb.Get()[i].Position = vertices[i];
if (normalsObj)
{
const auto normals = MCore::Array::GetAddress<Float3>(normalsObj);
@@ -400,42 +399,19 @@ bool UpdateMesh(SkinnedMesh* mesh, MArray* verticesObj, MArray* trianglesObj, MA
const auto tangents = MCore::Array::GetAddress<Float3>(tangentsObj);
for (uint32 i = 0; i < vertexCount; i++)
{
// Peek normal and tangent
const Float3 normal = normals[i];
const Float3 tangent = tangents[i];
// Calculate bitangent sign
Float3 bitangent = Float3::Normalize(Float3::Cross(normal, tangent));
byte sign = static_cast<byte>(Float3::Dot(Float3::Cross(bitangent, normal), tangent) < 0.0f ? 1 : 0);
// Set tangent frame
vb[i].Tangent = Float1010102(tangent * 0.5f + 0.5f, sign);
vb[i].Normal = Float1010102(normal * 0.5f + 0.5f, 0);
auto& v = vb.Get()[i];
RenderTools::CalculateTangentFrame(v.Normal, v.Tangent, normal, tangent);
}
}
else
{
for (uint32 i = 0; i < vertexCount; i++)
{
// Peek normal
const Float3 normal = normals[i];
// Calculate tangent
Float3 c1 = Float3::Cross(normal, Float3::UnitZ);
Float3 c2 = Float3::Cross(normal, Float3::UnitY);
Float3 tangent;
if (c1.LengthSquared() > c2.LengthSquared())
tangent = c1;
else
tangent = c2;
// Calculate bitangent sign
Float3 bitangent = Float3::Normalize(Float3::Cross(normal, tangent));
byte sign = static_cast<byte>(Float3::Dot(Float3::Cross(bitangent, normal), tangent) < 0.0f ? 1 : 0);
// Set tangent frame
vb[i].Tangent = Float1010102(tangent * 0.5f + 0.5f, sign);
vb[i].Normal = Float1010102(normal * 0.5f + 0.5f, 0);
auto& v = vb.Get()[i];
RenderTools::CalculateTangentFrame(v.Normal, v.Tangent, normal);
}
}
}