I am trying to convert this snippet to work inside a ComputeShader:

Tex3 = normalize(TriPos); //TriPos is the current Vertex
Normal = normalize((model*vec4(Tex3, 1.0f)).xyz);

vec3 CalculateNormal(vec2 uv, sampler2D tex, vec3 texOffset)
{
// read neightbor heights using an arbitrary small offset
float hL = height(uv - texOffset.xz, tex);
float hR = height(uv + texOffset.xz, tex);
float hD = height(uv - texOffset.zy, tex);
float hU = height(uv + texOffset.zy, tex);
// deduce terrain normal
vec3 N = normalize(vec3(hL - hR, hD - hU, 2.0));
vec3 norm = normalize(Normal);
vec3 up = vec3(0, 1, 0)-norm;
vec3 tang = normalize(cross(norm, up));//might need flipping
vec3 biTan = normalize(cross(norm, tang));//same
mat3 localAxis = mat3(tang, biTan, norm);
return normalize(localAxis * normalize(N));
}

The major Problem i have is that i don’t know, from where i can get the model Transform Matrix. The output of this should be a Normal on spherical Terrain(Planet)
Things that work:

• Generate a Heightmap with Perlin Noise
• Generate a NormalMap for the Heightmap
• Send Heightmap to the ComputeShader
• Calculate LOD with the ComputeShader
• Slope based Texturing

Edit 1:
This is what i got so far

for (int y = 0; y < geoData.GeoData.Num(); y++)
{
int32 locX = UKismetMathLibrary::MapRangeClamped(geoData.UVs[y].X, 0.f, 1.f, 0.f, heightmapWidth);
int32 locY = UKismetMathLibrary::MapRangeClamped(geoData.UVs[y].Y, 0.f, 1.f, 0.f, heightmapHeight);
FVector currentNorm = geoData.GeoData[y].GetSafeNormal();

float pr = heightMap[locX < heightmapWidth - 1 ? locY * heightmapWidth + locX + 1 : locY * heightmapWidth];// Right
float pl = heightMap[locX - 1 > 0 ? locY * heightmapWidth + locX - 1 : locY * heightmapWidth + heightmapWidth - 1];// Left
float pu = heightMap[locY > 0 ? ((locY - 1) * heightmapWidth + locX) : (heightmapWidth - 1) * (heightmapHeight - 1) + locX];// Up
float pd = heightMap[locY + 1 < heightmapHeight ? ((locY + 1) * heightmapWidth + locX) : locX];// Down

FVector cN = (FVector(pl - pr, pd - pu, 2.0)).GetSafeNormal();
FVector up = FVector(0, 1, 0) - currentNorm;
FVector tang = (FVector::CrossProduct(currentNorm, up)).GetSafeNormal();//might need flipping
FVector biTan = (FVector::CrossProduct(currentNorm, tang)).GetSafeNormal();//same

FVector finalNormal = FVector(  tang.X * cN.X + tang.Y * cN.Y + tang.Z * cN.Z,
biTan.X * cN.X + biTan.Y * cN.Y + biTan.Z * cN.Z,
currentNorm.X * cN.X + currentNorm.Y * cN.Y + currentNorm.Z * cN.Z);
geoData.TangentsData[y] = tang;
geoData.NormalsData[y] = finalNormal;
}

The Result is wrong

Edit 2:

I found the issue with the Normal pointing in the wrong direction. But now i noticed this

As you can see the Normal at the Cliff is not pointing in the direction it should

Solved it. I don’t use a computeshader for now. So i can use a different methode.

You can caluclate the normal with 3 Points and cross product.