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

问题描述:

试图修改Android Developer OpenGL Tutorial中的三角形顶点颜色值。三角形呈现,但显得黑暗。颜色缓冲区有什么问题?OpenGL ES 2.0中片段着色器的非均匀颜色值

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; 

用下面的着色器代码,取代了原来的“均匀vec4 vColor”与属性,而不是改变,因为没有GLES20.getVaryingLocation。

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;和变化的输出为varying vec4 vColor;。然后在主要你需要分配的颜色为vColor = aColor;。在片段着色器中,您只需要varying vec4 vColor;并按照您在主要方法中使用的方法使用它。

为了解释什么,这些都有点:

  • 的属性和统一的十分相似,但属性是每个顶点,而统一为每绘图调用(将对所有顶点相同的值,片段)。它们都是为了在CPU和GPU之间进行通信而设计的(您可以通过这两种方式将数据发送到GPU)。
  • 变化有点不同。通常从属性分配变量,并在顶点着色器中完成。这意味着每个顶点将从属性中拥有自己的值,但是在光栅化完成之后,每个变化值将根据片段相对于边界顶点的位置进行插值。所以变化被设计为在顶点和片段着色器之间进行通信(从顶点发送数据到片段着色器)。

这是最简单的解释,由2点(A,B)定义的线上,并假设你的渲染缓冲区线将需要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,这将产生一个很好的渐变。

我希望这会清理一些东西。

+0

太棒了,这清除了它。感谢彻底的回应! –