Skip to content
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
##### Fixes :wrench:

- Corrected glTF import process to flip textures and UV coordinates from glTF's U-right, V-down convention to comply with Unity's U-right, V-up coordinate system.
- Modified model importer to include tangents when they are present in the source glTF.

## v1.18.1 - 2025-10-01

Expand Down
41 changes: 38 additions & 3 deletions native~/Runtime/src/UnityPrepareRendererResources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,15 @@ void loadPrimitive(
computeFlatNormals = hasNormals = true;
}

bool hasTangents = false;
auto tangentAcccessorIt = primitive.attributes.find("TANGENT");
AccessorView<UnityEngine::Vector4> tangentView;
if (tangentAcccessorIt != primitive.attributes.end()) {
tangentView =
AccessorView<UnityEngine::Vector4>(gltf, tangentAcccessorIt->second);
hasTangents = tangentView.status() == AccessorViewStatus::Valid;
}

// Check if we need to upgrade to a large index type to accommodate the
// larger number of vertices we need for flat normals.
if (computeFlatNormals && indexFormat == IndexFormat::UInt16 &&
Expand Down Expand Up @@ -450,6 +459,15 @@ void loadPrimitive(
++numberOfAttributes;
}

if (hasTangents) {
assert(numberOfAttributes < MAX_ATTRIBUTES);
descriptor[numberOfAttributes].attribute = VertexAttribute::Tangent;
descriptor[numberOfAttributes].format = VertexAttributeFormat::Float32;
descriptor[numberOfAttributes].dimension = 4;
descriptor[numberOfAttributes].stream = streamIndex;
++numberOfAttributes;
}

// Add the COLOR_0 attribute, if it exists.
auto colorAccessorIt = primitive.attributes.find("COLOR_0");
bool hasVertexColors =
Expand Down Expand Up @@ -571,19 +589,27 @@ void loadPrimitive(
// The vertex layout will be as follows:
// 1. position
// 2. normals (skip if N/A)
// 3. vertex colors (skip if N/A)
// 4. texcoords (first all TEXCOORD_i, then all _CESIUMOVERLAY_i)
// 3. tangents (skip if N/A)
// 4. vertex colors (skip if N/A)
// 5. texcoords (first all TEXCOORD_i, then all _CESIUMOVERLAY_i)

size_t stride = sizeof(Vector3);
size_t normalByteOffset, colorByteOffset;
size_t normalByteOffset;
if (hasNormals) {
normalByteOffset = stride;
stride += sizeof(Vector3);
}

if (hasTangents) {
stride += sizeof(Vector4);
}

size_t colorByteOffset;
if (hasVertexColors) {
colorByteOffset = stride;
stride += sizeof(uint32_t);
}

stride += numTexCoords * sizeof(Vector2);

if (computeFlatNormals) {
Expand All @@ -593,11 +619,16 @@ void loadPrimitive(
indices,
indexCount,
positionView);

for (int64_t i = 0; i < vertexCount; ++i) {
TIndex vertexIndex = indices[i];
*reinterpret_cast<Vector3*>(pWritePos) = positionView[vertexIndex];
// skip position and normal
pWritePos += 2 * sizeof(Vector3);
if (hasTangents) {
*reinterpret_cast<Vector4*>(pWritePos) = tangentView[vertexIndex];
pWritePos += sizeof(Vector4);
}
// Skip the slot allocated for vertex colors, we will fill them in
// bulk later.
if (hasVertexColors) {
Expand All @@ -620,6 +651,10 @@ void loadPrimitive(
*reinterpret_cast<Vector3*>(pWritePos) = normalView[i];
pWritePos += sizeof(Vector3);
}
if (hasTangents) {
*reinterpret_cast<Vector4*>(pWritePos) = tangentView[i];
pWritePos += sizeof(Vector4);
}
// Skip the slot allocated for vertex colors, we will fill them in
// bulk later.
if (hasVertexColors) {
Expand Down