WebGL:使用纹理和颜色缓冲区

时间:2014-09-05 15:23:55

标签: javascript webgl

This question,当执行指令gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);时,OP正在报告发出警告让我思考:如果我想要一个带有两个(让我们假设:平面)形状的场景,该怎么办,一个有纹理,一个有均匀的颜色?在片段着色器的main中,如果我取消注释第二条指令并注释掉第一条指令,就像这样:

void main(void) {
    //gl_FragColor = vColor;
    gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
}

警告仍在发出,但这次是关于gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);的指示 如果我将两个都取消注释,它仍会抱怨vertexColorAttribute,因为它显然被覆盖了。
那我怎么能两个都有?我要使用两个不同的片段着色器吗?如果是这样,怎么办呢?

1 个答案:

答案 0 :(得分:1)

正确的方式是拥有两个单独的着色器,因为您要渲染它们 纹理着色。

以内存和执行时间为代价,您可能始终在顶点数据中使用颜色纹理属性,并根据您的使用情况使用某种混合。

正如您所描述的那样,您可以使用简单的加法混合,因为大多数WebGL实现在没有绑定纹理时将黑色像素[0,0,0,255]纹理绑定为默认值。

因此有类似

的东西
void main(void) {
    gl_FragColor = vColor + texture2D(uSampler, vTexCoord);
}

在未绑定纹理时渲染颜色,并在颜色为[0,0,0,0]时正确渲染绑定纹理。

有关各种blend modes

的概述,请参阅维基百科

作为一个更加昂贵的解决方案,您可以使用制服作为标志来指示您想要使用的“方法”并相应地在着色器内分支。这仍然要求所有顶点属性都可用,在某些平台上分支也非常低效。

void main(void) {
    if (uMethod == 1)
        gl_FragColor = vColor;
    else if (uMethod == 2)
        gl_FragColor = texture2D(uSampler, vTexCoord);
    else
        gl_FragColor = vColor + texture2D(uSampler, vTexCoord);
}