[fixed]Transparent objects sorting error bug/improvement

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
mpenacho
Posts: 3
Joined: Wed Apr 29, 2009 8:03 pm

[fixed]Transparent objects sorting error bug/improvement

Post by mpenacho »

Hello,

I posted this originally to the Irrlicht .NET forum, before I realized I was in the wrong place. Posting it here. After reading some of the posts here, this may be related to some of the transparency issues other people were reporting.

I have a bunch of transparent and partially transparent images that I am moving in 3D space. I have made my own custom node to orient them towards the camera (billboard didn't quite work). I ran into one problem, and have figured out a work-around, but it involves changing Irrlicht. I'm wondering if this was noticed before, if there is a different work-around, or if my fix is interesting to anyone.

In the CSceneManager::drawAll() function

Transparent nodes are drawn after all the solid objects, and are sorted by their distance from the camera. The sorting distance is set in the constructor for TransparentNodeEntry, and is a squared distance from the node's absolute location from the camera node.

The problem is that this sorting distance should be the 'Z' coordinate in camera space, and sorting problems are preventing my scene nodes from being drawn in the correct order. On my system (OpenGL, Ubuntu 9.04), this is further complicated by what appears to be zbuffer writes being turned on when rendering the same material twice in succession, regardless of the setting of scene::ALLOW_ZWRITE_ON_TRANSPARENT, but that's a different issue and isn't concerning me at the moment.

How I've worked around this is creating a new constructor for TransparentNodeEntry that takes a camera view matrix reference instead of a camera position reference as a parameter. I then store my sorting distance based on the 'Z' coordinate of the object position transformed to camera space, and my scene renders in the correct order.

Are any of my observations/changes relevant? Thanks for reading this long-winded post. I'm fairly new to Irrlicht, and I'm in the middle of porting a graohics interface to run on top of Irrlicht, and like it so far.

Thanks

Mark Penacho
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Hmm, I would have expected that the order of the elements is kept unchanged under the matrix transformation, which would make the elements being sorted exactly the same as in the original version. But that's only a gut feeling, so I'm open for any references or test cases.
mpenacho
Posts: 3
Joined: Wed Apr 29, 2009 8:03 pm

Post by mpenacho »

Here is an example that shows what I am talking about

I have a camera positioned at (0,0,-330) and pointing towards (0.0.0).

I have a semi transparent object (OBJ1) positioned at (0,0,0)
I have a semi transparent object (OBJ2) positioned at (50,0,-1)
OBJ1 and OBJ2 are big enough, that they overlap each other in the camera view.

The constructor for the TransparentNodeEntry computes the values that will be used by the list sorting algorithm, based on dx^2 +dy^2 + dz^2 from the camera or:

OBJ1 sorting distance = (0 - 0) ^ 2 + (0 - 0) ^ 2 + (-330 - 0) ^ 2 = 108900
OBJ2 sorting distance = (0 - 50) ^ 2 + (0 - 0) ^ 2 + (-330 - (-1)) ^ 2 = 110741

so the sorting values are computed showing OBJ2 farther away the camera than OBJ1 and OBJ2 is drawn before OBJ1.

The problem: OBJ2 is further from the camera than OBJ1, but given the camera's orientation, OBJ2 is closer to the camera's view plane (which in this simple case, the distance is simply the Z delta).

So, to draw them in the correct order, the sorting distance should not be the xyz squared distance, but instead be the distance from the view plane after the object position is transformed to camera space. I accomplished this by making a new constructor for TransparentNodeEntry that takes the camera view matrix as a parameter instead of the camera position, and computes a sorting distance by transforming the object position into camera space, and then using the resulting, post-transformed, Z coordinate
Last edited by mpenacho on Thu Apr 30, 2009 10:36 pm, edited 1 time in total.
Nyxojaele
Posts: 98
Joined: Mon Sep 18, 2006 4:06 am

Post by Nyxojaele »

I have another bug that is quite similar to this one, yet not quite the same- but it involves changes to almost the exact same piece of code.

The issue is with when you have an orthogonal camera, and you're positioning (semi-)transparent objects to be visible. The distance sorting is done via the distance between the ISceneNode in question and the ICameraSceneNode that is the ActiveCamera in the ISceneManager, but in the case of an orthogonal camera, shouldn't the distance be calculated base on the distance between the ISceneNode in question, and a plane perpendicular to the direction the ActiveCamera is pointing, and passing thru the ActiveCamera?

For example: If your orthogonal ActiveCamera is at (0, 0, 10), and targetting (0, 0, 0), then an object at (0, 0, -10) should always be in front of an object at (0, 10, -11), yet depending on where the camera is positioned, either object could appear to be in front of the other.

Unfortunately, I need my project to be easily usable by other Irrlicht coders, so I can't be going and modifying the Irrlicht code from what's in the 1.5 code, and thus I don't have a patch or anything prepared, and only my theory above on how to make it work.

EDIT: My workaround in my own code was to completely exaggerate my "depth" values- making them 500 times bigger than my "X" and "Y" values, resulting in the "layers" you would see via an orthogonal camera to be 100s of units apart on the Z axis, and I'm only moving the objects around by 0-30 units on the X and Y axes.
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

Tracking bug here.
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

Hi, I've downloaded official release 1.6 and this can be observed with the particle billboards in the Quake Explorer and Demo. Their Z order with the 3D background is ok, but if multiples billboards are overlapping (as in the particles coming from the wall) the Z Depth of the billboard are not properly drawn for their alphas.
jarlsburg
Posts: 3
Joined: Tue Oct 20, 2015 5:04 am

Re:

Post by jarlsburg »

mpenacho wrote: So, to draw them in the correct order, the sorting distance should not be the xyz squared distance, but instead be the distance from the view plane after the object position is transformed to camera space. I accomplished this by making a new constructor for TransparentNodeEntry that takes the camera view matrix as a parameter instead of the camera position, and computes a sorting distance by transforming the object position into camera space, and then using the resulting, post-transformed, Z coordinate
This bug is still in irrlicht 1.8.1.

I've just fixed it for myself:

In CSceneManager.cpp replace:

Code: Select all

TransparentNodeEntry e(node, camWorldPos);
With:

Code: Select all

TransparentNodeEntry e(node, ActiveCamera->getAbsoluteTransformation());
And replace TransparentNodeEntry's ctor with:

Code: Select all

TransparentNodeEntry(ISceneNode* n, const core::matrix4& cameraViewMatrix)
    : Node(n)
{
    core::vector3df out;
    cameraViewMatrix.transformVect(out, n->getPosition());
    Distance = out.Z;
}
Perhaps a contributor could commit this change as its a simple fix that surely affects a lot of people.
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Transparent objects sorting error bug/improvement

Post by hendu »

That massively increases the cpu overhead. Consider a hundred or a thousand units.
jarlsburg
Posts: 3
Joined: Tue Oct 20, 2015 5:04 am

Re: Transparent objects sorting error bug/improvement

Post by jarlsburg »

hendu wrote:That massively increases the cpu overhead. Consider a hundred or a thousand units.
Very true. That sort of transformation should be done in a shader, however i still think a slow fix on the CPU is better than broken functionality, and someone more acquainted with irrlicht conventions and architecture can make a GPU-based fixed when they have time.
chronologicaldot
Competition winner
Posts: 685
Joined: Mon Sep 10, 2012 8:51 am

Re: Transparent objects sorting error bug/improvement

Post by chronologicaldot »

I just saved a CSceneManager class member vector3df of camToTarget (camToTarget = ActiveCamera->getTarget() - camWorldPos), set at the same time as camWorldPos. Then I passed this into the TransparentNodeEntry as a parameter ( const core::vector3df& cameraToTarget ) and set the distance based on the dot product:

Code: Select all

Distance = cameraToTarget.dotProduct( Node->getAbsolutePosition() - camera );
Another thing:
Transparent mesh buffers are not sorted in CMeshSceneNode, causing this same z-order problem. Mesh buffers are simply drawn in-order. This results in the first buffer always causing the other buffers to be invisible when they are behind it. And of course, each buffer drawn next causes the one after it to be hidden.
CuteAlien
Admin
Posts: 9643
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: [fixed]Transparent objects sorting error bug/improvement

Post by CuteAlien »

Fixed in svn trunk r6573. Can now be set with ISceneManager::setTransparentNodeSorting
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply