Converting glsl to ComputeShader

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 :frowning:

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.