我尝试根据HeightMap值计算“顶点法线”。 我在开始时创建了一个HeightMap。到目前为止,该方法有效。 LOD也起作用。
我知道如何为平坦地形计算法线,但是如何为球形地形计算法线? 如您所见,照明不起作用,法线贴图也不起作用。
我正在考虑首先计算法线和切线,因为它会是平坦的地形。而不是使用一些变换,所以法线和切线 适合球形Terrrain。
修改1: 那就是我到目前为止所得到的。这是正确的Michael Nastenko吗?这里我用的不是PerlinNoise的Heightmap
float x1 = pRadius * FMath::Cos(lat + yDelta) * FMath::Cos(lon);
float y1 = pRadius * FMath::Cos(lat + yDelta) * FMath::Sin(lon);
float z1 = pRadius * FMath::Sin(lat + yDelta);
float x2 = pRadius * FMath::Cos(lat - yDelta) * FMath::Cos(lon);
float y2 = pRadius * FMath::Cos(lat - yDelta) * FMath::Sin(lon);
float z2 = pRadius * FMath::Sin(lat - yDelta);
float x3 = pRadius * FMath::Cos(lat) * FMath::Cos(lon + xDelta);
float y3 = pRadius * FMath::Cos(lat) * FMath::Sin(lon + xDelta);
float z3 = pRadius * FMath::Sin(lat);
float x4 = pRadius * FMath::Cos(lat) * FMath::Cos(lon - xDelta);
float y4 = pRadius * FMath::Cos(lat) * FMath::Sin(lon - xDelta);
float z4 = pRadius * FMath::Sin(lat);
float xDifference = GetNoiseValue(FVector(x1, y1, z1).GetSafeNormal())
- GetNoiseValue(FVector(x2, y2, z2).GetSafeNormal());
float yDifference = GetNoiseValue(FVector(x3, y3, z3).GetSafeNormal())
- GetNoiseValue(FVector(x4, y4, z4).GetSafeNormal());
FVector planeTangent = FVector(1.f, 0.f, xDifference).GetSafeNormal();
FVector planeBiTangent = FVector(0.f, 1.f, yDifference).GetSafeNormal();
修改2: x1,y1,z1 ...是顶点的相邻点,我想计算切线/法线。对于这些点中的每一个,我都会得到NoiseValue。因此,我可以使用有限的差异来获取表面的斜率。 这不是获取平坦地形切线的方法吗?
修改3: 这样计算法线在某种程度上是错误的。
TArray<FVector> normals;
normals.Init(FVector(0, 0, 0), geoData.GeoData.Num());
int32 triangleCount = geoData.Triangles.Num() / 3;
for (int32 i = 0; i < triangleCount; i++)
{
int32 normalTriangleIndex = i * 3;
int32 triangleIndexA = geoData.Triangles[normalTriangleIndex];
int32 triangleIndexB = geoData.Triangles[normalTriangleIndex + 1];
int32 triangleIndexC = geoData.Triangles[normalTriangleIndex + 2];
FVector pointA = geoData.GeoData[triangleIndexA];
FVector pointB = geoData.GeoData[triangleIndexB];
FVector pointC = geoData.GeoData[triangleIndexC];
FVector sideAB = pointB - pointA;
FVector sideAC = pointC - pointA;
FVector norm;
norm= FVector::CrossProduct(sideAB, sideAC);
normals[triangleIndexA] = -norm;
normals[triangleIndexB] = -norm;
normals[triangleIndexC] = -norm;
}
geoData.NormalsData = normals;