前段时间在公司写光照的时候,遇见个很神奇的BUG跟大家分享下。
我们在使用normalmap的时候,需要将float3的normal压缩成float2的数据,下面是大致代码:
float2 encode(float3 normal)
{
float2 norm = normalize(normal.xy);
return norm;
}
float4 normal(in float4 position : POSITION0) : POSITION
{
float3 fvec3 = position.xyz;
fvec3 = normalize(fvec3);
float2 fvec2 = encode(fvec3);
return float4(fvec2.xy, fvec3.x, fvec3.z);
}
在使用normal时,模型某个方向的光照始终不对。研究了很久都没发现问题,挂上pix截取帧查看具体数据时发现压缩后的normal有问题。具体体现在encode函数中,当将一个
经过normalize的float3传入后,normalize(normal.xy)完全不起作用,直接return了normal的xy。而我们需要的是将normal的xy再一次normalize后再传回。
引起这个问题的具体原因,应该是DX内部优化的问题。它认为传给它的float3已经是normalize过的,所以你即使想normalze它的xy,它也不会做任何擦做。我在公司电脑DX
SDKbin文件夹下单独编译很明显可以看出它优化了代码,使用/0d命令后再编译则完全正常。
不过事情还没结束,回家后,我用自己的DX SDK编译则又完全正常,下面是开优化与不开优化的截图。
开优化:
不开优化:
可以看出都做了2次normalize操作,结果完全正常。我不确定造成家里跟公司结果不同是否是因为DX小版本的不同。我用的是2010 6月的DX9SDK。
如果大家遇见此类问题,以供参考。