With cordite in the air, splintered steel, shell casings and powder burns, there’s only one explanation...
Find or post mapping tutorials.

Moderators: Joe Kari, Pardner, Breli

Using far-clipping

Postby Joe Kari » Tue Jan 20, 2009 10:27 pm

(I apologize, I just can't post image because of blogger's hotlinking protection, if you want to see screenshots, go to my blog ;) :
http://sgq3-mapping.blogspot.com/2009/0 ... pping.html )

Why using far-clipping

Far-clipping is commonly used in every game that take place outdoor. Most of time, grass geometry are clipped (meaning not rendered) every time it is too far away from the camera's point of view.
This is used for performance issue, cause your CPU doesn't have to send this geometry to your video card, and your video card don't have to render them.

Far-clipping can be used in place where fails the famous Q3's Potential Visibility Set (known as PVS, computed by q3map2 at VIS stage). The PVS is very efficient indoor, for game just like Q3, with map that consist of rooms and corridors. Far-clipping is efficient outdoor, for big landscape, allowing nice details close to the camera, while skipping those that are too far away. It can be used too if you have some detailed objects inside a house that can't be skipped using the VIS-stage because your house has too many windows, or this object stand in front of one of them... so specifying a clipping distance allow you to remove it from the render scene, if farther than the clipping distance, only few pixels of this object remain visible.

Well, I'm sure most of you are thinking "wait a minute, I have never seen far-clipping in Q3 engine", and you are right... But I have just coded this for Smokin' Guns. And that will be available with the next release! (if you can't wait, just compile your own qvm from smokinguns.sourceforge.net)

Basic tutorial of far-clipping

Open your favorite testbox map with Radiant.
Create some brushes, add some textures to them.
Create an origin brush (a brush with the texture: common/origin). This origin brush is _very_ important, cause this will be the reference for computing distance to the camera.
Select all your newly created brushes and the origin brush, and turn them into a func_static (right-click, choose func->func_static in the menu entry).

Now open the entity window (hit the 'n' key). Add a new key for this entity: "farclip". Enter a value for this key: "sphere 800" (and hit 'return'). You should have something that looks like that:

Compile your map as you usually do, launch the game, and look at your func_static entity: every time you get close to it, it appears, every time you move far away from it, it disappears...

Setting farclip to "sphere 800" means that your func_static is magically clipped every time you are farther than 800 game units (same unit used by Radiant) from it.

Here what you get in-game:

You may want your func_static to cast shadows (unlike those screenshots), just open the entity window, and add the key "_cs" (or "_castshadows", it is the same) with a value of 1.

If you want a cubic clipping, change the value of the farclip key to "cube 800".
Here is the clipping frontier you get:

How to use far-clipping with a model

For instance only func_static support far-clipping. If you want to attach a model as func_static, you have 2 ways of doing it. First you specify this model in a "model2" key you add to a func_static entity, but this is weird cause you can't adjust anything with that.
The second way I discovered recently just consists to target your func_static. It is easy, just deselect all, select your model, select a brush which is part of the func_static, and hit Ctrl-K: an arrow will be displayed from your model to the func_static entity. If you open the entity window, you will see that your func_static has now a key named "targetname" with the same value that you will found in your model's entity window under the "target" key. Repeat this for all models you want to be part of the func_static entity (don't forget to deselect all by pressing the escape key before starting to include the next model).

Note that including one or more models to an entity works for most of entity type (including for example SG's specific entity like func_door_rotating).

Now if you want that your models cast shadows, don't forget to add "_cs" key with a value of 1 to your func_static entity!!! If you don't do that, even if you specify _cs=1 in your model pseudo-entity window, it will not work.

Here screenshots of the entity window for the func_static (left) and for the model window (right):

Here what you get in-game:

Of course, those example look stupid, but here an example where far-clipping is usefull, in the big house of Alamo, there is a lot of object that have many polys:

From these point of view they are really small, but still have the same amount of tris:

And this can't be helped by hintbrushing... because there are too many windows, not enough VIS-blocker wall...
So in the next release of Alamo, all this stuff will be clipped if you are too far away.

Important note about the origin brush!

Q3 engine assume for all entities that their bounding box are symetric along all axis!
So when you are about positionning the origin brush, move it exactly at the center of your entity, in the middle of both brushes and models that target your func_static.
If you don't do that, your entity's bounding box will be extended to get this axial symetry.
During the VIS-processing, if any part of the bounding box is visible from a cluster, all your entity will be visible too from this cluster even if there is no part of the geometry that is actually visible, but just the bounding box.

About Cvar that controle far-clipping

You can controle far-clipping in-game with three Cvar:

    * cg_farclip to enable/disable far-clipping (default value is 1, enable), useful if you don't mind far-clipping because you have a powerful computer, or for various reason (if you want to compare what you gain with far-clipping, if you want to record a nice video, etc).
    * cg_farclipValue will multiply all distances by this value (default is 1, can't be lesser than 1), if you want that clipping occurs twice farther, set it to 2.
    * cg_farclipZoomValue: the same for the sharp rifle zoom mode (default is 3, can't be lesser than 1), it is usefull to have a different value, otherwise you will be able to notice those missing brushes while zooming.

That's all for today, see you soon for the advanced far-clipping tutorial!
Last edited by Joe Kari on Fri Feb 06, 2009 1:39 pm, edited 1 time in total.
User avatar
Joe Kari
SG Team
Posts: 879
Joined: Sun Sep 16, 2007 8:44 pm
Location: France

Postby Joe Kari » Wed Jan 21, 2009 11:29 pm

(To have screenshots, go to: http://sgq3-mapping.blogspot.com/2009/0 ... grass.html )

Using far-clipping, part 2: with grass

What is wrong with the sphere clipping form

Let's say you have made a whole terrain with a lot of func_static, each func_static consists in few grass brushes. You have used "sphere 512" for each farclip key. In this example, we only display 3 grass func_static:

For each point of view:

* A. can see grass 1 and 2, that's good because 3 is too far, and behind 1, 2, and all grass brushes between 1 and 2: it is probably impossible to see it.
* B. can only see 1... just elevating the point of view make 2 too far away... this is not really fine...
* C. is so high that all 3 grass brushes are too far and aren't displayed... that's not fine.

A grass shader usually consists in an alpha-blending one. Alpha-blending needs more video-card render-power at close range (because many pixels/texels are involved) than at long-range, and if your brush is seen from above, the number of pixels/texels involved are reduced even more.
So what we need is something that clip close if we stand on the ground, but something that clip farther if we jump, or climb some crate, or join spec...

Good news: the "cone_z" clipping form is just designed for that!
It looks like that:

Now if we apply this to the previous example, we get this:

For each point of view:

* A. can see grass 1 and 2, that's good because 3 is too far, and behind 1, 2, and all grass brushes between 1 and 2: it is probably impossible to see it.
* B. and C. can see 1, 2 and 3, and that's good because 3 is no longer hidden behind 1 and 2.

More about the cone_* clipping form

Using cone_z, the cone will have Z as its axis. You can use cone_x or cone_y if you want your cone along X or Y axis.

While using cone_z, the first number is the clipping distance that occurs if your point of view has the same z-coordinate than the origin of your func_static.
The second number describe how fast the radius of the clipping distance grow up.
If you specify "cone_z x-value y-value", you get this (here x-value = y-value):

For each game-unit you move up, the clipping radius grow by one game-unit.

Setting y-value to twice the x-value, you get something like that:

This time, for each game-unit you move up, the clipping radius grow by two game-units.

Few advices

So if your grass are small and use the same color than your ground texture, I suggest using a narrow cone. If your grass is really small a simple sphere-clipping will do it better.

If your grass are rather big, using a cone_z with the first argument equal to the second is good.

If your grass is as big as human, I suggest using a wide cone. I have made some test with this setting "cone_z 512 2048", that was looking good. However, I strongly suggest you to leave some grass brushes here and there into the worldspawn (meaning not far-clipped): this will not really cost framerate drop, but this will looks definitively better.

Oh, and have you noticed that I have used numbers like 512 or 2048? This is because all value are rounded to the closest multiplier of 64 (for data compression).
User avatar
Joe Kari
SG Team
Posts: 879
Joined: Sun Sep 16, 2007 8:44 pm
Location: France

Postby Joe Kari » Fri Jan 23, 2009 7:29 pm

The last part of this tutorial just consists in images:
http://sgq3-mapping.blogspot.com/2009/0 ... art-3.html

It explains all the existing clipping-form ;)
User avatar
Joe Kari
SG Team
Posts: 879
Joined: Sun Sep 16, 2007 8:44 pm
Location: France

Return to Tutorials

Show Sidebar
Show Sidebar

User Control Panel