根据HeightMap计算球形地形法线

时间:2019-09-10 21:56:27

标签: c++ unreal-engine4 perlin-noise

我尝试根据HeightMap值计算“顶点法线”。 我在开始时创建了一个HeightMap。到目前为止,该方法有效。 LOD也起作用。

我知道如何为平坦地形计算法线,但是如何为球形地形计算法线? enter image description here 如您所见,照明不起作用,法线贴图也不起作用。

我正在考虑首先计算法线和切线,因为它会是平坦的地形。而不是使用一些变换,所以法线和切线 适合球形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;

左边是我的计算,右边是UE4的内置功能 enter image description here

0 个答案:

没有答案