【问题标题】:Why are Uniform variables not working in GLSL?为什么统一变量在 GLSL 中不起作用?
【发布时间】:2020-04-18 14:30:16
【问题描述】:

我目前正在尝试使用 LWJGL 创建用于后处理目的的模糊着色器,但偶然发现了一个问题。

我要更改的 Uniforms 是分辨率、半径和模糊方向(水平或垂直,因此我可以在两个方向上使用一个 Shader)。我将输出渲染到 FrameBuffer,然后渲染到屏幕上。但不知何故,纹理只是黑色。当我使用常量值而不是制服时,它完全按照预期工作,所以问题一定是制服变量。

这是我的片段着色器的代码:

#version 330 core

out vec4 fragColor;

in vec2 coords;
in vec4 color;
in float samplerIndex;

uniform sampler2D samplers[32]; //Just an Array with ints from 0 to 31
uniform float radius;
uniform vec2 resolution; //Screen Resolution, or width & height of Framebuffer
uniform vec2 direction; //Either 1 or 0 for x and y

void main() {
    int index = int(samplerIndex);

    vec4 sum = vec4(0.0);

    float blurX = radius / resolution.x * direction.x;
    float blurY = radius / resolution.y * direction.y;

    sum += texture2D(samplers[index], vec2(coords.x - 4.0 * blurX, coords.y - 4.0 * blurY)) * 0.0162162162;
    sum += texture2D(samplers[index], vec2(coords.x - 3.0 * blurX, coords.y - 3.0 * blurY)) * 0.0540540541;
    sum += texture2D(samplers[index], vec2(coords.x - 2.0 * blurX, coords.y - 2.0 * blurY)) * 0.1216216216;
    sum += texture2D(samplers[index], vec2(coords.x - 1.0 * blurX, coords.y - 1.0 * blurY)) * 0.1945945946;
    sum += texture2D(samplers[index], vec2(coords.x, coords.y)) * 0.2270270270;
    sum += texture2D(samplers[index], vec2(coords.x + 1.0 * blurX, coords.y + 1.0 * blurY)) * 0.1945945946;
    sum += texture2D(samplers[index], vec2(coords.x + 2.0 * blurX, coords.y + 2.0 * blurY)) * 0.1216216216;
    sum += texture2D(samplers[index], vec2(coords.x + 3.0 * blurX, coords.y + 3.0 * blurY)) * 0.0540540541;
    sum += texture2D(samplers[index], vec2(coords.x + 4.0 * blurX, coords.y + 4.0 * blurY)) * 0.0162162162;

    fragColor = color * vec4(sum.rgb, 1.0);
}

这就是我渲染 FrameBuffer 的方式:

    public void render(boolean fixed) {
        model.setTextureID(Shader.getTextureID(texture));

        model.buffer(vertices);
        indices.put(0).put(1).put(2).put(2).put(3).put(0);

        vertices.flip();
        indices.flip();

        shader.bind();
        texture.bind();

        shader.setUniform1iv("samplers", Shader.SAMPLERS);
        shader.setUniform1f("radius", 10.0f);
        shader.setUniform2f("resolution", width, height);
        shader.setUniform2f("direction", horizontal, vertical);
        if(fixed) {
            shader.setUniformMatrix4f("camProjection", Camera.fixedProjection);
            shader.setUniformMatrix4f("camTranslation", Camera.fixedTranslation);
        } else {
            shader.setUniformMatrix4f("camProjection", Camera.projection);
            shader.setUniformMatrix4f("camTranslation", Camera.translation);
        }

        vao.bind();

        vbo.bind();
        vbo.uploadSubData(0, vertices);
        ibo.bind();
        ibo.uploadSubData(0, indices);

        GL11.glDrawElements(GL11.GL_TRIANGLES, Model.INDICES, GL11.GL_UNSIGNED_INT, 0);

        vao.unbind();

        texture.unbind();
        shader.unbind();

        vertices.clear();
        indices.clear();
    }

虽然采样器制服工作得很好,但问题似乎只影响其他三件制服。 我对 OpenGL 和 GLSL 没有太多经验,我缺少什么?

【问题讨论】:

    标签: opengl glsl shader lwjgl


    【解决方案1】:

    您的着色器代码根本无法工作,因为

    samplers[index]
    

    samplerssampler2D 的数组,index 是从顶点着色器输入 samplerIndex 设置的:

    int index = int(samplerIndex);
    

    请参阅您使用的 GLSL 版本 3.30(来自 OpenGL Shading Language 3.30 Specification - 4.1.7 Samplers):

    采样器聚合成数组 在着色器中(使用方括号 [ ])只能使用整数常量表达式进行索引

    请参阅 GLSL 版本 4.60(最新)(来自 OpenGL Shading Language 4.60 Specification - 4.1.7. Opaque Types):
    (此规则适用于 GLSL 4.00 以后的所有版本)

    当在着色器中聚合成数组时,这些类型只能使用动态统一表达式进行索引,否则纹理查找将导致未定义的值。

    因此,无论是在您使用的 GLSL 版本中,还是在最新版本中,采样器数组都可以通过顶点着色器输入(属性)进行索引。

    从 GLSL 4.00 开始,可以通过统一索引采样器数组,因为统一变量索引是dynamically uniform expression


    我建议使用sampler2DArray(请参阅Sampler)而不是sampler2D 的数组。
    当您使用sampler2DArray 时,您根本不需要任何索引,因为“索引”在纹理查找时被编码在纹理坐标的第三个分量中(请参阅texture)。

    【讨论】:

    • 我终于让它完美运行,但我的代码还有第二个问题。我使用 HashMap 来存储统一的位置,因此我不必每次需要它们时都搜索它们。由于 HashMap 是静态的,因此每个 Shader 的位置总是相同的,这显然不能与不同的着色器一起使用。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多