【问题标题】:GLSL: enabling/disabling texturing + shadersGLSL:启用/禁用纹理+着色器
【发布时间】:2010-10-27 10:38:24
【问题描述】:

我正在寻找一种从着色器访问 OpenGL 状态的方法。 GLSL Quick Reference Guide,一个很棒的资源,在这方面帮不了我。

在我正在处理的示例中,我有以下两个着色器:

顶点:

void    main()
{
    gl_FrontColor = gl_Color;
    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = ftransform();
}

片段:

uniform sampler2D   tex;
uniform float   flattening;

void main( void ) 
{
    vec4    texel;
    texel = texture2D(tex, gl_TexCoord[0].st);
    texel.r *= gl_Color.r;
    texel.g *= gl_Color.g;
    texel.b *= gl_Color.b;
    texel.a *= gl_Color.a;
    gl_FragColor = texel;
}

当我渲染没有纹理的多边形时,它们的 alpha 值是正确的,但它们被分配了黑色。

1,我可以设置什么条件检查,以便在禁用GL_TEXTURE_2D 时将变量“texel”设置为vec4(1.0, 1.0, 1.0, 1.0),而不是从纹理中采样?

2,如果我为不同的纹理模式编写不同的着色器并在它们之间切换我会使用glEnable/glDisable(GL_TEXTURE_2D),处理会更快吗?

【问题讨论】:

  • 简短说明:你可以写 texel *= gl_Color;作为一个向量运算而不是 4 个标量运算。
  • 谢谢,它是硬件加速的吗?这不是一个函数调用和 4 个标量操作 vs 4 个标量操作吗?
  • 它是加速的(如果你没有在软件中运行所有着色器,在这种情况下你是 int seconds-per-frame 领域),但没有额外的函数调用。诚然,它仍然是 4 个标量操作(在现代 GPU 上),我只是将其视为向量操作,但以这种方式跟踪和调试代码也容易得多。 (GLSL 编译器非常内联,以避免函数调用开销。)
  • 这确实是一个向量运算(=所有 4 个乘法都是并行计算的),如果可能,您应该始终尝试对标量运算进行分组。 GLSL 编译器可能会将 4 个单独的操作优化为一个,但我不会指望它。

标签: opengl shader glsl texturing


【解决方案1】:

我见过的一种方法是在渲染没有纹理的多边形时将 1x1 纹理与 (1.0, 1.0, 1.0, 1.0) 的单个纹素绑定。纹理切换应该比着色器切换更便宜,并且 1x1 纹理将完全适合纹理缓存。

【讨论】:

    【解决方案2】:

    抱歉,您不能从 GLSL 访问那种状态,句号。

    事实上,在未来的 GLSL 中,您必须自己发送所有 unforms/attributes,即没有自动的 gl_ModelViewMatrix、gl_LightPosition、gl_Normal 等。只有 gl_Position 和 gl_FragColor 等基本内容可用。

    这样可以使您的第二个问题无效,但是如果您发现这比为不同的纹理模式编写单独的着色器更方便,您总是可以使用#ifdef 来启用/禁用着色器中的部分。

    相关,请注意分支通常相当慢,因此如果您需要速度,请尽可能避免使用它。 (这尤其重要,因为片段在 SIMD 块中处理,并且块中的所有片段必须计算相同的指令,即使它们只适用于一个或几个片段。)

    【讨论】:

    • 感谢您的深入回答。我刚刚意识到(除此之外我已经陷入思维墙),我可以为启用/禁用声明一个统一的布尔值,并将相关调用路由到它。
    • 这是可行的,但不会很快。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 2019-03-09
    • 2015-02-23
    • 2013-06-13
    • 2012-03-05
    • 1970-01-01
    相关资源
    最近更新 更多