天天看点

[HLSL]关于shader中normalize失效的一个问题

    前段时间在公司写光照的时候,遇见个很神奇的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编译则又完全正常,下面是开优化与不开优化的截图。

    开优化:

[HLSL]关于shader中normalize失效的一个问题

不开优化:

[HLSL]关于shader中normalize失效的一个问题

   可以看出都做了2次normalize操作,结果完全正常。我不确定造成家里跟公司结果不同是否是因为DX小版本的不同。我用的是2010 6月的DX9SDK。

   如果大家遇见此类问题,以供参考。

继续阅读