Pixel bender法线贴图

时间:2013-03-11 09:12:20

标签: flash graphics 3d pixel-bender

像往常一样感谢提前..

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

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归一化为不应该总是输出全蓝色?

我做错了什么?!?

1 个答案:

答案 0 :(得分: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);
}

这对我来说非常好。在不到100ms的时间内运行1.8M顶点。为了澄清,我将三角形定义为顶点之间的列。这意味着每4个顶点有两个三角形。我用“quadIdx”识别每个四边形的两个三角形。

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