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,因为它显然被覆盖了。
那我怎么能两个都有?我要使用两个不同的片段着色器吗?如果是这样,怎么办呢?
答案 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);
}