0

像往常一样提前谢谢..

我正在使用像素弯曲器为基于高度图的地形生成照明效果。我想制作地形的法线贴图,并从那里将每个法线点在给定的太阳方向上。确实很标准的东西,但是像素弯曲器玩得不好。我有这个代码:

void
evaluatePixel()
{
    float2 pt = outCoord();

    pixel3 a = sampleNearest(src,pt);
    pixel3 b = sampleNearest(src,float2(pt.x + 1.0, pt.y));
    pixel3 c = sampleNearest(src,float2(pt.x, pt.y + 1.0));

    float3 v1 = float3(1.0, 0.0, b.r - a.r);
    float3 v2 = float3(0.0, 1.0, c.r - a.r);

    normalize(v1);
    normalize(v2);

    float3 n = cross(v1,v2);

    dst = pixel3(n.x,n.y,n.z);
}

我希望这会产生一个法线贴图。为了进行测试,我假设光线直接指向下方并仅用n.z作输出颜色。这会产生纯色。如果您使用上面的代码并运行它,您会看到虽然红色和绿色有变化,但蓝色总是在 255 处充满。这是为什么呢?我希望考虑v1v2规范化这不应该总是输出全蓝色?

我究竟做错了什么?!?

4

1 回答 1

0

实际上我在这里做了一些非常相似的事情,我的三角形带高度图。

input image3 verts;
output pixel3 triNorms;

void
evaluatePixel()
{
    float2 tCoord = outCoord() - 0.5; //move coord from pixel center to lower-left corner
    float quadIdx = mod(tCoord[0], 2.0); //potentially faster to use sign(fract(tCoord[0] / 2.0))
    float2 vCoord0 = float2(floor(tCoord.x / 2.0), tCoord.y);
    float2 vCoord1 = float2(vCoord0.x + 1.0, vCoord0.y + 1.0 - quadIdx);
    float2 vCoord2 = float2(vCoord0.x + quadIdx, vCoord0.y + 1.0);
    float3 v0 = sampleNearest(verts, vCoord0 + 0.5);
    float3 v1 = sampleNearest(verts, vCoord1 + 0.5);
    float3 v2 = sampleNearest(verts, vCoord2 + 0.5);
    float3 s0 = v1 - v0;
    float3 s1 = v2 - v0;
    float3 n = cross(s0, s1);
    float len = 1.0 / length(n);
    n.x *= len;
    n.y *= len;
    n.z *= len;
    triNorms = float3(n.x, n.y, n.z);
}

这对我来说非常有效。在不到 100 毫秒的时间内通过 180 万个顶点。为了澄清起见,我将三角形定义为顶点之间的列。这意味着每 4 个顶点有两个三角形。我用“quadIdx”标识每个四边形的两个三角形。

注意:您正在标准化然后计算交叉 - 这是向后的,您需要在之后进行标准化。另外,我实际上相信我在 normalize() 中发现了一个错误。它在我没想到的地方创造了 NaN。我用 length() 实现了我自己的标准化,一切都很好!

于 2013-07-06T01:37:33.633 回答