Game Development Community

Terrain Super Shader

by Matt Vitelli · in Torque Game Engine Advanced · 05/11/2007 (9:47 am) · 32 replies

After a few late nights of programming I came up with this terrain shader. It does accurate water rendering using Jacob Dankovchik's code. It also renders a parallax mapped shoreline which unfortunately sticks out because of no blending. Detail textures also change based on elevation. This is a work in progress, but I think it's coming along nicely.

img91.imageshack.us/img91/1570/terrainshot1ex3.png
i63.photobucket.com/albums/h138/eternaldark112/terrainshot4.png
i63.photobucket.com/albums/h138/eternaldark112/terrainshot3.png
i63.photobucket.com/albums/h138/eternaldark112/terrainshot2.png
Once again, this is a work in progress. As soon as I sort out some issues I'm having with blending and fading detail textures, I may post the code.

Any feedback is greatly appreciated!

-Matt Vitelli
Page«First 1 2 Next»
#21
07/19/2007 (12:46 pm)
Bobby, could you elaborate more on the what you're trying to accomplish?
#22
07/19/2007 (1:30 pm)
Setting a detail texture for each of the textures used on the terrain. Say .....if texture[0] is present then blend with detail texture[0]...if texture[1] is present then apply detail texture[1], and so on.. then we could set a different texture to mix with each used:) I'm playing with render-monkey right now trying to get it working, but i loose myself more than anything...It actually doesn't seem all that different from what your doing, just instead of height determining where the detail is, it weather a certain texture is there or not.....I hope I can figure this out I have been trying to figure out a way to make the terrain look as close to W.O.W terrain as i can, well i at-least want to be able to display "real" textures instead of stretched and blended.
#23
07/19/2007 (1:51 pm)
Ohh..Yes, that's been something I've wanted to explore for a while. Unfortunately that won't work in the current state. There's no way to do that just through a shader. You'd need to make some changes to the terrain sysem which also poses some problems since all the textures you paint on the terrain are converted into one rendered image.
#24
07/19/2007 (2:31 pm)
Could we tie them to a single alpha map each using it to control placement?
#25
07/19/2007 (2:38 pm)
I've tried that as well without much luck. It might be worth another try though.
#26
07/19/2007 (4:09 pm)
Let me know what your progress is.... Im going to try too:0)
#27
07/19/2007 (5:52 pm)
@bobby

I think what you are trying to do sounds a lot like atlas blended terrain.
#28
07/19/2007 (6:13 pm)
I don't think I've ever looked at a hill on a sunny day and seen anything like that shown in the first image.. might want to tone down the uh.. everything.. lol.

BTW everything else sounds great.
#29
07/19/2007 (7:12 pm)
Not a very constructive comment, but alright.
#30
07/19/2007 (9:20 pm)
Yeah it is sort of....but I was thinking of different B&W opacity maps for each texture you want to tile, without making them all one file,...and not necessarily for detail textures. i would rather we-write the whole shader to make it use textures without the automatic mipmapping if thats the correct term. i dont care if i can see the repeating pattern from far back, my character will always pretty much be at ground level.(Sorry to use this example yet again!!) W.O.W. textured terrain is what im looking for...full bright colors blended only where it fades from one texture to the next:)...Does anyone know why our terrain shaders make the texture look so blocky looking...maybe that's a good question to ask,... is there some kind of texture fogging going on?? We all just want good looking terrain i dont care how we all get there, but between us all we should be able to come up with a solution to make us smile:)
#31
07/19/2007 (10:04 pm)
In HLSL you have a set of coordinates just like you would anywhere else. (Take Constructor for example, you can enter in UV coordinates to move/scale/rotate the texture, it's like this in HLSL) This is just one example of it. I have explored fog methods in Legacy basically using the atlas detail shaders as an example. This is based off of the dot product terrain detail chapter in shaderX4. This shader was mainly for testing and should not be thought of as a final, usable shader. The fog cutoff values were mostly trial and error to see what looked good.

Pixel Shader:
//Copyright 2007 Matt Vitelli
//-----------------------------------------------------------------------------
// Structures                                                                  
//-----------------------------------------------------------------------------
#define IN_HLSL
#include "../shdrConsts.h"

struct ConnectData
{
   float2 texCoord        : TEXCOORD0;
   float2 fogCoord        : TEXCOORD1;
   float2 lightMapCoord   : TEXCOORD2;
   //float2 detCoord        : TEXCOORD3;
   float2 lowFreqUV		  : TEXCOORD3;
   float2 midFreqUV		  : TEXCOORD4;
   float2 midFreqUV2	  : TEXCOORD5;
   float2 highFreqUV	  : TEXCOORD6;
   float  detFog		  : TEXCOORD7;
};


struct Fragout
{
   float4 col : COLOR0;
};


//-----------------------------------------------------------------------------
// Main                                                                        
//-----------------------------------------------------------------------------
half4 unpackSigned( half4 value )
{
	return value * 2 - 1;
}

half dotOp(half4 a, half4 b)
{
return dot(a.rgb, b.rgb) + a.a * b.a;
}

half3 lerpOp(half3 a, half3 b, half t)
{
return a + t * (b - a);
}

Fragout main( ConnectData IN,
              uniform sampler2D diffuseMap      : register(S0),
              uniform sampler2D fogMap          : register(S1),
              uniform sampler2D lightMap        : register(S2),
              uniform sampler2D ColorMapSampler : register(S3),
              uniform sampler2D PackedDetail0Sampler : register(S4),
              uniform sampler2D PackedDetail1Sampler : register(S5),
              uniform sampler2D ColorDetailSampler : register(S6)
              )
{
   Fragout OUT;
   
   float4 diffuseColor = tex2D(diffuseMap, IN.texCoord);
   diffuseColor *= tex2D(lightMap, IN.lightMapCoord) * 4.0;
	
	half4 lowColor = tex2D(	ColorMapSampler, IN.lowFreqUV );
	half4 midDetailLayers =	unpackSigned( tex2D( PackedDetail0Sampler, IN.midFreqUV	) );
	half4 highDetailLayers = unpackSigned( tex2D( PackedDetail1Sampler,	IN.highFreqUV )	);
	half4 highColor	= tex2D( ColorDetailSampler, IN.midFreqUV2 );
	
	// unpack and calculate	detail intensities
	half midDetails	= dotOp( midDetailLayers, float4(1,1,1,1) );
	half highDetails = dotOp( highDetailLayers,	float4(1,1,1,1) );
	
	// add medium frequency	details
	half3 diffuse =	lowColor.rgb + midDetails;
	
	// calculate combined opacity for color	details
	half colorMask = 0.5 * highColor.a;
		
	// apply color details
	half4 o	= (lerpOp( diffuse, highColor.rgb, colorMask	),0.5); 
		// add high	frequency details to color details
		o =	o +	highDetails;
   
   float4 fogColor     = tex2D(fogMap,     IN.fogCoord);

   //float4 detailColor = tex2D(detailMap, IN.detCoord);
   float4 o2 = lerp(float4(0.5, 0.5, 0.5, 1), o * 0.8, IN.detFog);

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

Vertex Shader:
#define IN_HLSL
#include "../shdrConsts.h"
//Copyright 2007 Matt Vitelli
//-----------------------------------------------------------------------------
// Structures                                                                  
//-----------------------------------------------------------------------------
struct VertData
{
   float2 texCoord        : TEXCOORD0;
   float4 position        : POSITION;
   float3 normal          : NORMAL;
};


struct ConnectData
{
   float4 hpos            : POSITION;
   float2 texCoord        : TEXCOORD0;
   float2 fogCoord        : TEXCOORD1;
   float2 lightMapCoord   : TEXCOORD2;
   //float2 detCoords       : TEXCOORD3;
   float2 lowFreqUV		  : TEXCOORD3;
   float2 midFreqUV		  : TEXCOORD4;
   float2 midFreqUV2	  : TEXCOORD5;
   float2 highFreqUV	  : TEXCOORD6;
   float  detFog		  : TEXCOORD7;
};

//-----------------------------------------------------------------------------
// 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.detFog = 1.0 - ( distance( IN.position, eyePos ) / 90 );
   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;
   
   OUT.lowFreqUV = IN.texCoord;
   OUT.midFreqUV = IN.texCoord * 2;
   OUT.midFreqUV2 =	OUT.midFreqUV * 3.5;
   OUT.highFreqUV =	IN.texCoord * 10;

   return OUT;
}
#32
07/20/2007 (6:31 am)
@bobby What you are asking for exist see here:
tdn.garagegames.com/wiki/WorldBuilding/Terrain/Realistic_Blended_Terrain_Using_T...

the only difference is that there is only one detail texture. But if it could be made so that there is one detail texture for every regular texture. it would be exatly what you are describing.

Plus I know have personally combined these 2 resources here for a nice effect.

This adds the detail texture controls to the editor for atlas.

www.garagegames.com/mg/forums/result.thread.php?qt=57940

and this make it so there are 2 one at 10% the repeat value of the first one.

www.garagegames.com/mg/forums/result.thread.php?qt=58025#432506


I would think that the easiest thing would then be to make it so that the set of detail textures is also defined using the same blending system that is beinge used for the blending of the main textures.

Altas blended terrain has half of the issue solved already. the maps to control the blendiong are already in place. It is just a matter of making it so that the detail texures change when the terrains main textures do.

the ultimate would be to then also modify the Atlas shader so that detail maps could be normal maps. although I would think that cold get very expensive. Of course a fall back to regular blended detail maps would need to be provided for older cards and prolly exposed in the options panel so people could turn it off if it was supported but too much of a performance hit.
Page«First 1 2 Next»