为什么统一变量在GLSL中不起作用? [英] Why are Uniform variables not working in GLSL?

查看:153
本文介绍了为什么统一变量在GLSL中不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am currently trying to create a Blur Shader for postprocessing purposes using LWJGL, but stumbled across a problem.

我要更改的均匀度是分辨率,模糊的半径和方向(水平或垂直),因此我可以在两个方向上使用一个着色器.我将输出渲染到FrameBuffer,然后将其渲染到屏幕.但是不知何故,纹理只是黑色.当我使用常量值而不是均匀值时,它的工作原理完全符合预期,因此问题必须出在统一变量上.

The Uniforms I want to change are resolution, radius and direction of the blur (horizontal or vertical, so I am able to use one Shader for both directions). I render the output to a FrameBuffer, which then gets rendered to the screen. But somehow, the Texture is just black. When I use constant values instead of uniforms, it works exactly as expected, so the problem must be the uniform variables.

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

This is the code of my fragment shader:

#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的方式:

This is how I render the 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没有太多经验,我缺少什么?

The sampler uniform works perfectly fine though, the problem only seems to affect the other three uniforms. I don't have much experience with OpenGL and GLSL, what am I missing?

推荐答案

由于以下原因,您的着色器代码根本无法工作

Your shader code can't work at all, because of

samplers[index]

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

samplers is an array of sampler2D and index is set from the vertex shader input samplerIndex:

int index = int(samplerIndex);

请参阅您使用的GLSL版本3.30(摘自 OpenGL着色语言3.30规范-4.1.7采样器):

See GLSL version 3.30, which you use (from OpenGL Shading Language 3.30 Specification - 4.1.7 Samplers ):

聚集到数组中的放大器 在着色器中(使用方括号[])只能使用整数常量表达式索引

Samplers aggregated into arrays within a shader (using square brackets [ ]) can only be indexed with integral constant expressions

请参阅GLSL版本4.60(最新版本)(摘自

See GLSL version 4.60 (most recent) (from OpenGL Shading Language 4.60 Specification - 4.1.7. Opaque Types):
(This rule applies to all the versions since GLSL 4.00)

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

When aggregated into arrays within a shader, these types can only be indexed with a dynamically uniform expression, or texture lookup will result in undefined values.

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

Thus, neither in the GLSL version which you use, nor in the most recent version, array of samplers can be indexed by an vertex shader input (attribute).

自GLSL 4.00起,可以通过统一方式对采样器数组进行索引,因为通过统一变量进行索引是

Since GLSL 4.00 it would be possible to index an array of samplers by an uniform, because indexing by a uniform variable is a dynamically uniform expression.

我建议使用sampler2DArray(请参见 Sampler )而不是sampler2D数组.
使用sampler2DArray时,根本不需要任何索引,因为在纹理查找时索引"被编码在纹理坐标的第3个分量中(请参见

I recommend to use sampler2DArray (see Sampler) rather than an array of sampler2D.
When you use a sampler2DArray, then you don't need any indexing at all, because the "index" is encoded in the 3rd component of the texture coordinate at texture lookup (see texture).

这篇关于为什么统一变量在GLSL中不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆