【问题标题】:Unable to load Attribute into shader无法将属性加载到着色器中
【发布时间】:2020-05-18 13:43:38
【问题描述】:

我希望在着色器中存储一些自定义数据,以便在渲染期间重新用于多个帧。 起初我尝试做的是存储一个颜色缓冲区,看看是否可以这样做。

顶点着色器:

attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;

uniform mat4 u_projTrans;

varying vec4 v_color;
varying vec2 v_texCoords;
vec2 u_mouse;
uniform float u_time;
attribute vec3 my_data;
varying vec3 frag_data;

void main() {
    v_color = a_color;
    v_texCoords = a_texCoord0;
    gl_Position = u_projTrans * a_position;
    frag_data = my_data;
}

片段着色器:

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

varying vec3 frag_data;

void main(){
    gl_FragColor = vec4(vec3(frag_data),1.0);
}

除了vec3 my_data 的使用之外,着色器按预期编译和工作:

        ShaderProgram.pedantic = false;
        vertex_shader = Gdx.files.internal("vertex_shader.glsl").readString();
        fragment_shader = Gdx.files.internal("fragment_shader.glsl").readString();
        shader_program = new ShaderProgram(vertex_shader, fragment_shader);

我尝试通过单击按钮来设置变量,如下所示:

        goBtn = new TextButton("Reset", textButtonStyle);
        goBtn.setSize(128,128);
        goBtn.addListener(new ChangeListener() {
            @Override
            public void changed(ChangeEvent event, Actor actor) {
                FloatBuffer myArray = BufferUtils.newFloatBuffer(3);
                myArray.put(1.0f);myArray.put(1.0f);myArray.put(1.0f);

                shader_program.begin();
                shader_program.setVertexAttribute("my_data", 3, GL20.GL_FLOAT, false, 0, myArray);
                shader_program.end();
            }
        });

但是没有效果..

我在这里做错了什么?

这样做的正确方法是什么?

【问题讨论】:

  • 你不能将外部的东西附加到一个变化的上。您必须将您使用的任何内容绑定到一个 attribute 并将该属性传递给一个变量,就像您已经对 a_color/v_colora_texCoord0/v_texCoords 所做的那样。
  • varying 变量是着色器阶段之间的接口变量。您必须在顶点着色器中设置my_data。如果你想要一个额外的属性,那么你必须使用关键字attribute
  • 你是对的。我更新了着色器以反映这一点。但是,按下按钮仍然没有效果。

标签: java opengl libgdx glsl


【解决方案1】:

我从未尝试通过 ShaderProgram 设置顶点属性。我什至不确定为什么它作为一个选项存在,因为顶点数据应该是每个顶点的。由于您要为整个网格设置它,因此它应该是统一的。而且由于它是制服,因此您也不必通过变量传递它。

所以从你的顶点着色器中移除变量和属性。并将片段着色器中的变化更改为统一。

并传递数据:

        public void changed(ChangeEvent event, Actor actor) {
            shader_program.begin();
            shader_program.setUniformf("my_data", 1.0f, 1.0f, 1.0f);
            shader_program.end();
        }

但您也应该在首次设置时调用此代码来设置此制服的默认值。在设置它们的值之前,行为可能是未定义的。

【讨论】:

  • 在整个渲染步骤中,统一值是否应该保持不变?这应该是从着色器内部修改的东西。这仍然有效吗?
  • 如果您为这个对象切换到不同的着色器,当您切换着色器时,无论如何它都会刷新批次。但无论如何,您是在更改此侦听器中的值,而不是在渲染期间。
  • 确实如此,您编写的内容使程序正常运行。但是,我这样做的全部原因是实际计算GPU上的逐像素操作,现在当我尝试修改它时,出现以下错误:ERROR: 0:20: 'assign' : l-value required "my_data" (cannot modify a uniform)
  • 不完全确定你在做什么。如果它只是一个可以用来计算每个片段值的常量,您可以将其复制到main 函数中的变量并修改副本。 `vec3 localFragData = frag_data;
  • 它应该是计算每个像素的值,但它不应该是恒定的,GPU核心会修改它,基本上它会像vector field
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-03
  • 2013-04-21
相关资源
最近更新 更多