Jump to content
  • Advertisement
Sign in to follow this  
Hiyar

Another Terrain Texturing question

This topic is 3609 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

How do I implement splatting in pixel shader, so that distant parts of the terrain are rendered with low res terrain texture (without detail texture). For blending I do something like this at the end: ... Res = lerp(Temp, Mat, Blend.a) * Bas Bas is low-res terrain texture for the entire terrain. and what about lighting? I'm just doing normal mapping and this is to expensive for distant parts. Thanks

Share this post


Link to post
Share on other sites
Advertisement
I ussually split the terrain texturing into 2 parts, a basic layer and a detailed layer. The detailed layer is a mix of tiled textures that use vertex(or pixel) weights. The basic layer is just 1 big texture that covers the entire terrain. Farcry/Crysis use a similiar technique, and if you look at the detail textures you will notice that these are heavily satured/grayscaled. The green grass color does not come from the detail texture, its from the base layer.

This combination allows to blend between the basic texture for far-away terrain parts:
result = lerp( detailLayer * baseLayer, baseLayer, distanceFactor )

Everything too far away could use another shader that simply does the base-layer, or an IF statement in your shader to skip the detail-layer part works ok nowadays as well. Furthermore, the detail layer textures can use mipmapping to smooth further.


The lighting is another thing. The base layer texture I was talking about, can also be used as a lightMap. Cheap and simple, but no dynamic lighting. Although you could mix static and dynamic light here. If you don't plan day-night cycle stuff, you could bake the sun or moonlight into the base-layer texture. Extra lights can be projected on top with shadowMaps. If you want a more dynamic solution, you might want to try an Ambient Occlusion map for the sun light. With an AO map, you can still change the sun position/color.

Greetings,
Rick

Share this post


Link to post
Share on other sites
Thanks for reply.

I'm actually using FarCry terrain textures. It is true, the detail textures are grayscale textures.

I tried your blending formula, but I don't know, what might be a right value for distanceFactor.

Blending works but the distant parts are brighter and the detail parts are darker.

Thanks!

Share this post


Link to post
Share on other sites
Ah, I noticed that problem. If you look at the FarCry shaders, they are multiplying the detailed result with 2 if I remember correctly. You should play around with a multiplication factor in the shader, something like

baseColor = tex2D( baseLayer, baseTexCoords )

detailColor = tex1 * weights.x + tex2 * weights.y + ...
detailColor*= 2 <or another value>

result = lerp( detailColor * baseColor, baseColor, distance )

I think the actual FarCry shader did something more though, but this simple trick might do the job already. The distance factor is a matter of personal taste as well. The detailed Layer should be completely invisible at the point you won't see the low-res quality of the base layer anymore.... 30 meters? I don't know, just try to tweak your distance factor:
distanceFactor = saturate( pixelCameraDistance / maxDetailRange )

The range where the detailed texture is used as well can make use of mipmaps in the detail textures to create a more smoother transition.

Rick

Share this post


Link to post
Share on other sites
Thanks,
Multiplying detailed result by 2 fixed the problem. Blending looks fine now.

For dynamic lighting, how do I calculate tangent space vectors in the vertex shader?

Thanks

[Edited by - Hiyar on November 10, 2008 7:57:37 AM]

Share this post


Link to post
Share on other sites
>> For dynamic lighting, how do I calculate tangent space vectors in the vertex shader?

Sure you need this? Until Crysis lots of terrains did not use normalMapping for the little details. You can use a global normalMap that is stretched over the entire terrain for large details such as cracks in a mountain though. If you are planning to use that, keep in mind that you don't need to mess around with tangents. Just generate that normalMap in 'absolute space' instead of tangent space, which means the pixel color on the normalMap texture represents the world 3D vector, not a local vector.

If you need tangents anyway, I wouldn't calculate them in the vertex shader. There are dozens of examples on the internet where they calculate tangents and biTangents for a group of triangles, and that code is relative intensive for a shader. In fact, I'm not even sure if you can calculate the tangent in a shader with just a normal! Maybe its possible though, you might want to take a look at shaders & animated characters where the normals, and thus also tangents, continously change.

Unless you are planning really wacky terrains, you can pre-calculate all the normal/tangent/biTangents. Store them along with the vertices/texcoords/normals from your terrain. If your terrain deforms (explosion crater), recalculate the tangents for that spot on the terrain.

Greetings,
Rick

Share this post


Link to post
Share on other sites
How is it done for Crysis, as far as I know there are normalmap textures for each individual detail map.

I don't want the tangents as vertex input, because I have implemented terrain rendering almost the same like explained in this paper-> 5.4 Terrain Rendering. ati.amd.com/developer/SIGGRAPH07/Chapter5-Andersson-Terrain_Rendering_in_Frostbite.pdf
So I'm using a single shared vertex buffer, and I don't want to waste memory for tangents etc.

Share this post


Link to post
Share on other sites
Heres a trick...only for heightmaps without overhangs, etc.

Just use a flat normal and tangent:

normal= 0,1,0
tangent= 1,0,0
binormal= cross(normal, tangent)

then you can do normal mapping correctly with no precalculation...however, this means that you must have a special normal map that has the main normals calculated from the actual hieghtmap...any detail normal maps must be added to that the large normal map in the pixel shader...like this:

float3 addnormal=lerp(detailnorm.rgb,macronorm.rgb,0.35);
float distSq = 1 - (dot( 2 * (addnormal.xyz - 0.5), 2 * (addnormal.xyz - 0.5)));
addnormal = (distSq*(addnormal-0.5))+(2*(addnormal-0.5));

..........

I use this method because I have a vertex-texture-based terrain (meaning the terrain mesh itself has no inherent vertex normals). You would have to scale the values of your large normal map depending on how steep the final terrain is...

Share this post


Link to post
Share on other sites
Thanks, I will look into your suggestion.


Another question:
For now, I'm using Crysis and FarCry terrain textures(exported from editor). How are these low-res terrain textures are generated. Using low-res colormaps?

[Edited by - Hiyar on November 23, 2008 7:01:23 AM]

Share this post


Link to post
Share on other sites
I dont know how its generated in Crysis, but a good bet is this:

at the start of the app render the terrain to texture from the top down, using an ortho projection, with the splatting textures and no lighting. Then in your game project the texture using that matrix...This is how I do it.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!