Opengl es OpenGL ES 2.0中片段着色器的非均匀颜色值

Opengl es OpenGL ES 2.0中片段着色器的非均匀颜色值,opengl-es,Opengl Es,尝试从中修改三角形顶点颜色值。三角形渲染,但显示为黑色。颜色缓冲区有什么问题 public class Triangle { ... 添加以下行以建立颜色缓冲区。这有必要吗 private FloatBuffer colorBuffer; static final int COLORS_PER_VERTEX = 4; static float triangleColors[] = { 0.6f, 0.2f, 0.2f, 1.0f,

尝试从中修改三角形顶点颜色值。三角形渲染,但显示为黑色。颜色缓冲区有什么问题

public class Triangle {

    ...
添加以下行以建立颜色缓冲区。这有必要吗

    private FloatBuffer colorBuffer;
    static final int COLORS_PER_VERTEX = 4;

    static float triangleColors[] = {
            0.6f, 0.2f, 0.2f, 1.0f,
            0.2f, 0.6f, 0.2f, 1.0f,
            0.9f, 0.9f, 0.2f, 1.0f
    };

    private final int colorStride = COLORS_PER_VERTEX * 4; 
使用以下着色器代码,将原始“uniform vec4 vColor”替换为属性,而不是变化,因为没有GLES20.GetVarygLocation

    private final String vertexShaderCode =
        "attribute vec4 vPosition;void main(){gl_Position = vPosition;}";

    private final String fragmentShaderCode =
            "precision mediump float;" +
                    //originally uniform, use varying?
                   "attribute vec4 vColor;" +
                    "void main() {" +
                    "    gl_FragColor = vColor;"+
                    "}";
在构造函数中:

    public Triangle()
    {
        ...

        ByteBuffer cb = ByteBuffer.allocateDirect(triangleColors.length * 4);
        cb.order(ByteOrder.nativeOrder());
        colorBuffer = cb.asFloatBuffer();
        colorBuffer.put(triangleColors);
        colorBuffer.position(0);

        ... //compile and link shaders code is unchanged   
    }

    public void draw()
    {
        GLES20.glUseProgram(mProgram);

        ...

        /*
        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
        GLES20.glUniform4fv(mColorHandle, 1, color, 0);
        */

        mColorHandle = GLES20.glGetAttribLocation(mProgram, "vColor");
        GLES20.glEnableVertexAttribArray(mColorHandle);
        GLES20.glVertexAttribPointer(mColorHandle, COLORS_PER_VERTEX,
                GLES20.GL_FLOAT, false, colorStride, colorBuffer);

        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
        GLES20.glDisableVertexAttribArray(mPositionHandle);
        GLES20.glDisableVertexAttribArray(mColorHandle);

    }

}

你误解了什么是统一,什么是属性,什么是变化

要进行所描述的更改,您需要属性和变量。顶点着色器必须包含颜色的属性,例如
attribute vec4 aColor
和可变输出,如
可变vec4 vColor。然后主要需要将颜色指定为
vColor=aColor。在片段着色器中,您只需要
改变vec4 vColor
并以与main方法中相同的方式使用它

解释一下这些是什么:

  • 属性和统一非常相似,但属性是逐顶点的,而统一是逐绘制调用(对于所有顶点、片段将具有相同的值)。它们都是为了在CPU和GPU之间产生通信而设计的(您可以通过这两种方式之一将数据发送到GPU)
  • 变化无常有点不同。通常从属性指定一个变量,并在顶点着色器中完成。这意味着每个顶点都有自己的属性值,但在光栅化完成后,每个不同的值都将根据片段相对于边界顶点的位置进行插值。因此,设计了一个变量来在顶点和片段着色器之间通信(将数据从顶点发送到片段着色器)
在一条由2个点定义的直线上进行解释是最容易的,假设在渲染缓冲区上,这条直线需要100个像素。如果第一行有白色
C1=(1,1,1,1)
,第二点有黑色
C2=(0,0,0,1)
。您将在顶点着色器中为不同的值指定相同的颜色,片段着色器将被调用100次,这是针对每个像素的。现在,片段着色器中的不同颜色将具有位置
X
的插值,如中所示

color=C1+(C2-C1)*((X-A).length()/(B-A).length())

所以对于100像素的情况,第46个像素是

color=(1,1,1,1)-(1,1,1,0)*(64/100)

结果是
(.36,36,36,1.0)
。 因此,像素将从
A
B
线性淡入黑色,这将产生很好的渐变效果


我希望这会让事情变得明朗一点。

太好了,这会让事情变得明朗一点。感谢您的全面回复!