【问题标题】:Fragment shader always uses 1.0 for alpha channel片段着色器始终使用 1.0 作为 Alpha 通道
【发布时间】:2014-01-07 05:10:29
【问题描述】:

我有一个我加载的 2d 纹理

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, gs.width(), gs.height(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, gs.buffer());

其中gs 是一个对象,它具有返回正确类型的方法。

在片段着色器中,我从纹理中采样并尝试将其用作生成颜色的 Alpha 通道。如果我将采样值用于输出纹理中的其他通道,它会产生我期望的结果。我用于 Alpha 通道的任何值似乎都被忽略了,因为它总是绘制 Color

我正在使用以下方式清除屏幕:

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

谁能建议我可能做错了什么?我得到一个带有 8 个红色、8 个绿色、8 个蓝色和 8 个 alpha 位的 OpenGL 4.0 上下文。

顶点着色器:

#version 150

in vec2 position;
in vec3 color;
in vec2 texcoord;

out vec3 Color;
out vec2 Texcoord;

void main()
{
    Texcoord = texcoord;
    Color = color;
    gl_Position = vec4(position, 0.0, 1.0);
}

片段着色器:

#version 150

in vec3 Color;
in vec2 Texcoord;

out vec4 outColor;

uniform sampler2D tex;

void main()
{
    float t = texture(tex, Texcoord);
    outColor = vec4(Color, t);
}

【问题讨论】:

    标签: opengl glsl


    【解决方案1】:

    坦率地说,我很惊讶这真的有效。 texture (...) 返回 vec4(除非您使用的是阴影/整数采样器,但您不是)。如果您打算将纹理存储在float 中,真的应该将纹理转换为单个组件。

    我猜你想要纹理的 alpha 分量,但谁知道呢?试试这个吧:

    float t = texture (tex, Texcoord).a; // Get the alpha channel of your texture
    

    一个中规中矩的 GLSL 编译器会警告/错误你正在做你正在尝试做的事情。我怀疑你的也是这样,但是当你编译你的着色器时你没有检查着色器信息日志。


    更新:

    最初的答案甚至没有开始解决您对 GL_DEPTH_COMPONENT 内部格式纹理所做的疯狂行为。我完全错过了,因为代码不适合屏幕。

    为什么要使用gs.rgba() 将数据传递给内部和像素传输格式正好是1 个分量的纹理?此外,如果您打算在着色器中使用深度纹理,那么它总是返回 a=1.0 的原因实际上 非常 很简单:


    从 GLSL 1.30 开始,当使用 texture (...) 进行采样时,深度纹理会自动设置为返回以下 vec4

           vec4 (r, r, r, 1.0)

    RGB 分量被替换为 R(浮点深度)的值,A 被替换为常数值1.0

    【讨论】:

    • rgba() 是我最初的名字,当我提供这些时。我更改了函数,使其只有一个组件,但我忘记更改函数名称以表明这一点。我已编辑帖子以将名称更改为buffer()
    • @Graznarak:好吧,如果你想从深度纹理中获得非 1 值,你将需要使用 .r 组件。如果您采用 alpha 组件,正如我在答案中讨论的那样,它始终是 1.0
    • 我已将着色器更改为使用float t = texture(tex, Texcoord).r;outColor = vec4(Color, t);,但它仍然只是输出颜色,而显然忽略了第四个组件。
    • @Graznarak:那么你需要以下混合函数:glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)。而且我没有看到您的代码中设置或启用GL_BLEND 的任何部分。如果不这样做,alpha 对任何事情都没有影响。
    • @Graznarak:该混合函数会将片段着色器的输出颜色乘以输出 alpha,并将其与片段着色器的 (1 - output alpha) 相加到帧缓冲区中的原始颜色。它会准确地完成您想要的操作,但在更复杂的渲染场景中,顺序依赖性可能会成为一个问题。
    【解决方案2】:

    您的问题是,当您需要 vec4 时,您只会传入 vec3。 RGBA - 4 个组件,而不仅仅是三个。

    【讨论】:

    • Color 是 vec3,但 outColor 是 vec4。什么需要有 4 个组件?
    猜你喜欢
    • 1970-01-01
    • 2019-10-28
    • 1970-01-01
    • 2014-11-12
    • 2012-11-08
    • 2014-02-06
    • 2021-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多