2011-09-20 42 views
7

但是POW(0,2.0)给出0pow(0,2.2)在hlsl像素着色器中给出1?

似乎任何浮动指数给出1,而整数指数给我使用的DirectX 9 0

和HLSL编译器 “D3DCompiler_43.dll”。 确认在Nvidia和Ati卡上。

我很困惑! 这是一种已知的行为或错误?

为了说明效果尝试以下简单的测试着色器:

// Test shader demonstrating strange pow behaviour 
// when brightness becomes 0 resulting color will jump to white 

float4x4 WorldViewProjXf : WorldViewProjection < string UIWidget="None";>; 

float Brightness 
< 
    string UIName = "Brightness"; 
    float UIMin = 0; 
    float UIMax = 1;  
> = 0; 


struct VS_Input 
{ 
    float4 position : POSITION0; 
}; 

struct VS_Output 
{ 
    float4 position : POSITION0; 
}; 

VS_Output Vertex_Func(VS_Input in_data) 
{ 
    VS_Output outData; 
    outData.position = mul(in_data.position, WorldViewProjXf); 
    return outData; 
} 

float4 Fragment_Func(VS_Output in_data) : COLOR 
{ 
    return pow(Brightness, 2.2); 
} 

technique Main 
{ 
    pass p0 
    {  
     VertexShader = compile vs_3_0 Vertex_Func(); 
     PixelShader = compile ps_3_0 Fragment_Func(); 
    } 
} 

回答

5

望着HLSL文档,pow(x, y)似乎直接实现为exp(y * log(x))。由于x=0在你的问题中,再次看文档log(x) == -INF。看起来y的价值在这一点上应该不重要,只要它是正数且大于零。

您可能会意外地比较pow(0.0, 2.0) == 0.0pow(0.0, 0.0) == 1.0。这是我对发生的事情的最好猜测。

log(0)=-INF reference

pow = exp(y * log(x)) reference

+0

可否请你发布一个链接到那些你讲的文档。听起来比我能在msdn上找到的信息更好。 –

+0

添加参考。第二个参考是“pow”指令,而不是“pow”内部函数。 –

+0

现在我明白了,您正在讨论着色器汇编器文档。不是HLSL,但有一些帮助,因为有一些额外的信息。它的右边“pow(abs(Color),Exponent)”和“exp(Exponent * log(Color))”都给出了相同的结果 - 包括零错误,不幸的是。那么,你的答案不完全是一个答案,但只要没有其他答案,并且你很有帮助,你就会得到答案。 –

相关问题