Game Development Community

Legacy terrain detail texture

by Vincent D · in Torque Game Engine Advanced · 04/09/2007 (5:43 am) · 5 replies

Hello, I want the detail texture on legacy terrains to fade like it does on atlas. After going through the atlas and legacy code for a whole day (and now having a much better understanding) the only thing i was able to accomplish is setting the detail texture from the terrainblock in the mission file instead of the hardcoded one in the terrain material. Now ive noticed that the detail texture on atlas is being redered with its own method and own shader (TGEA 1.01).
What would be the best way of accomplishing a fading detail texture on legacy terrain. Could it be done with editing the terrainShader (have no idea how) or would it also involve some changes in the render code.

plz advice :)

#1
04/12/2007 (2:58 pm)
Its actually not that difficult but you will need to modify the shaders (and thats it actually :)).

You will need to Modify TerrainV and TerrainP from the shaders directory (back them up before you mess with them though). I haven't tested this so try to follow what I am doing so you can debug if necessary:

First add an outgoing variable from the Vertex Shader (that will go to the Pixel shader)

in TerrainV change
struct ConnectData
{
   float4 hpos            : POSITION;
   float2 texCoord        : TEXCOORD0;
   float2 fogCoord        : TEXCOORD1;
   float2 lightMapCoord   : TEXCOORD2;
   float2 detCoords       : TEXCOORD3;
};

to
struct ConnectData
{
   float4 hpos            : POSITION;
   float2 texCoord        : TEXCOORD0;
   float2 fogCoord        : TEXCOORD1;
   float2 lightMapCoord   : TEXCOORD2;
   float2 detCoords       : TEXCOORD3;
   float3  fade                : TEXCOORD4;
};

Now in the body of the Vertex shader we need to calulate distance from our camera (eye) to the vertex we are trying to render. then we will use two constants a fadestart (where we start fading) and fade out ( the amount we are fading out by every 1.0 in distance)...

//-----------------------------------------------------------------------------
// Main                                                                        
//-----------------------------------------------------------------------------
ConnectData main( VertData IN,
                  uniform float4x4 modelview       : register(C0),
                  uniform float3   eyePos          : register(VC_EYE_POS),
                  uniform float3   fogData         : register(VC_FOGDATA),
                  uniform float1   terrainsize     : register(C54)
                  )
{
   ConnectData OUT;

   OUT.hpos       = mul(modelview, IN.position);
   OUT.texCoord   = IN.texCoord;
   OUT.lightMapCoord = IN.position * terrainsize.x;
   OUT.fogCoord.x = 1.0 - ( distance( IN.position, eyePos ) / fogData.z );
   OUT.fogCoord.y = (IN.position.z - fogData.x) * fogData.y;
   OUT.detCoords = IN.position.xy * 0.12;
   
   //new code added to fade out detail textures
   float fadeStart = 30.0; //start to fade out here
   float fadeOut = 0.1;// fade amount every 1.0 distance after that
   
   //get the distance
   float eyeDist = distance( IN.position, eyePos );
   OUT.fade.x     = 1.0 - (eyeDist - fadeStart ) * fadeOut; //when this is >= 1 we get full detail, nothing at <=0
   OUT.fade.yz    = 0.f;

   return OUT;
}

That should give us a good fade value that we pass to the pixel shader
//-----------------------------------------------------------------------------
// Structures                                                                  
//-----------------------------------------------------------------------------
#define IN_HLSL
#include "../shdrConsts.h"

struct ConnectData
{
   float2 texCoord        : TEXCOORD0;
   float2 fogCoord        : TEXCOORD1;
   float2 lightMapCoord   : TEXCOORD2;
   float2 detCoord        : TEXCOORD3;
   float3 fade                : TEXCOORD4;//add our new data

};


struct Fragout
{
   float4 col : COLOR0;
};


//-----------------------------------------------------------------------------
// Main                                                                        
//-----------------------------------------------------------------------------
Fragout main( ConnectData IN,
              uniform sampler2D diffuseMap      : register(S0),
              uniform sampler2D fogMap          : register(S1),
              uniform sampler2D lightMap        : register(S2),
              uniform sampler2D detailMap       : register(S3)
              )
{
   Fragout OUT;
   
   float4 diffuseColor = tex2D(diffuseMap, IN.texCoord);
   diffuseColor *= tex2D(lightMap, IN.lightMapCoord) * 4.0;
   
   float4 fogColor     = tex2D(fogMap,     IN.fogCoord);

   float4 detailColor = tex2D(detailMap, IN.detCoord);

   //simply interpolate the detailcolor with 1 using the fade value
   detailColor = lerp (float4(1, 1, 1, 1), detailColor, IN.fade.x);

   OUT.col = lerp( diffuseColor * detailColor, fogColor, fogColor.a );
   
   
   return OUT;
}

I think I got that right... I sometimes get confused on the order in the Lerp so if you end up with detail wayout but nothing close up swap the float4(1, 1, 1, 1) and detailColor in the Lerp above and that should work.

Hope this helps

Ves

EDIT: changed 1 to float4(1, 1, 1, 1) ... been doing too much scripting and forgot how to be type sensitive for a second there
#2
04/14/2007 (12:44 am)
Thanks for responding, but with you changes i end up with a total black terrain and when i fire a projectile (with light) i can see that there is no detail texture.
#3
04/15/2007 (6:21 pm)
Then changes likely didn't compile (probably a syntax error somewhere). Check the error log file to insure the shaders compiled with the new changes (black terrian usually means the pixel shader is borked somehow). In fact I see the problem right now. fade is a float3 it should be a float4 (colors are float4 and it is lerp'd with a color so the types must match). Change it to float4 in both the vertex and pixel shader (in the connectdata struct in both locations). My bad but at least I was acurate when I said you were going to have to debug it :).

Anyway, I don't see anything else glaring right now. So that "should" compile and work (you might need to play with constants to get it to look right though.

If it doesn't compile it should tell you on the console what line it failed on so you can fix it.


Ves
#4
05/04/2007 (12:24 pm)
Ive been away for some time and been busy with some other things so that explains my late reply but,

I changed fade from a float3 to a float4 like you said and got the following compile error

example\shaders\legacyTerrain\terrainP.hlsl(13): error X4502: 'texcoord' reference exceeds valid range for this shader model (max: 4)

so i changed in client/script/shaders.cs the TerrShader to look like this
new ShaderData( TerrShader )
{
   DXVertexShaderFile   = "shaders/legacyTerrain/terrainV.hlsl";
   DXPixelShaderFile    = "shaders/legacyTerrain/terrainP.hlsl";
   //pixVersion = 1.1;
   pixVersion = 2.0;
};
and did the 'same' change in /data/materials.cs for the TerrainMaterial

but then my terrain didn't render at all (there was collision however) without compile error.
#5
06/16/2007 (12:04 pm)
After moving on with some other things i realised that the terrain not showing up problem may have been caused by my video card that didn't support pixVersion 2.0 (a GeForce 4200Ti) so i tested it again on another computer and the terrain did show up after i changed fade back to a float3 :-)
The detailmap does fade correctly now but in the distance the terrain texture looks al messed up. I think this is caused by the detailshader and terrainshader not being sepperated or something.
A screenshot to make the problem clear.
veni-studios.com/ofp/screenshot1.jpgany advice is welcome thanks in advance