I have the most highly-optimized sort possible for back-to-front rendering of partially transparent objects by assuming that order of the last repaint is close to being correct. Which means that even when a huge number of these objects are present, if the character is standing still, or relatively still, the number of swaps in the drawing order is for all purposes zero. However, when the character turns abruptly, there is nothing I can do… the number of swaps skyrockets: with 2,000 objects sorted the swaps for that frame are over 1 million, and there is a significant pause in the game’s rendering. And I really do have to render 2,000 or so objects in the same frame… sigh. This post is not a question really, but I would just like anyone’s educated guess as to when graphics cards WILL SORT TRANSPARENT OBJECTS FOR YOU!!
There is the “depth peeling” technique. It requires new hardware though.
http://developer.nvidia.com/object/Interactive_Order_Transparency.html
What sorting algo are you using? Maybe you are not using the best one. Check out the “Good sort algorithms” thread: http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=Tuning;action=display;num=1066906739;start=0#0
2000 visible transparent objects? Thats a heck of a lot, how have you got so many of them?
It might be an idea to trade some accuracy for speed by grouping some of them together. Instead of sorting every particle lump them together and sort just particle systems or similar.
Then again, you should be able to use your bsp tree, quadtree etc. to cut down on the sorting time, as it divides your objects into more managable chuncks for sorting.
I have a similar problem: I’m developing a graph-visualization tool for Visual Data Mining purposes… Each node represents an association rule and is displayed as a sphere. Each node is made up of 2-3 “items”.
I was requested to implement a feature which should let the user be able to see the “contents” of a node, ie making the node transparent and displaying a colored sphere for each of the items (inside the transparent node) that make up the node.
So in the average case I have hundreds of objects in the scene. I could sort them but they are not static (I have a layout algorithm running that tries to organize the graph) and some objects (the edges that connects the various nodes) are oriented (requiring more complicated testing… I suppose).
Before trying to develop some kind of solution I searched in some OpenGL forums and there someone said that turning down Depth Writes (while maintaining Depth Test) could solve the problem.
And in fact it seems it does, all objects seem to be blended correctly.
This is how I blend my objects:
(draw Opaque Objects)
gl.glEnable(GL.GL_BLEND);
gl.glDepthMask(false);
gl.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA);
(draw transparent objects)
gl.glDisable(GL.GL_BLEND);
gl.glDepthMask(true);
glDepthMask seem to do the trick… but maybe there are some drawbacks…
I have 2000 in this particular case because I need a forest of a huge number of trees. For geometry purposes I constructed them by placing 8 half-billboards around the trunk axis at 45-degree intervals, which means that even with a forest like this one the polygon count is not going to be high. But 2000 partially-transparent-textured trees is a lot of sorting.
Yes I know all about mergesort, heapsort, quicksort / randix sort and all the other common O(log n) sorts but I decided that since the character is moving in a large world, the z-values of most objects will not change significantly with every frame, so I needed a sort algorithm that would, in a “best-case scenario” such as this one, simplify to O(n), and to answer this I developed a doubly-linked list insertion sort in which the newly-formed linked list runs in a direction contrary to the first, so that when the first is traversal there will be a minimum number of comparisons done. It should be significantly faster than, for example, quicksort in my case.
hmm… turning down Depth Writes? I’m gonna try that now…
Trees generally look better when done with alpha testing instead of blending (how many transparent leaves have you actually seen?). And because this doesn’t require any blending its order independant, so you could eliminate the sorting all together.
Go hunt out Wurm in Your Game Here if you want to see good looking trees done in this method.
wait…
(now all of your newbie alarms should be going off in your head)…
what’s the difference between alpha testing and blending? I thought …
Alpha blending uses the current framebuffer colour and the incomming colour, pushes them though your blending equation and then writes the final, combined colour to the framebuffer. So you get transparency in various forms, and because it uses the current buffer colour is usually order dependant.
Alpha testing is a simple “should I draw this pixel?” If it passes the pixel gets drawn as normal, if not it gets discarded. Its usually used for things like chain link fences, where you couldn’t realistically make the same object out of individual triangles.
If you were using blending on the trees, you can probably just remove the blending and replace it with testing.
glEnable(GL_ALPHA_TEST);
glAlphaFunc(less/greater/etc., testValue);
You probably want GL_GREATER and a test value of about 0.5, and remember to turn off blending.
The alpha test allows an incoming pixels to be ignored, depending on it’s alpha value. Alpha blending will still be done. Unless you’ve set it up to only accept opaque pixels, then there will be no transparent pixels. This is atleast how I think it works :-/
It’s usually a good idee to set the alpha test to greater than 0. Although if you’ve disabled z write, I guess it doesnt mather.
Alpha testing & no blending is definately the way to go for trees (what we call punch-through textures). No sorting required, so you can also minimise state changes - just remember to leave the depth test on! Note that you can vary the ‘jaggedness’ of the outline by tuning the alpha test value. A test of ‘0.5’ gives a nice smooth outline, ‘0.9’ gives a blocky outline (good for hard straight edges like prison bars or ventilation ducts)
For particle effects like smoke, fire, lasers, rain, etc. you should try using additive blending (dest = dest + source) as this also doesnt require sorting.
Note that fill-rate on pretty much all graphics cards will drop by half if you turn any form of alpha blending on (additive included) - so catogorising the trees as simply ‘punch through’ will gain you CPU time (no sorting), fewer state changes (better vertex throughput) and double fill rate.
- Dom
wow… what a concept… 2000 trees without sorting at all… imagine the possibilities… lol i’m trying this right now, thanks a lot
what the… you mean this is all I had to do? No depth test function accounting for matrix transformations? No optimized sort? I’m not sure I should be happy or upset!
Without sorting, my 2000 trees are now rendered 30% faster 8)
Hi, by searching through the forum for information on the particle effect like fire, water etc… i fell on this topic.
However i am quite new to using particle system so i would need some advice and guidance.
I have seen the demo about particle engines but they are all using a image with a black background.
This made me wondering, How can i create a fire effect in a room, for example with a torch on the wall so it looks like a fire without this black background. Is the additive blending the way to do so? If so, it would be great if you could explain it in details to me so i can try to include the technique to produce the different effects i have in mind.
Thanks