# Sorting for alpha rendering

## Recommended Posts

GuinnessKMF    122
I have all the semi-transparent objects in my scene stored in an array of a base class (this class exposes my world matrix for the object and the type of mesh to draw), I have to sort them based on distance from the camera and didn't really like the idea of looping through the array setting some property (distance, which is then used in the CompareTo) and then calling sort on my array, it seems inefficient. Is there a better way to sort my objects based on distance from the camera? And is there a way to avoid sorting objects that are just going to be clipped off-camera anyway (I always let DirectX do the clipping for me, calling draw on all objects regardless of their location, is this the way to do it? are there any tutorials on pre-clipping content)

##### Share on other sites
jkleinecke    251
I think the term you are looking for is 'culling'. Culling the scene means that you only process the objects that the camera can see.

Do some research on Octree or BSP culling. There's quite a few different methods out there, each with their own pros and cons. You'll need to weigh your options to find the best one.

##### Share on other sites
GuinnessKMF    122
Thanks, yes I meant culling...

Most of the guides I'm finding on the topic are more theoretical and don't show many examples (or really talk about implementation). I'm looking for a "best practice" approach, are there any SDK examples I should be looking at?

##### Share on other sites
devronious    108
I currently use an algorythm that marks a sorted object as sorted and then only compares unsorted objects until all objects are sorted...

[source lang = "c#"]        /// <summary>        /// Sorts the list by it's assigned draw order.        /// </summary>        /// <remarks>        /// <para>        /// Use the Screen object's NotifyDrawOrderRefreshRequired method to perform the draw        /// order assignment of the system.  Then this method will automatically be called to update the <see cref="VertexMap"/> order.        /// </para>        /// </remarks>        public void DrawOrderSort()        {            //sort list            VertexMap[] vm = new VertexMap[this.vertexMaps.Length];            for (int j = 0; j < vm.Length; j++)            {                VertexMap c = null;                for (int i = 0; i < vm.Length; i++)                {                    VertexMap v = this.vertexMaps[i];                    if (!v.Sorted)                    {                        if (c == null) c = v;                        else if (v.drawOrderIndex < c.drawOrderIndex) c = v;                    }                }                vm[j] = c;                c.Sorted = true;            }            foreach (VertexMap v in this.vertexMaps)            {                v.Sorted = false;            }            this.vertexMaps.ItemArray = vm;            this.vertexMaps.AssignOffsets();        }

There's probably a better way. I'll have to think about that myself.

##### Share on other sites
jkleinecke    251
Quote:
 Original post by GuinnessKMFThanks, yes I meant culling...Most of the guides I'm finding on the topic are more theoretical and don't show many examples (or really talk about implementation). I'm looking for a "best practice" approach, are there any SDK examples I should be looking at?

Well, there really isn't a best practice approach. Usually its hard to go wrong with Octree culling, but it depends on what type of scene you are running. A lot of the examples are pretty theoretical because its relatively easy to implement, all you do is pick a way to remove large chunks of objects from the screen.

##### Share on other sites
GuinnessKMF    122
To actually perform the alpha sort I ended up making a Comparer class that has a Camera property, so I instantiate the comparer, set it's camera property then call sort on a list(of Renderable) and the actual CompareTo(first as Renderable, other as Renderable) function just returns
Vector3.Subtract(camera.Translation, first.Translation).length.compareTo(Vector3.Subtract(camera.Translation, other.Translation).length)

That way to update the camera I just update the property on my comparer and re-sort my list.

Any glaring mistakes with my approach? The only issue I have which is too minor for me to worry about right now is that it uses the origin of an object, not it's "closest face" to determine if it should be drawn first (so a large object who's origin is far away but who's closest face is actually closer than a smaller object will be drawn incorrectly first).