Game Development Community

T3D 1.1 Beta 1/2 - Still broken MeshCulling? [With Fix for T3D Beta 1] - LOGGED

by Alfio Saitta · in Torque 3D Professional · 04/14/2010 (5:06 pm) · 10 replies

During an test with a Shape with MultiMesh, i have activated the option for the MeshCulling. That what you see in the video is the result. Is there a solution to this error?


Apparently the culling is calculated on the submesh, and not on the hidden polygons (I misunderstood the concept of MeshCulling). In any case, seems to be inversely calculated. Theoretically, the furthest SubMesh should disappear, not the one near the camera. Even the shadows generate artifacts.

new TSStatic() {
      shapeName = "art/buildings/Block001.dts";
      playAmbient = "1";
      meshCulling = "1";
      receiveSunLight = "1";
      receiveLMLighting = "1";
      useCustomAmbientLighting = "0";
      customAmbientLighting = "0 0 0 1";
      collisionType = "Visible Mesh";
      decalType = "Collision Mesh";
      allowPlayerStep = "1";
      renderNormals = "0";
      forceDetail = "-1";
      position = "0.749468 -96.6491 0.506469";
      rotation = "1 0 0 0";
      scale = "5 5 5";
      canSave = "1";
      canSaveDynamicFields = "1";
      Enabled = "1";
   };

Also. With an Shape with just over 1 million polygons, because it was counted as above 8 million polygons? With MeshCulling, the number of polygons counted by polycount is fell below 3 million, but rarely drop below 1 million into areas with very few polygons on the screen.

#1
04/20/2010 (5:07 am)
Anything new?
#2
04/22/2010 (2:06 pm)
I haven't seen this in my testing here, but it could be because of the models i used to do it.

If you can drop me one of your models that exhibits the problem at tom@sickheadgames.com i should be able to test it and post a fix. Seems like a simple transform problem in how it does the sub-mesh culling.
#3
04/22/2010 (2:38 pm)
The error is certainly in this part of code:

tsStatic.cpp
// If we have submesh culling enabled then prepare
   // the object space frustum to pass to the shape.
   Frustum culler;
   if ( mMeshCulling )
   {
	   culler.set( state->getFrustum() );    
	   MatrixF xfm = getRenderWorldTransform();
	   xfm.mul( culler.getTransform() );
	   culler.setTransform( xfm );
	   rdata.setCuller( &culler );
   }

But I have not had time and opportunity to correct it.
#4
04/23/2010 (3:01 pm)
So i did a bunch of testing and i haven't been able to reproduced this in either the most current code or in the 1.1 beta 1 release code.

Do you happen to have any source code modifications related to TSStatic or Frustum?

EDIT: Duh... of course right after i post that i figure out the bug. The problem is we don't account for scale.
#5
04/23/2010 (3:48 pm)
So, if do not scale the object, the problem does not occur?
#6
04/23/2010 (3:50 pm)
Ok... the fix:

// If we have submesh culling enabled then prepare
   // the object space frustum to pass to the shape.
   Frustum culler;
   if ( mMeshCulling )
   {
      culler.set( state->getFrustum() );
      MatrixF xfm( true ); // CHANGE!
      xfm.scale( Point3F::One / getScale() ); // CHANGE!
      xfm.mul( getRenderWorldTransform() ); // CHANGE!
      xfm.mul( culler.getTransform() );
      culler.setTransform( xfm );
      rdata.setCuller( &culler );
   }
#7
04/23/2010 (3:54 pm)
And another little trick...

$SceneGraph::lockCull = 1;

... can be used in the console to lock the frustum culling to the current position. This lets you move the camera around and see what is getting culled out.
#8
04/23/2010 (6:20 pm)
I applied the fix and did the tests. The first thing i noticed, is the lack of reflection of the mesh in the WaterPlane. Subsequently, blocking the frustum cullingin one end of the mesh, and raising the camera, i noticed that none of the submesh had been hidden from culling. In any case, the number of polygons counted from the metrics(gfx) are lower than the previous.

Also if i go to set the far distance, the number of polygon drops dramatically, from 5M to 900K

// If we have submesh culling enabled then prepare
   // the object space frustum to pass to the shape.
   Frustum culler;
   if ( mMeshCulling )
   {
      culler.set( state->getFrustum() );
      MatrixF xfm( true ); // CHANGE!
      xfm.scale( Point3F::One / getScale() ); // CHANGE!
      xfm.mul( getRenderWorldTransform() ); // CHANGE!
      xfm.mul( culler.getTransform() );
      culler.setTransform( xfm );
      culler.setFarDist(500); // ADDED FOR TEST WITH A SAMPLE VALUE (my VisibleDistance /2)
      rdata.setCuller( &culler );
   }

img14.imageshack.us/img14/7067/screenshot00300000t.th.png img14.imageshack.us/img14/5826/screenshot00300001.th.png



#9
08/08/2010 (5:09 pm)
Update for T3D 1.1 Beta 2

My platform:

- Windows 7 64bit
- Directx SDK February 2010
- Intel Core 2 Quad Q8600
- Radeon HD 2600 Pro

The culling now works almost perfectly. But unfortunately still do not work the shadows.

img833.imageshack.us/img833/4329/immagine3v.th.png img828.imageshack.us/img828/2233/immagine4a.th.png

I also added code to change the display values. My Diff file:
diff U3B T3D/tsStatic.cpp T3D/tsStatic.cpp
--- T3D/tsStatic.cpp	Sat Aug 07 15:40:25 2010
+++ T3D/tsStatic.cpp	Sat Aug 07 15:46:18 2010
@@ -85,7 +85,9 @@
    mForceDetail = -1;
 
    mMeshCulling = false;
-
+   mNearDistance = 0.1f;// ADDED
+   mFarDistance = 500.0f;// ADDED
+
    mUseOriginSort = false;
 
    mPhysicsRep = NULL;
@@ -127,15 +129,23 @@
 
       addField( "playAmbient",   TypeBool,   Offset( mPlayAmbient, TSStatic ),
          "Enables automatic playing of the animation named "ambient" (if it exists) when the TSStatic is loaded.");
-      addField( "meshCulling",   TypeBool,   Offset( mMeshCulling, TSStatic ), 
-         "Enables detailed culling of meshes within the TSStatic. Should only be used "
-         "with large complex shapes like buildings which contain many submeshes." );
-
       addField( "originSort",    TypeBool,   Offset( mUseOriginSort, TSStatic ), 
          "Enables translucent sorting of the TSStatic by its origin instead of the bounds." );
 
    endGroup("Rendering");
 
+   addGroup("Culling");
+
+      addField( "meshCulling",   TypeBool,   Offset( mMeshCulling, TSStatic ), 
+         "Enables detailed culling of meshes within the TSStatic. Should only be used "
+         "with large complex shapes like buildings which contain many submeshes." );
+	  addField( "NearDistance", TypeF32, Offset( mNearDistance, TSStatic ), // ADDED 
+		 "Furthest Near distance fromt he camera's position to render the submeshes." ); // ADDED
+      addField( "FarDistance", TypeF32, Offset( mFarDistance, TSStatic ), // ADDED 
+		 "Furthest Far distance fromt he camera's position to render the submeshes." ); // ADDED
+
+   endGroup("Culling");
+   
    addGroup("Collision");
 
       addField( "collisionType",    TypeTSMeshType,   Offset( mCollisionType,   TSStatic ),
@@ -427,7 +437,9 @@
       xfm.scale( Point3F::One / getScale() );
       xfm.mul( getRenderWorldTransform() );
       xfm.mul( culler.getTransform() );
-      culler.setTransform( xfm );
+	  culler.setNearDist(mNearDistance); // ADDED
+	  culler.setFarDist(mFarDistance); // ADDED
+	  culler.setTransform( xfm );
       rdata.setCuller( &culler );
    }
 
@@ -512,7 +524,8 @@
 
    stream->writeFlag( mAllowPlayerStep );
    stream->writeFlag( mMeshCulling );
-
+   stream->write( mNearDistance ); // ADDED
+   stream->write( mFarDistance ); // ADDED
    stream->writeFlag( mUseOriginSort );   
    
    stream->write( mRenderNormalScalar );
@@ -560,6 +573,8 @@
 
    mAllowPlayerStep = stream->readFlag();
    mMeshCulling = stream->readFlag();  
+   stream->read( &mNearDistance ); // ADDED
+   stream->read( &mFarDistance ); // ADDED
 
    mUseOriginSort = stream->readFlag();
 
diff U3B T3D/tsStatic.h T3D/tsStatic.h
--- T3D/tsStatic.h	Sat Aug 07 15:40:44 2010
+++ T3D/tsStatic.h	Sat Aug 07 15:35:34 2010
@@ -138,6 +138,8 @@
    /// If true each submesh within the TSShape is culled 
    /// against the object space frustum.
    bool mMeshCulling;
+   F32 mNearDistance; // ADDED
+   F32 mFarDistance; // ADDED
 
    /// If true the shape is sorted by the origin of the
    /// model instead of the nearest point of the bounds.
#10
08/11/2010 (9:46 pm)
Logged as TQA-800 for the QA team to verify.