Multiple textures in one shader with ZBuffer and alpha blending in 2D
I have a few sprite sheets and on the scene I have to render multiple pictures coming from different textures. Each object on the sprite sheet can have a different Z value (it can be beneath or above other objects). Z values of objects from distinct textures often overlap and I am also using alpha blending for transparency.
All these factors force me to sort all objects sent for rendering by their Z value ( the farthest objects are drawn first). And here the problem arises. Doing 1 render call per each texture enables to properly sort and draw just the objects from one texture at a time. Objects from 2nd texture could probably be drawn before some objects from the 1st texture dependning on their Z value. In such case I can't sort properly the objects before drawing becouse drawing would require more than textures amount render calls which is unacceptable I guess.
The only solution which came to my mind so far was to create such a fragment shader (changing sampler depending on the varying passed):
public static final String fs_Image =
"precision mediump float;" +
"varying vec2 v_texCoord;" +
"varying float v_texInd;" +
"uniform sampler2D u_tex0;" +
"uniform sampler2D u_tex1;" +
"void main() {" +
" if(v_texInd == 0.0)" +
" gl_FragColor = texture2D( u_tex0, v_texCoord );" +
" else" +
" gl_FragColor = texture2D( u_tex1, v_texCoord );" +
" if(gl_FragColor.a == 0.0)" +
" discard;" +
"}";
I don't quite like this solution but it enables me to draw all the objects even in 1 render call. In case there would be more than 2 textures I doubt this could be efficient solution.
The other alternative would be to create Z value constraints for all objects from distinct sprite sheets and then z values from different textures wouldn't overlap and I could properly sort and draw objects from multiple textures in a few render calls.
I'm wondering which of these approaches is better? Or maybe there's some better solution? I would be very grateful for any help!
As you did, first, z-order your objects. Then, let's say your pixel can come from 4 different textures and you want a one pass rendering :
The frag shader would be like this:
precision mediump float;
varying vec2 v_texCoord;
uniform vec4 u_SelectedTexture;
uniform sampler2D u_tex0;
uniform sampler2D u_tex1;
uniform sampler2D u_tex2;
uniform sampler2D u_tex3;
void main() {
glFragColor = texture2D(u_tex0, v_texCoord) * uSelectedTexture.x
+ texture2D(u_tex1, v_texCoord) * uSelectedTexture.y +
texture2D(u_tex2, v_texCoord) * uSelectedTexture.z +
texture2D(u_tex3, v_texCoord) * uSelectedTexture.w;
}
Where u_SelectedTexture is the uniform I propose you to add.
In your rendering pipeline, if you want to use u_tex1 for example, you should use something like before drawing :
glUniform4f(uniformLocation, 0.0f, 1.0f, 0.0f, 0.0f);
These are non-dependent texture reads that should not dramatically impact your rendering time.
Hope it answers to your question.
Regards !
链接地址: http://www.djcxy.com/p/37172.html上一篇: 为访问体素的多个线程获取唯一的缓冲区索引