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

Posted

技术标签:

【中文标题】pow(0, 2.2) 在 hlsl 像素着色器中给出 1?【英文标题】:pow(0, 2.2) gives 1 in a hlsl pixel shader? 【发布时间】:2011-09-20 14:27:39 【问题描述】:

但是 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();
    

【问题讨论】:

【参考方案1】:

查看 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

【讨论】:

能否请您发布指向您所说的那些文档的链接。听起来比我在 msdn 上找到的信息要好。 添加了参考。第二个引用是pow 指令,而不是pow 内在函数。 现在我明白了,您在谈论着色器汇编器文档。不是 HLSL,但有些帮助,因为有一些附加信息。它的权利,“pow(abs(Color), Exponent)”和“exp(Exponent * log(Color))”都给出了相同的结果——不幸的是,包括零错误。好吧,您的答案并不完全是一个答案,但只要没有其他答案,并且您对您有所帮助,您就会得到复选标记。

以上是关于pow(0, 2.2) 在 hlsl 像素着色器中给出 1?的主要内容,如果未能解决你的问题,请参考以下文章

WPF 像素着色器入门:使用 Shazzam Shader Editor 编写 HLSL 像素着色器代码

HLSL像素着色器

统一按钮在着色器中丢弃像素

在片段着色器中绘制别名像素完美线?

像素着色器中的 SamplerState 问题

GLSL 像素化着色器中的边框伪影