【问题标题】:'texture' function call on sampler2D in glsl makes entire screen grayglsl 中 sampler2D 上的“纹理”函数调用使整个屏幕变灰
【发布时间】:2021-01-15 10:44:19
【问题描述】:

我正在尝试在片段着色器中同时使用 samplerBuffersampler2D

单独使用 samplerBuffer 可以正常工作,代码如下所示

#version 460
out vec4 FragColor;
in vec2 texcoord;

uniform sampler2D background;
uniform samplerBuffer OctreeData;

...

void main()
{    
    Ray ray = initRay();
    /*this function does raytraycing in octree and retrieves data
    from samplerBuffer using texelFetch function.*/
    Contact res = iterativeHitNodes(ray);

    if(res.hit)
      FragColor = assignNodeColor(res); //sets color of the node
    else
      FragColor = getBackground(origin, ray);
}

然后,如果我在main 函数的开头添加FragColor = texture(background, texcoord.xy); return; 行,它会成功读取图像并显示它。 (A)

但是当在getBackground 中调用texture 时,它会显示灰屏。结果发现着色器根本不工作——当我故意加载重型模型时,帧率保持不变。但是没有着色器编译错误。

最大的“什么”是即使texture 从未被称为(B),屏幕仍然是灰色的。例如,当backgroundType 始终为 0 而getBackground 函数为:

vec3 getBackground(vec3 from, vec3 direction)
{
    if(backgroundType == 0)
        return getSkyBackground(from, direction);
    else if(backgroundType == 1)
    {
        return texture(background, texcoord.xy).xyz;
    }

    return vec3(0);
}

似乎完全存在texture 调用丢弃片段。

P.S. 在调试中它按预期工作。由于某种原因,问题出现在Release模式

P.P.S大部分shader的代码https://pastebin.com/SWCQ9HUw

【问题讨论】:

    标签: c++ opengl glsl


    【解决方案1】:

    OpenGL Shading Language 4.60 Specification (HTML) - Texture Functions:

    某些纹理函数(非“Lod”和非“Grad”版本)可能需要隐式导数。在非均匀控制流和非片段着色器纹理提取中未定义隐式导数。

    如果您使用纹理和texture 进行纹理查找,请确保调用组中的所有调用都执行相同的控制流路径:

    vec3 getBackground(vec3 from, vec3 direction, vec3 backgroundColor)
    {
        if (backgroundType == 0)
            return getSkyBackground(from, direction);
        else if (backgroundType == 1)
            return backgroundColor;
    
        return vec3(0);
    }
    
    void main()
    {
        vec3 backgroundColor = texture(background, texcoord.xy).xyz;
        
        Ray ray = initRay();
        /*this function does raytraycing in octree and retrieves data
        from samplerBuffer using texelFetch function.*/
        Contact res = iterativeHitNodes(ray);
    
        if(res.hit)
          FragColor = assignNodeColor(res); //sets color of the node
        else
          FragColor = getBackground(origin, ray, backgroundColor);
    }
    

    【讨论】:

    • 这意味着我们不应该在分支条件下使用对texture 的调用?但如果所有分支都调用它(可能有不同的参数),那没关系?
    • @Beko " 如果所有分支都调用它(可能有不同的参数),那没关系?" - 不,不是。计算分支中的纹理坐标,但在统一控制流中进行查找。
    • @Rabbid76 这一次证明着色器在调用iterativeHitNodes(调用texelFetch)后停止。如果我删除它texture 似乎即使使用分支也可以正常工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-09
    相关资源
    最近更新 更多