# UE4 - UProceduralMeshComponent - texturing issues

I am having a lot of trouble texturing a procedural mesh in UE4. I am using perlin noise from Accidental Noise Library with PolyVox to generate randomized marching cube terrain.

Accidental Noise Library: https://github.com/LtBrandon/accidental-noise-library PolyVox: https://bitbucket.org/volumesoffun/polyvox/src/develop/

I've tried to make a Triplanar material, and it seems to work great when I apply it to an imported mesh:

When I apply it to my randomly generated procedural mesh however, I see the following:

I have a suspicion that my issue is either UV0 or Normals but I just do not understand this issue enough to effectively troubleshoot. Here is the code for the important part of generation for my mesh. I'm not including a lot for brevity sake, please let me know if you need to see includes and whatnot:

ProceduralTerrainActor.h

// This is very truncated for brevity sake please let me know if you'd like to see more of this file
public:
UPROPERTY(Category = "Voxel Terrain - Terrain Settings", BlueprintReadWrite, EditAnywhere) UMaterialInterface* Material;

private:
TSharedPtr<PolyVox::PagedVolume<PolyVox::MaterialDensityPair88>> VoxelVolume;


ProceduralTerrainActor.cpp

bool AProceduralTerrainActor::GenerateChunk(int32 X, int32 Y, int32 Z) {

int32 ChunkSize = 64;
// The offset is important if I want to create more than one chunk
int32 OffsetX = (X * ChunkSize);
int32 OffsetY = (Y * ChunkSize);
int32 OffsetZ = (Z * ChunkSize);

//PolyVox does its magic
PolyVox::Region ToExtract(Vector3DInt32(OffsetX, OffsetY, OffsetZ), Vector3DInt32(OffsetX + ChunkSize, OffsetY + ChunkSize, OffsetZ + ChunkSize));

auto ExtractedMesh = extractMarchingCubesMesh(VoxelVolume.Get(), ToExtract);
auto DecodedMesh = decodeMesh(ExtractedMesh);
if (DecodedMesh.getNoOfIndices() == 0) {
return false;
}

//Creating my mesh
FGuid UniqueIdentifier = FGuid::NewGuid();
FString MeshName = "VoxelMesh_" + UniqueIdentifier.ToString();
UProceduralMeshComponent* Mesh = NewObject<UProceduralMeshComponent>(this, FName(*FString::Printf(TEXT("VoxelMesh_%s"), *MeshName)));

Mesh->RegisterComponent();
Mesh->AttachToComponent(GetRootComponent(), FAttachmentTransformRules(EAttachmentRule::KeepRelative, false));
Mesh->SetMaterial(0, Material);

auto Vertices = TArray<FVector>();
auto Indices = TArray<int32>();
auto Normals = TArray<FVector>();
auto UV0 = TArray<FVector2D>(); // I know for sure I'm calculating these incorrectly
auto Colors = TArray<FColor>(); // I'm not calculating these yet as I don't know how
auto Tangents = TArray<FProcMeshTangent>();

FVector OffsetLocation(OffsetX, OffsetY, OffsetZ);

// Loop over all of the triangle vertex indices
for (uint32 i = 0; i < DecodedMesh.getNoOfIndices() - 2; i += 3)
{
// We need to add the vertices of each triangle in reverse or the mesh will be upside down
auto Index = DecodedMesh.getIndex(i + 2);
auto Vertex2 = DecodedMesh.getVertex(Index);
auto TriangleMaterial = Vertex2.data.getMaterial();

Index = DecodedMesh.getIndex(i + 1);
auto Vertex1 = DecodedMesh.getVertex(Index);

Index = DecodedMesh.getIndex(i);
auto Vertex0 = DecodedMesh.getVertex(Index);

// Calculate the tangents of our triangle
const FVector Edge01 = FPolyVoxVector(Vertex1.position - Vertex0.position);
const FVector Edge02 = FPolyVoxVector(Vertex2.position - Vertex0.position);

/******************************
* Here is my attempt at creating UVs.. big yikes.
*****************************/
// Triangle vertices and center point
FVector A = (FPolyVoxVector(Vertex0.position) + OffsetLocation) * 100.f; //A
FVector B = (FPolyVoxVector(Vertex1.position) + OffsetLocation) * 100.f; //B
FVector C = (FPolyVoxVector(Vertex2.position) + OffsetLocation) * 100.f; //C
FVector P = FVector((A.X + B.X + C.X) / 3, (A.Y + B.Y + C.Y) / 3, 0);

// Mesh box extend
auto b = Mesh->Bounds.BoxExtent;// (transform);

// Vertex UVs (?)
auto UVA = FVector2D(A.X / b.X, A.Z / b.Z);
auto UVB = FVector2D(B.X / b.X, B.Z / b.Z);
auto UVC = FVector2D(C.X / b.X, C.Z / b.Z);

/*****************************/

const FVector TangentX = Edge01.GetUnsafeNormal();
FVector TangentZ = (Edge01 ^ Edge02).GetUnsafeNormal();

for (int32 j = 0; j < 3; j++)
{
}
}

// Finally create the mesh
Mesh->CreateMeshSection(0, Vertices, Indices, Normals, UV0, Colors, Tangents, true);

return true;
}


Thank you for reading my very lengthy post, please let me know if I'm not providing details you need!

EDIT:

I should probably include the tri-planar material I'm using:

• It looks flat - try to add some to world offset and or normal. You material works by world normal - but the mesh seems to be flat and also no normal map is plugged. – ColdSteel Nov 15 '19 at 14:26
• @ColdSteel Perhaps I could have used a better screenshot - it looks like that even on slopes. In the code I am adding normals (Though probably not correctly) Normals.Add(TangentX); Are you saying I need normals for the textures in the material as well? – Skettenring Nov 15 '19 at 15:11
• I don't know, if you will add a normal texture it will just add a little bit more details - but I doubt it will be noticeable IMO. iw ould plug something just for the experiment - sometimes it helps tbh. – ColdSteel Nov 15 '19 at 15:19
• @ColdSteel Ok i'll try that out! Thanks! – Skettenring Nov 15 '19 at 16:23