Wednesday, January 21, 2009

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).

No comments:

Post a Comment