奇怪的GLSL行为

时间:2016-12-16 15:57:02

标签: opengl glsl

我正在尝试在我自己的图形引擎中实现色调图校正,我正在使用asylum2010(https://github.com/asylum2010/Asylum_Tutorials)的优秀演示作为参考 现在看:这是从上述演示中获得的着色器的改编:

#version 150

uniform sampler2D sampler0;
uniform vec2 texelSize;
uniform int prevLevel;

in vec2 tex;
out vec4 my_FragColor0;

void main()
{
    const vec3 LUMINANCE_VECTOR = vec3(0.2125, 0.7154, 0.0721);

    vec4 sample = texture(sampler0, tex + vec2(-0.5, -0.5) * texelSize);
    float dt = dot(sample.rgb, LUMINANCE_VECTOR);

    if (sample.r > 0.99 && sample.g > 0.99 && sample.b > 0.99)
    {
        if (dt > 0.9998)
        {
            if (log(0.0001 + dt) < 1.0) // <== NOTICE THIS!
                my_FragColor0 = vec4(0.1, 0.0, 0.0, 1.0);
            else
                my_FragColor0 = vec4(1.0, 0.0, 0.0, 1.0);
        }
        else
            my_FragColor0 = vec4(0.0, 0.0, 0.0, 1.0);
    }
    else
        my_FragColor0 = vec4(0.0, 0.0, 0.0, 1.0);
}

这是我写的着色器:

#version 150

uniform sampler2D ColorMap;
uniform vec2 TexelSize;
uniform int PreviousLevel;

in vec2 fragmentUV;
out vec4 fragment;

void main()
{
    const vec3 LUMINANCE_VECTOR = vec3(0.2125, 0.7154, 0.0721);

    vec4 sample = texture(ColorMap, fragmentUV + vec2(-0.5, -0.5) * TexelSize);
    float dt = dot(sample.rgb, LUMINANCE_VECTOR);

    if (sample.r > 0.99 && sample.g > 0.99 && sample.b > 0.99)
    {
        if (dt > 0.9998)
        {
            if (log(0.0001 + dt) < 1.0) // <== NOTICE THIS!
                fragment = vec4(0.1, 0.0, 0.0, 1.0);
            else
                fragment = vec4(1.0, 0.0, 0.0, 1.0);
        }
        else
            fragment = vec4(0.0, 0.0, 0.0, 1.0);
    }
    else
        fragment = vec4(0.0, 0.0, 0.0, 1.0);
}

您可能会注意到,除变量名称外,代码完全相同。 现在,当我在自己的引擎上运行第一个着色器时,它输出一个完整的红色,几乎所有通过的采样器的白色像素几乎是白色的(r,g和b> 0.99),这意味着对数计算的结果大于1.0

当我运行自己的着色器(当然传递相同的样本且具有相同的纹素大小)时,它会输出深红色,这意味着日志结果低于1.0。

在我看来,第二个着色器的结果是正确的,但这不是重点。关键是:结果如何不同?

1 个答案:

答案 0 :(得分:0)

对于那些感兴趣的人我终于找到了问题。 错误实际上是点积。我作为ColorMap传递了一个内部格式为GL_RGBA的纹理,而它应该是一个浮点纹理,以便存储大于1的值。 我也想知道我收到的downvote的原因。知道原因将有助于我避免任何可能发布问题的错误。