我正在做的是使用法线贴图来照亮 2D 精灵。最初我打算在图像红色通道中使用凹凸/高度图,并使用其他两个通道来存储其他信息。我的想法是,因为我知道法线贴图上的任何法线总是在 [0 .. 1] 范围内具有 z 值,我可以从蓝色通道中排除此信息并根据 x 的长度计算 z 值和 y 值。所以我试了一下,它似乎到目前为止工作,它看起来几乎和原来的一样。
我的问题是附加说明的费用是多少?有一些额外的乘法和加法以及另外两个 sqrt 调用。
这是使用的片段着色器:
// Input >
// fc0 : Color to normal conversion factor - <2, 1, 0, 0>
// fc1 : Light - <lightDirection.x, lightDirection.y, lightDirection.z>
// v0 : texture coordinates - <u, v>
// fs0 : color texture
// fs1 : normal map
// Sample normal map (fs1) at coordinates (v0) into temp register (ft0)
tex ft0 v0 fs1 <2d,nearest>
// Convert color values [0, 1] to normal values [-1, 1]
mul ft0 ft0 fc0.xxx
sub ft0 ft0 fc0.yyy
//
// The code below is used to calculate the z value from the
// 2D x/y normal values
//
// <Start normal z calculation>
// (ft0) should now hold a 2D vector - first find its length
// - length = sqrt(x * x + y * y)
mul ft1.x ft0.x ft0.x // x * x
mul ft1.y ft0.y ft0.y // y * y
add ft1.z ft1.x ft1.y // (x * x + y * y)
sqt ft1.z ft1.z // ft1.z = sqrt(x * x + y * y)
// Now using the length of the 2D normal find the z value
// - z = sqrt(1 - length * length)
mul ft1.z ft1.z ft1.z // length * length
sub ft1.z fc0.y ft1.z // 1 - length * length
sqt ft1.z ft1.z // ft1.z = sqrt(1 - length * length)
// Now move the z value into temp register (ft0) along with the normal x and y value
mov ft0.z ft1.z
// <End normal z calculations>
// The rest of the shader left out