Sort by depth and not by distance + naming difficulties

Discussion area about developing or extending OGRE, adding plugins for it or building applications on it. No newbie questions please, use the Help forum for that.
Post Reply
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 50

Sort by depth and not by distance + naming difficulties

Post by madmarx »

Hi everyone,

Concerning transparency sorting, right now :
- it is written at many places in the code that the sorting is done by z.
- but in fact the sorting is done by distance.
The fact that the sorting is done by distance and not z (in camera view), recently came up as a problem for one of our game, which has many 2D elements. The good thing is that until now it hasn't been a problem to anyone apparently. I would like to add the opportunity to sort by z, but there are already many places where "sort by depth" is already suggested in the names (of functions / struct) instead of "sort by distance".

The renderqueue is sorted by :
- OgreRenderQueueSortingGrouping.h/RadixSortFunctorDistance.
==>this name is great, it sorts by distance. I would propose another functor near this one, a RadixSortFunctorZ for example.
- DepthSortDescendingLess
==> this name is less good, because it does sort by distance too, not by z. (although mathematically depth and distance could be synonymous, in 3D computer graphics depth sometimes means z for me)

Then DepthSortDescendingLess calls

Code: Select all

			// Different renderables, sort by depth
             Real adepth = a.renderable->getSquaredViewDepth(camera);
		
from OgreRenderQueueSortingGrouping.h

and getSquaredViewDepth is from OgreNode :

Code: Select all

		  Real Node::getSquaredViewDepth(const Camera* cam) const
			{
				Vector3 diff = _getDerivedPosition() - cam->getDerivedPosition();

				// NB use squared length rather than real depth to avoid square root
				return diff.squaredLength();
			}
		
clearly the diff.squaredLength(); is about distance.

Question 1 :
If i were to add the opportunity to sort by z, then what do I do with the existing names?
Should I rename getSquaredViewDepth => getSquaredViewDistance?
I feel like it will give more pain to almost everyone than help people given the wide spread of these function in Ogre. Also I am not sure there is so many needs for a z .
If i use "ZSortDescendingLess" for example as a name for my sort, is it different enough from "DepthSortDescendingLess"? Or should this last one be called DistanceSortDescendingLess

Question 2 :
Is it ok with you if I simply propose a patch to get z depth, without making it to head, so that if anyone needs it from 1.9 he actually can use it?
One big issue is that there is no real place to choose 1 strategy over the other (apart from a static variable ... erk) without shaking too much the user.

Question 3:
I think transparent sorting could (not should!) be done by z anyway, not by distance, here is an explanation :
Let say
- camera is in [0;0;0], looking towards -Z.
- there is a renderable bigHuman1 is in 5,0,-9.
- there is a renderable bigHuman2 is in 0,0,-10.
- there are fragments of bigHuman1 and bigHuman2 that share the same 2D coordinates.
So obviously fragments of bigHuman1 should be closer from cam than those of bigHuman2. But with distance calculation, bigHuman2 is sorted to be closer.
There is no pure answer for these (appart shader tricks), since it highly depends on geometry. That is why z sorting could be done anyway.
What do you think?

Best regards,

Pierre

EDIT for those interested, transparent sorting is done this way :

1/ Your material's technique's pass tells if it needs transparent sorting (or if you got blending).

2/ the renderprioritygroups are created
OgrePass::getTransparentSortingEnabled
is called by
OgreTechnique::isTransparentSortingEnabled
which is called by
is used in RenderPriorityGroup::addRenderable to add it to RenderPriorityGroup::mTransparents.

3/
Later, the RenderPriorityGroup::mTransparents is sorted by :
RenderPriorityGroup::sort
which calls
RenderPriorityGroup::mTransparent.sort(camera);

mTransparent is a QueuedRenderableCollection.
So the call is : QueuedRenderableCollection::sort.
Inside this call, depending on the number of object, different sorting function are used (more or less faster, but same results).
In the end, it's always Renderable::getSquaredViewDepth(camera) that is called to make the sort.
This last function calculate the squared distance between the camera and the renderable most of the time (it does not for Rectangle2D for example).
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 50

Re: Sort by depth and not by distance + naming difficulties

Post by madmarx »

I did it , but no one else would like it.
Basically I got 1 inverse matrix calculation + multiplication + a few division for each renderable.
Also getSquaredviewDepth is used for some of other things, like lod calculations. I changed only what I needed for my precise needs (not like a surgeon, more like an elephant^^).
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
bstone
OGRE Expert User
OGRE Expert User
Posts: 1920
Joined: Sun Feb 19, 2012 9:24 pm
Location: Russia
x 201

Re: Sort by depth and not by distance + naming difficulties

Post by bstone »

For 3D objects sorting by distance makes more sense. For 2D stuff z-sorting is more appropriate. So your example is not correct - all other things equal bigHuman2 fragments should be closer to the camera because their distance is less. I remember there was another guy who stumbled upon that issue when he needed an ortho camera and the distance based sorting didn't work for him.

The sort-order rendering of transparent objects is a very crude approximation and it only sort-of works for relatively small objects. Anything large and it doesn't really matter if you sort by distance or Z in 3D. It's wrong either way. 2D is a different matter though.
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 50

Re: Sort by depth and not by distance + naming difficulties

Post by madmarx »

all other things equal bigHuman2 fragments should be closer to the camera because their distance is less
Sorry I don't exactly get it. I meant that in reality the human1 is before the human2 (clearly), but since we use distance calculation the human2 is drawn on top of human1. On the other end, I understood that you say that "distance is better, as a consequence human2 should be drawn on top", which is not convincing me, because I consider that we try to mimic the real world in the first place, not to respect some mathematical rule. Well I should take a nap :roll:, i must have misunderstood something.
The sort-order rendering of transparent objects is a very crude approximation and it only sort-of works for relatively small objects. Anything large and it doesn't really matter if you sort by distance or Z in 3D. It's wrong either way. 2D is a different matter though.
Thanks for your answer, I agree. In that case, since it would be better for at least 2D, then z would be preferable since it doesn't matter that much for 3D (so at least we have a gain for 2D elements). But as i saw, it consumes far more CPU + is harder to integrate at the moment. So it's better to keep distance for 3D, since 99% won't notice anything but a performance difference.

This last paragraph is pretty epic, it looks like i disagree with myself ^^.
Have a nice day!
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 50

Re: Sort by depth and not by distance + naming difficulties

Post by madmarx »

This patch was done on 1.9, and uses transparent sorting with Z from cam instead of distance.
Don't use it if you are not doing a 3D game :
- it is slower
- it will have a bad effect on the shadows.
Attachments
patch_19_transparentSorting.txt
sorts by z, not by distance for transparency and shadows. slower and with more bugs than by distance.
(4.51 KiB) Downloaded 96 times
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Sort by depth and not by distance + naming difficulties

Post by Kojack »

I've only just glanced at this so I might be missing something, but the inverse matrix stuff shouldn't be needed, just use a dot product.

From your patch...
Original code:

Code: Select all

    Real Node::getSquaredViewDepth(const Camera* cam) const
    {
        Vector3 diff = _getDerivedPosition() - cam->getDerivedPosition();

        // NB use squared length rather than real depth to avoid square root
        return diff.squaredLength();
    }
The patched version:

Code: Select all

    Real Node::getSquaredViewDepth(const Camera* cam) const
    {
        //Vector3 diff = _getDerivedPosition() - cam->getDerivedPosition();
        Vector3 lPos = cam->getPositionInCameraView (_getDerivedPosition());

        // NB use squared length rather than real depth to avoid square root
        return lPos.z;
    }
where getPositionInCameraView does matrix inversion.

But to get the z depth you could do:

Code: Select all

    Real Node::getSquaredViewDepth(const Camera* cam) const
    {
        Vector3 diff = _getDerivedPosition() - cam->getDerivedPosition();

        // NB use squared length rather than real depth to avoid square root
        return diff.dotProduct(cam->getDirection());
    }
(Well, you'd probably want to square that since it's called "getSquaredViewDepth", but yours didn't so I left it out of mine).
And similar for other bits of code that need it.
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 50

Re: Sort by depth and not by distance + naming difficulties

Post by madmarx »

Thanks Kojack,

you are right, your solution is far superior. I was afraid of computationnal cost of the inverse, and your suggestion avoids it so well !

That is really great!

Best regards,

Pierre
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
Post Reply