问题
As part of my 2D game engine, I would like to be able set the order (from back to front) in which my sprites are rendered on screen by manipulating their z-index
. This z-index
sprite property is a floating point value which can range between the far and near planes of my orthographic projection (in the range of (-1.0, 1.0]
).
Currently, in order to minimize unnecessary texture switching, I store my sprites in an un-ordered dictionary, where the keys are textures and the values are the corresponding ordered list of sprite quads using that particular texture. This dictionary is then parsed every frame to populate a giant VBO with all of the appropriate per-vertex attributes (position
, texcoords
, and a mat4 modelview matrix
). This is great since I only need to then make one texture bind for each texture, and I have been pretty happy with its performance.
While this z-ordering issue has always been there in my code, it became really obvious when I was working with translucent textures and enabled alpha blending, as rendering sprites in the wrong order resulted in some sprites appearing opaque instead! After some testing, I have come to the following conclusions:
- The order of my texture keys matters as this determines which corresponding sprite lists are written to my giant VBO first. This basically means that all of the sprites of the first texture appear below all of the sprites of the second texture.
- If two sprites have the same texture, then the relative order of the two sprites in the sprite list associated with that texture matters (first sprite appears on the bottom again).
- If I call
glEnable(GL_DEPTH_TEST)
, then I need to set thez-index
in increasing order to match the order of the sprite list; otherwise I get incorrectly opaque sprites. - If I call
glDisable(GL_DEPTH_TEST)
, then myz-index
value I set for the sprites is (obviously) ignored, so only rules 1 and 2 apply.
My question is, given a set of translucent and opaque sprites of various textures, how can I best order my sprites in my giant VBO every frame so as to minimize texture changes? Are the rules different for handling opaque and translucent sprites (and should they be handled in separate passes)? I also read that the alpha blending functions in OpenGL are order-dependent and that there are some order-independent techniques that can be used apparently to get around this, but this went over my head, so any light that could be shed on those types of techniques would be appreciated as well.
来源:https://stackoverflow.com/questions/45139666/rendering-opaque-and-transparent-2d-sprites-using-z-index-sorting