凸起球体上法线的计算显示光源前方有奇怪的对角线阴影

时间:2017-11-06 15:27:44

标签: java opengl normals heightmap

在下图中,您将看到我当前的设置。我正在渲染一个带有高度图信息的球体。网格是围绕球体缠绕的正方形。光源直接位于摄像机位置。我目前遇到的问题是法线的计算。

从我发现的,在连续表面上得到法向量的一种方法是,对于每个顶点,找到与其相邻的所有顶点,在网格中(在我的情况下,我有6个相邻顶点)找到法线到他们正在形成的所有六个平面,然后将它们相加并正常化。

您可以看到以下代码。 不幸的是,对于地球上的某些地方来说,它似乎有效,但不是一切。还要注意看起来在纹理上对角线的奇怪阴影线。

任何想法可能导致这种行为?

编辑:该问题与最终正常计算中的adjecent平面的权重无关。

private Vector3f calcNormal(int x, int z)
{
    if ( x<1 || x> RESOLUTION-2 || z<1 || z > RESOLUTION -2) {
        Vector3f newNormal = new Vector3f();
        newNormal = globe[x][z].sub(this.getTransform().GetPos()).normalize();
        return newNormal;
    }
    Vector3f center = globe[x][z];
    Vector3f up = globe[x][z-1];
    Vector3f down = globe[x][z+1];
    Vector3f left = globe[x-1][z];
    Vector3f right = globe[x+1][z];
    Vector3f rightUp = globe[x+1][z-1];
    Vector3f leftDown = globe[x-1][z];


    Vector3f dUp = new Vector3f(center).sub(up);
    Vector3f dRightUp = new Vector3f(center).sub(rightUp);
    Vector3f dRight = new Vector3f(center).sub(right);
    Vector3f dDown = new Vector3f(center).sub(down);
    Vector3f dLeft = new Vector3f(center).sub(left);
    Vector3f dLeftDown = new Vector3f(center).sub(leftDown);


    Vector3f normal = new Vector3f(dUp.cross(dRightUp)).
                    add(new Vector3f(dRightUp.cross(dRight))).
                    add(new Vector3f(dRight.cross(dDown))).
                    add(new Vector3f(dDown.cross(dLeftDown))).
                    add(new Vector3f(dLeftDown.cross(dLeft))).
                    add(new Vector3f(dLeft.cross(dUp)));

    return normal.normalize();  

}

Screen

1 个答案:

答案 0 :(得分:0)

这可能不是您的代码的实际问题,但可能仍然很好知道:

这个简单的算法不会给你带来好的结果。您需要在每个相邻法线上使用一些加权因子,并将其考虑在内。#34;如何相邻&#34;一个三角形是你当前的顶点。例如,可以使用三角形的归一化入射角。 this presentation from Crytek中描述的问题非常好。

注意,由于你没有对相邻三角形的法线进行标准化,所以你已经这样做了,因为它们是由两个边向量所跨越的平行四边形的大小来缩放的。