[2.1+] Is F.Clustered supposed to work with ortho camera?

Discussion area about developing with Ogre2 branches (2.1, 2.2 and beyond)
Post Reply
rujialiu
Goblin
Posts: 224
Joined: Mon May 09, 2016 8:21 am
x 20

[2.1+] Is F.Clustered supposed to work with ortho camera?

Post by rujialiu » Tue Feb 26, 2019 2:29 pm

Hi!

Although 99% of the time we're using perspective camera, in some special cases we need to switch the camera mode to orthogonal, but then the screen becomes "griddy": as we move our camera, some cells suddenly becomes darker/brighter, making the cell's border clearly visible (that's why I guessed it's related to F. Clustered). So my first question is: is F.Clustered INTENDED to work with ortho camera? If so, it should be a bug and I will look into it.
0 x

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 4066
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 228
Contact:

Re: [2.1+] Is F.Clustered supposed to work with ortho camera?

Post by dark_sylinc » Tue Feb 26, 2019 5:19 pm

It should work, and it is likely a bug.

The best way to debug this is to set cluster width, height and slices to 1. If it still doesn't work, then go to ForwardClustered::collectLightForSlice and make sure that the mask in "ArrayMaskR mask" is always true so that it enters this statement:

Code: Select all

if( IS_BIT_SET( k, scalarMask ) )
If it still doesn't work, then it is likely a bug in the shader code. Could be how the projection matrix, the way the xy position in the grid is calculated, etc.

If it works, then it is likely a bug in the frustum culling code. Most likely this returns incorrect results:

Code: Select all

camera->getFrustumExtents( origFrustumLeft, origFrustumRight,
						   origFrustumTop, origFrustumBottom, FET_PROJ_PLANE_POS );
Another possibility is that ForwardPlusBase::getCachedGridFor should account for projection types, else it may think that two near-identical cameras, where the only difference is the projection type, are he same, and reuse the same result for both render passes. Which is obviously wrong.
0 x

rujialiu
Goblin
Posts: 224
Joined: Mon May 09, 2016 8:21 am
x 20

Re: [2.1+] Is F.Clustered supposed to work with ortho camera?

Post by rujialiu » Wed Feb 27, 2019 10:03 am

Thanks for the info. First, I reduce the number of threads to 1, disabled pcc and planar reflections, then tried to alter the grid size. I found 4x1x1 works (I can't use 1x1x1 because I'm using SSE and width must be multiple of 4), 4x1x2 works, but 4x1x3 doesn't work. Then I changed

Code: Select all

if( IS_BIT_SET( k, scalarMask ) )
to

Code: Select all

if( true )
It works (so shader code should be correct).

Then I reverted the if(true) change and commented out the dotResult checks, and it doesn't work. So it should mean getFrustumExtents is wrong.

And after carefully debugged the codes, I found that the frustom extents for slice 2 are ridiculously large (so one of the frustums lie completely outside the point light range, which is obviously wrong for my scene). To my knowledge, at each slice, the extents of an ortho camera should be the same, but it's still calculated from the "keep the half tangent, set near/far clip distance" method, which should be only applicable to perspective cameras.

I wonder if the whole "calculate frustom for each cell in this slice" part should follow a different path for ortho camera...
0 x

rujialiu
Goblin
Posts: 224
Joined: Mon May 09, 2016 8:21 am
x 20

Re: [2.1+] Is F.Clustered supposed to work with ortho camera?

Post by rujialiu » Wed Feb 27, 2019 10:22 am

Here is my patch. It's simply wrapped the old code with if (camera->getProjectionType() == PT_PERSPECTIVE) and get the extends from mCurrentCamera for ortho cameras. I don't know whether it's correct but it works for me :)

BTW: During the debugging I also changed nearDepthAtSlice a little bit, because in our case camera's near clip is larger than Forward Clustered's mMinDistance.

Code: Select all

OgreMain/src/OgreForwardClustered.cpp | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/OgreMain/src/OgreForwardClustered.cpp b/OgreMain/src/OgreForwardClustered.cpp
index 881ffa9..99f4a6e 100644
--- a/OgreMain/src/OgreForwardClustered.cpp
+++ b/OgreMain/src/OgreForwardClustered.cpp
@@ -314,8 +314,8 @@ namespace Ogre
         Real nearDepthAtSlice = -getDepthAtSlice( slice );
         Real farDepthAtSlice  = -getDepthAtSlice( slice + 1 );

-        if( slice == 0 )
-            nearDepthAtSlice = mCurrentCamera->getNearClipDistance();
+        if (slice == 0)
+            nearDepthAtSlice = Ogre::min(mCurrentCamera->getNearClipDistance(), nearDepthAtSlice);

         if( slice == mNumSlices - 1u )
             farDepthAtSlice = Ogre::max( mCurrentCamera->getFarClipDistance(), farDepthAtSlice );

@@ -338,16 +338,22 @@ namespace Ogre
             camera->enableReflection( mCurrentCamera->getReflectionPlane() ); 

         Real origFrustumLeft, origFrustumRight, origFrustumTop, origFrustumBottom;
-        mCurrentCamera->getFrustumExtents(origFrustumLeft, origFrustumRight,
-                                          origFrustumTop, origFrustumBottom, FET_TAN_HALF_ANGLES);
-        camera->setFrustumExtents(origFrustumLeft, origFrustumRight,
-                                          origFrustumTop, origFrustumBottom, FET_TAN_HALF_ANGLES);
-
-        camera->setNearClipDistance( nearDepthAtSlice );
-        camera->setFarClipDistance( farDepthAtSlice );
-
-        camera->getFrustumExtents( origFrustumLeft, origFrustumRight,
-                                   origFrustumTop, origFrustumBottom, FET_PROJ_PLANE_POS );
+        if (camera->getProjectionType() == PT_PERSPECTIVE) {
+            mCurrentCamera->getFrustumExtents(origFrustumLeft, origFrustumRight,
+                origFrustumTop, origFrustumBottom, FET_TAN_HALF_ANGLES);
+            camera->setFrustumExtents(origFrustumLeft, origFrustumRight,
+                origFrustumTop, origFrustumBottom, FET_TAN_HALF_ANGLES);
+
+            camera->setNearClipDistance(nearDepthAtSlice);
+            camera->setFarClipDistance(farDepthAtSlice);
+
+            camera->getFrustumExtents(origFrustumLeft, origFrustumRight,
+                origFrustumTop, origFrustumBottom, FET_PROJ_PLANE_POS);
+        }
+        else {
+            mCurrentCamera->getFrustumExtents(origFrustumLeft, origFrustumRight,
+                origFrustumTop, origFrustumBottom, FET_PROJ_PLANE_POS);
+        }

         const Real frustumHorizLength = (origFrustumRight - origFrustumLeft) / (Real)mWidth;
         const Real frustumVertLength = (origFrustumTop - origFrustumBottom) / (Real)mHeight;
0 x

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 4066
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 228
Contact:

Re: [2.1+] Is F.Clustered supposed to work with ortho camera?

Post by dark_sylinc » Wed Feb 27, 2019 4:38 pm

rujialiu wrote:
Wed Feb 27, 2019 10:22 am
BTW: During the debugging I also changed nearDepthAtSlice a little bit, because in our case camera's near clip is larger than Forward Clustered's mMinDistance.
That seems unnecessary. You're obtaining the minimum between nearDepthAtSlice and mCurrentCamera->getNearClipDistance(). Anything behind mCurrentCamera->getNearClipDistance() won't be visible. You will just be collecting more lights than you should.
0 x

rujialiu
Goblin
Posts: 224
Joined: Mon May 09, 2016 8:21 am
x 20

Re: [2.1+] Is F.Clustered supposed to work with ortho camera?

Post by rujialiu » Thu Feb 28, 2019 6:30 am

dark_sylinc wrote:
Wed Feb 27, 2019 4:38 pm
That seems unnecessary. You're obtaining the minimum between nearDepthAtSlice and mCurrentCamera->getNearClipDistance(). Anything behind mCurrentCamera->getNearClipDistance() won't be visible. You will just be collecting more lights than you should.
Yeah... you're right. I just found near > far for slice 0 in my case, which doesn't seem right. But yes, that's not a problem actually.
What about the other parts of my fix?
0 x

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 4066
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 228
Contact:

Re: [2.1+] Is F.Clustered supposed to work with ortho camera?

Post by dark_sylinc » Thu Feb 28, 2019 11:46 pm

Yeah, the rest looks alright.

Although I'm still a little worried about caching. I think the cache issue may cause bugs.
0 x

rujialiu
Goblin
Posts: 224
Joined: Mon May 09, 2016 8:21 am
x 20

Re: [2.1+] Is F.Clustered supposed to work with ortho camera?

Post by rujialiu » Wed Mar 06, 2019 2:54 am

dark_sylinc wrote:
Thu Feb 28, 2019 11:46 pm
Although I'm still a little worried about caching. I think the cache issue may cause bugs.
Do you mean new cache issues introduced by my changes, or there were already some cache issues before I made changes?
0 x

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 4066
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 228
Contact:

Re: [2.1+] Is F.Clustered supposed to work with ortho camera?

Post by dark_sylinc » Wed Mar 06, 2019 5:31 am

I meant that there were already existing bugs before your changes.

To quote myself:
Another possibility is that ForwardPlusBase::getCachedGridFor should account for projection types, else it may think that two near-identical cameras, where the only difference is the projection type, are he same, and reuse the same result for both render passes. Which is obviously wrong.
0 x

Post Reply