Game Development Community

dev|Pro Game Development Curriculum

view Occlusion blocker

by Caylo Gypsyblood · 03/13/2009 (8:44 am) · 16 comments

Some time ago i build an Occlusion blocker for TGE that use DIF, it had many unexpected bugs and problems, and was never satisfactory. This morning I decided to revisit that concept. As my game levels use more and more complex graphics and more of them, it became necessary to think of tricks and design features that would allow the same lever of detail but at a higher performance. This is just one of the tricks:

home.comcast.net/~porkcow/NowYouSee.jpg
What you see is a forest of giant high poly mushrooms. The FPS is at ~130 from that view.

home.comcast.net/~porkcow/NowYouDont.jpg
That red rectangle is the view Occlusion blocker. Now the FPS is around 180.

Used properly, the view Occlusion blocker can be a substitute for DIF zoning, if your geometry is built from DTS. Place at strategic locations to optimize level design in towns, or anyplace with large viewable areas. Of course one must be cleaver about useing them, and the effect should be mostly unnoticeable, unlike the exaggerations from my screen shots.

So on to how its done:
//////  view Occlusion blocker==============================================================
   //////
   //////-------------------------------------------------------------------------
   //////   toolsmissionEditorguiobjectBuilderGui.ed.gui
   //////      Add this at end of file :
   //////
   //////	function ObjectBuilderGui::buildVehicleBlocker(%this)
   //////	{
   //////	   %this.className = "VehicleBlocker";
   //////	   %this.addField("dimensions", "TypePoint3", "Dimensions",  "1 5 15");
   //////	   %this.process();
   //////	}
   //////
   //////-------------------------------------------------------------------------
   //////        toolsmissionEditorscriptseditorscreator.ed.cs
   //////     search for  %Environment_Item
   //////    Add this at last in Environment_Item list :
   //////
   //////	   %Environment_Item[19] = "VehicleBlocker";
   //////
   //////
   //////  Build VehicleBlocker as a thin as possible for best results  IE x=1 y=5 z=15

   RayInfo rinfo;
   if (gClientContainer.collideBox( localCamPos , pObj->getBoxCenter(), VehicleBlockerObjectType, &rinfo))
   {
	   //Test for things we want to always see...
	   if ((pObj->getType() & TerrainObjectType) == 0)
	   {
		   PROFILE_END();
		   return true;
	   }
   }
   //////  view Occlusion blocker==============================================================
Bleeding simple! Drop that in sceneTraversal.cpp right after the line(near very end of file)
bool aboveTerrain = (height <= localCamPos.z);
Find the lower RayInfo rinfo; and comment it out.
Follow the comments to add the VehicleBlocker into the mission editor objectBuilder.
There you go! Happy happy Joy joy...

This should work in TGE as well.



EDIT:04/30/2009

So as to have an 'render always' BOOL and not add any new code, i add a test for receiveLMLighting, it become a render always and will not be effected by view Occlusion blocker.


RayInfo rinfo;
   if (gClientContainer.collideBox( localCamPos , pObj->getBoxCenter(), VehicleBlockerObjectType, &rinfo))
   {
	   //// Test for things we want to always see...
	   if (pObj->receiveLMLighting)
		   if (((pObj->getType() & TerrainObjectType) == 0))
		   {
			   PROFILE_END();
			   return true;
		   }
   }
Now one may easily hide view Occlusion blocker inside a piece of mesh scenery.

#1
03/13/2009 (8:49 am)
Very interesting. I would love further information on this. Nice work
#2
03/13/2009 (8:55 am)
Fun! I'll have to check this out!
#3
03/13/2009 (9:50 am)
Well done! Now, that's useful.
#4
03/13/2009 (11:28 am)
How hard would it be to make it occlude hidden triangles instead of the whole shape thats behind it?
#5
03/13/2009 (12:08 pm)
@Adam That would be very computational expensive, if it were even possible. I recall reading at one time about video hardware that tried to do just that but it never paned out. Logically the render engine would now need to 'think' about each and every triangle and decide weather or not to render it, spending even more time then just spitting all the triangles out.
In the very end, it is not rendering the polys who slow down the FPS, as much as all the other FX(shaders dynamic light...) on top of the polys who need to be computed. The 'view Occlusion blocker' wins back the FPS by basically saying "dont even bother with whats behind this magical VehicleBlockerObjectType shape."

@Andrew This is basically like any 'render blocker' found with several other much more expensive game engines.

The line:
if (gClientContainer.collideBox( localCamPos , pObj->getBoxCenter(), VehicleBlockerObjectType, &rinfo))

Is essentially a cast ray checking for VehicleBlockerObjectType(I picked this as an unused yet already engine integrated class who had an defined object type). If one were inclined to build a new object type for the "view Occlusion blocker" this is where the check would be placed.
We then have;
if ((pObj->getType() & TerrainObjectType) == 0)
So we can be sure NOT to block TerrainObjectType object type in the case it is caught between the view and a "view Occlusion blocker"- an early bug i had with the TGE version, here is where one would add other object types they wish to NEVER occlude.
Finaly with;
PROFILE_END();
		   return true;
We tidy up the PROFILE and return to SceneGraph::treeTraverseVisit with a TRUE (in the case all the IF checks worked out). TRUE is saying, 'Yes this object is blocked from view please dont render it', actual it do not do any obj->prepRenderImage for this object, as the case is.

If you look below the 'view Occlusion blocker' code, you will see the ONLY place where Torque ever actual do any type of object occlusion, checking for objects hidden by the terrain useing if (pBlock->castRay(start, end, &rinfo)). If you wish for more precise occlusion tests this would be where to tweak it alternately if you wish to optimize even more,this bit of code could handle some at the expense of a few false positive occlusions (dont check each corner before tossing the object as hidden, but just test the center; would be a 3/4 speed improvement but only if you were already truly lugged down by mass amounts of objects).

#6
03/13/2009 (1:08 pm)
Very nice! Can this can be enabled/disabled like other mission objects?
#7
03/13/2009 (1:21 pm)
You mean like Vblock.setEnabled(false)? That would be cool, or even a distance from player behavior, so it turns on or off if the player is near or far. Possibility's are truly endless! But right now, no. If take a look at vehicleBlocker.cpp, its such a simple little thing, could easily add any functionality you need.

Its in my notebook to change the way one edit the actual VehicleBlocker shape dimensions, so it updates in world editor; but it is inline behind 2 bug fix(not related) and an world editor improvement attempt.
#8
03/13/2009 (4:27 pm)
Yeees! The proper name for the ol antiportals. You get my vote for awesome.

In your last sentence did you mean TGEA?
#9
03/14/2009 (2:33 am)
'Antiportals' that is what Unreal called them. Thanks, for the life of me i could not remember that name.

About TGEA, i build this version in TGEA1.8.1, but it is so simple in nature (unlike my earlier TGE version) that it should work with any of the Torque engine that have a sceneTraversal.
#10
03/14/2009 (1:31 pm)
Portals for "outside"!
jasonjeffrey.files.wordpress.com/2007/06/seal-of-awesomeness.jpg
#11
04/30/2009 (3:20 am)
So as to have an 'render always' BOOL and not add any new code, i add a test for receiveLMLighting once false, it become a render always and will not be effected by view Occlusion blocker.


RayInfo rinfo;
   if (gClientContainer.collideBox( localCamPos , pObj->getBoxCenter(), VehicleBlockerObjectType, &rinfo))
   {
	   //// Test for things we want to always see...
	   if (pObj->receiveLMLighting)
		   if (((pObj->getType() & TerrainObjectType) == 0))
		   {
			   PROFILE_END();
			   return true;
		   }
   }
Now one may easily hide view Occlusion blocker inside a piece of mesh scenery.
#12
05/27/2009 (1:42 pm)
Excellent resource there Caylo. I am probably going to add a few things to this and I will post those changes once I get done. There is a minor change to get this into T3D as well. Another thing to mention is it is probably a good idea to take the check out of the terrain occlusion check so this will work in zones without a terrain. Works good with the dungeon kit since it has some issues scaling out become of all of the dts stacking behind each other. Place a few of these and rotate them properly and it works like a charm.

--Josh
#13
07/29/2009 (10:39 am)
2 questions:

1. You said "Find the lower RayInfo rinfo; and comment it out."

Do I comment out just that one line, or all the code below it as well?
for (U32 i = 0; i < 3; i++)
   {
      Point3F start = (xBaseL0_s * checkPoints[i]) + localCamPos;
      Point3F end   = (xBaseL0_e * checkPoints[i]) + localCamPos;

      if (pBlock->castRay(start, end, &rinfo))
         continue;

      pBlock->getHeight(Point2F(start.x, start.y), &height);
      if ((height <= start.z) == aboveTerrain)
         continue;

      start = (xBaseL1_s * checkPoints[i]) + localCamPos;
      end   = (xBaseL1_e * checkPoints[i]) + localCamPos;

      if (pBlock->castRay(start, end, &rinfo))
         continue;

      Point3F test = (start + end) * 0.5;
      if (pBlock->castRay(localCamPos, test, &rinfo) == false)
         continue;

      PROFILE_END();
      return true;
   }

2. Once I get this compiled, how do I add an Occlusion Blocker to my mission? I don't see any examples for that...
#14
07/29/2009 (11:55 am)
Well, I figured it out...

1. ALL that code gets commented out.

2. I used the commented out section in your code above to get the ability to make the object in the editor. What threw me off is that you used the term 'VehicleBlocker' which made me think that was optional code to allow your occlusion blocker to also block vehicles...

I have to suggest you change that name! VERY misleading!
#15
04/23/2010 (7:52 am)
What would be the disadvantages of using TerrainObjectType instead of VehicleBlockerObjectType? Tested a little and it seemed to work nice. Would need to exclude WaterObjectType so far is all I have found.
#16
04/23/2010 (11:16 am)
One may use any object type they wish as the view blocking object. I expect using the terrain could lead to situations where very tall objects beyond a hills apex would be falsely occluded. It truly comes right down to your level design.

I used the VehicleBlockerObjectType simply because it was already in the engine as vestigial leftovers. Exaptation seem the best way to example the Occlusion Blocker in the most flexible manner.