From one angle my shrubs look like this:
From the other, they look like this:
Solution #1:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
objects (smoke/glass/grass): Render transparent scene from furthest polygon to nearest polygon with depth buffer write disabled (glDepthMask(GL_FALSE)
). If all transparent objects are convex and do not intersect, you can sort objects instead of polygons.glBlendFunc(GL_SRC_ALPHA, GL_ONE)
and glBlend(GL_ONE, GL_ONE)
(fire, "magic" particle systems, glow): Render transparent scene in any order with depth buffer write (glDepthMask(GL_FALSE)
) disabled. Solution #2:
Use depth-peeling (google it). Especially if transparent objects intersect each other. Not suitable for particle systems and grass, which require Solution #1.
and then manually sort them on the CPU pretty much every single frame
Insertion sort works great for already sorted or partially sorted data.
There has to be a way to delegate this to the GPU...
I think you can generate grass polygons (in correct order) in geometry shader using texture that has a channel (say, alpha), that marks areas with and without grass. Requires OpenGL 4, and you probably will have to perform some kind of higher-level sorting for polygons you'll feed to shader to generate grass patches.
Individual shrubs can be rotated in vertex shader (by +- 90/180/270 degrees) to maintain correct polygon ordering if they're perfectly symmetrical in all directions.
And there's merge sort algorithm that parallelizes well and can be performed on GPU, using either GDGPU approach or OpenCL/CUDA.
However, using something like that to render 5 shrubs of grass is roughly equivalent to trying to kill a cockroach with grenade launcher - fun thing to do, but not exactly efficient.
I suggest to forget about "offloading it to GPU" until you actually run into performance problem. Use profilers and always measure before optimizing, otherwise you'll waste large amount of development time doing unnecessary optimizations.