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

发布于 2024-12-05 10:12:22 字数 1057 浏览 0 评论 0原文

但 pow(0, 2.0) 给出 0

似乎任何浮点指数给出 1,而整数指数给出 0。

我正在使用 DirectX 9 和 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();
    }
}

But pow(0, 2.0) gives 0

Seems that any float exponent gives 1 while integer exponents give 0.

I am using DirectX 9 and hlsl compiler "D3DCompiler_43.dll".
Confirmed that on Nvidia and Ati cards.

I am confused!
Is that some kind of known behaviour or bug?

To illustrate the effect try the following simple test shader:

// 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();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

没有心的人 2024-12-12 10:12:22

查看 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 进行比较。这是我对正在发生的事情的最好猜测。

日志(0) =-INF参考

pow = exp(y * log(x) )参考

Looking at the HLSL docs, pow(x, y) appears to be implemented directly as exp(y * log(x)). Since x=0 in your question, again looking at the docs log(x) == -INF. It seems like the value of y shouldn't matter at that point as long as it's positive and greater than zero.

You might be accidentally comparing pow(0.0, 2.0) == 0.0 with pow(0.0, 0.0) == 1.0. That's my best guess for what's happening.

log(0)=-INF reference

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文