Procedural Mesh Component Lighting Issue

I’m having some issues with lighting when I’m using the procedural mesh component in C++.

I’ve tried all kinds of debugging and fixes like winding order and normals/tangent normals double sided faces, among other things, and can’t seem to find the solution to this issue. Long story short, if I’m generating anything more complex than a simple plane, this strange lighting issue happens on faces where all the vectors are axis aligned (like a plane that sits on the Z axis that is part of a larger generated mesh). The best way I know how to describe it is it’s as if the lighting has been “flipped”. Here’s 2 images to demonstrate what I mean:


By rotating the directional light you can see how other faces are acting normally but this z axis aligned face seems “backwards” or “reversed” even though the normals and winding order are all correct.

I first noticed this under different lighting conditions that included a skylight and such and the walls appeared to be sort “reflective” like this Y axis aligned set of faces in this example:

I also find it strange because I can generate a simple plane that is axis aligned and everything looks as I’d expect but when I generate larger “3-dimensional” structures like cubes/spheres/etc that make use of multiple axis that’s when the issue begins even if you isolate the generation of the single face:

I tried to dumb it down to see if I could resolve the issue but the issue persists even when I only generate 3 planes each axis aligned:

I do however find this example interesting as it may provide a clue to fixing it since the Z-axis aligned plane is behaving normally whereas the x and y axis aligned planes are producing this weird lighting glitch.

Does anyone have any idea why this is happening or any suggestions of fixing it?

void AProcGenPlane::GenerateThreePlaneMesh()
{
Vertices.Empty();
Triangles.Empty();

// Plane size (1m x 1m, centered at 0,0,0)
const float HalfSize = 50.0f; // 1m wide (50 units per side)

// Define plane normals
FVector PlaneNormals[3] = {
    FVector(0, 0, 1),  // XY Plane (Ground Plane)
    FVector(0, 1, 0),  // XZ Plane (Front Plane)
    FVector(1, 0, 0)   // YZ Plane (Side Plane)
};

// Define right and up vectors for each plane
FVector RightVectors[3] = {
    FVector(1, 0, 0), FVector(1, 0, 0), FVector(0, 0, 1)
};

FVector UpVectors[3] = {
    FVector(0, 1, 0), FVector(0, 0, 1), FVector(0, 1, 0)
};

int32 VertexOffset = 0;

// Generate 3 axis-aligned planes
for (int32 PlaneIndex = 0; PlaneIndex < 3; PlaneIndex++)
{
    FVector Normal = PlaneNormals[PlaneIndex];
    FVector Right = RightVectors[PlaneIndex];
    FVector Up = UpVectors[PlaneIndex];

    // Define 4 vertices of the plane
    FVector V1 = (-HalfSize * Right) + (-HalfSize * Up);
    FVector V2 = (HalfSize * Right) + (-HalfSize * Up);
    FVector V3 = (-HalfSize * Right) + (HalfSize * Up);
    FVector V4 = (HalfSize * Right) + (HalfSize * Up);

    // Add vertices to mesh
    int32 V1Index = Vertices.Add(V1);
    int32 V2Index = Vertices.Add(V2);
    int32 V3Index = Vertices.Add(V3);
    int32 V4Index = Vertices.Add(V4);

    // Create two triangles for the plane
    AddTriangle(V1Index, V3Index, V2Index);
    AddTriangle(V2Index, V3Index, V4Index);
}

// Empty arrays
TArray<FVector> Normals;
TArray<FVector2D> UVs;
TArray<FProcMeshTangent> Tangents;
TArray<FLinearColor> VertexColors;

// Create the mesh section
ProcMeshPlane->CreateMeshSection_LinearColor(0, Vertices, Triangles, Normals, UVs, VertexColors, Tangents, true);

}

If I can find a solution for this simple example I think I can apply it to my more complex examples. Any help would be appreciated! Can’t think of what might be doing this so figured I’d reach out to the community.