Problem: iOS, WebGL and some android devices do not support hardware per pixel depth (gl_FragDepth(EXT)), resulting in the mess you see above. Reading from the rendertarget we are writing to as a workaround is not an option. (eg. reading from depth render target to draw into depth... hardware does not support this i believe) Observation: All sprites whose bounds do not intersect can be rendered without immediate z concerns. If we split all sprites into groups that contain no intersections, they can be rendered as large blocks without intense depth/pixel target switching for each sprite. (can still group sprites by texture) Above: Counter sprites grouped by no-intersectons. Note: blue group never intersects other sprites in blue group, so an intermediate depth test is not required. Same with green. Process: - Start with empty spritelist (no rectangle bounds) --Loop - Add a sprite, with bounds given. Search in spritelist[ i ] for intersecting rectangle. (Olog(n) search) - Found intersection, move to next spritelist and check again [i++] - not, add to spritelist[ i ]-- - We now have a list of spritelists, each with no intersections - TWO render targets, color and depth. One STENCIL buffer shared between each. - for each spritelist - clear stencil buffer, or just use another bit (faster) - draw into color target, using depth as input texture. Discard on depth fail with previously drawn depth (previous spritelists). Record all drawn pixels in stencil buffer. - switch target to depth, using same stencil buffer (needs monogame mod). Draw depth masked by stencil. (deferred "depth test" on itself) - DEPTH RESTORE OF SCROLL BUFFERS: same technique, downside is that there is no hardware depth. 3d sims must use unusual depth setup too. Benefits: - Renderer does not require hardware depth out. Works on iOS, non-nvidia android (and probably some 3dfx trash at this point) - If enabled on desktop, could potentially SORT sprites by z and render in order, without foregoing group-by-texture optimisation. - When enabled on desktop, can use MRTs and real depth to draw sprites single pass.- Does not need to be enabled for floor rendering. If wall rendering is changed to 3d, doesn't need to be used for that either. Downsides: - Could be slower, but is the only way to get per pixel depth on iOS. - Massive sprite overlap could stall the entire renderer. Maybe give up after a while. - Lots of effort to implement.