Gamestudio Links
Zorro Links
Newest Posts
AlpacaZorroPlugin v1.3.0 Released
by kzhao. 05/22/24 13:41
Free Live Data for Zorro with Paper Trading?
by AbrahamR. 05/18/24 13:28
Change chart colours
by 7th_zorro. 05/11/24 09:25
Data from CSV not parsed correctly
by dr_panther. 05/06/24 18:50
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
0 registered members (), 1,320 guests, and 6 spiders.
Key: Admin, Global Mod, Mod
Newest Members
LucasJoshua, Baklazhan, Hanky27, firatv, wandaluciaia
19053 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Page 1 of 2 1 2
Ultimate Terrain Shader #39835
01/20/05 16:40
01/20/05 16:40
Joined: Oct 2003
Posts: 4,131
M
Matt_Aufderheide Offline OP
Expert
Matt_Aufderheide  Offline OP
Expert
M

Joined: Oct 2003
Posts: 4,131
Another part of my Ultimate Shader(tm) series

This shader is probably excessive, but it seems to run fine for me and looks fantastic when applied well. It is based on the Wiki terrain multitextureing shader developed by Ventilator, Steempipe, and JCL. Here is what it does in total:

--4 color textures, blended by the rga channels of a blender texture in entskin1. entskin 2-4 then are the first three color textures, mtl.skin3 is the 4th color texture. Also blends in a shadow map in the blender's b channel

--2 detail textures, both in mtl.skin1 ..one is in the rgb channels, and the other is in the alpha.. of course you could also encode a maximum of 4 detail maps here if you wanted, using the same methods as in the texture blender. I only needed 2 detail maps.

--a tiled normalmap diffuse per-pixel lighting pass to give some bumpiness to the terrain.

--the standard vertex lighting from the WIKI example.. you could change this to make all the dynamic light per pixel, but that's really excessive..maybe later.

--finally, an environmental bumpmapping shader, applied to the 4th color texture. it uses a cubemap stored in mtl.skin4. My reason for this effect is that i wanted the 4th color, mud, to be reflective as though it's wet. You can eliminate this pass if you want.. just comment out the third pass in the technique. But it looks pretty cool(could be improved however if can find a way to environment mapping in HLSL) Then environment mapping is additionally given an attenuated view distance(sort of like a light), for speed and fogging reasons.. this can be set in the code..

OK..that's about it as far as functionality..as you can see this really just a combination of standard effects. This is a complicated, 3 pass shader that eats up about all texture stages possible, using a total of 8 textures. Its probably not elegantly or perfectly designed, but as said i get no problems. Just make sure you use a far_clip range thats not too far away. One problem with shadrs of this type(multipass) is dealing with fogging correctly. Basically i had to add fogging in the first 2 passes, relying on the attenuation in the 3rd pass to eliminate the fog altogether there. The reason this is a problem is that if you add ofging in alphabelded pass, you usually get fog color acumulation. That means the final fogging color will be differnet form the standard A6 pass.. it wil be the same rgb hues, but usually noticably lighter. In any case this can play hell with your fogging system, since models and trees for instance may not use pass material and thus will appear the wrong color when fogged..

In my game i fortunately use a 2 pass shader for about everything so i don't have a problem. However.. if you can have this issue, then you can look at the distance attentuation formula used in the third pass for the environment bump, and apply variation of this to the normal mapping pass, and elmiminate fogging from that pass. Not a perfect solution but i can't think of a better way.. in my research I've found that this problem seems general for every engine using fogging and multipass shaders.. it seems most poeple do some kind of fakery to make it work. If you are using a shader like this, dont expect to just "plug-n-play".. it takes a lot of work to make it suited to your game. I have posted this because of a user's request, not as a panacea to everyone's terrain needs.

Here are some screenshots:



Here is the script needed:
Code:
 /////////////////////////////////////////
// Title: Terrain multitexture material
// Conitec / jcl 2004
/////////////////////////////////////////
// Blends 3 textures together, according to
// the red and green channel in the first skin.
// The blue channel can be used for a shadow map.

// Skin1 - Terrain RGB blend & shadow mask
// Skin2 - Base terrain texture
// Skin3 - Red channel masked tiled texture
// Skin4 - Green channel masked tiled texture
// Skin5 - Replacement base texture for non-shader hardware
// Skin6 - Replacement detail texture for non-shader hardware

// Skill41 - Skin2 scale, float(1..50)
// Skill42 - Skin3 scale, float(1..50)
// Skill43 - Skin4 scale, float(1..50)
// Skill44 - ambient, float(-1..1)

// Based on concepts by Thomas 'ventilator' Oppl
// and Eric 'Steempipe' Hendrickson-Lambert

// Requires A6.31, VS 1.1, PS 1.1

//todo: pass real sun color
//todo: blend 2 more textures on blue and alpha in a second pass

bmap terrain_normal = <terrain_bump.tga>;
bmap grass_detail = <grass_detail.tga>;
bmap mud = <dirt_1.tga>;
bmap reflect=<reflect_1+6.tga>;

MATERIAL mtl_terrainmulti3
{
skin1=terrain_normal;
skin2=grass_detail;
skin3=mud;
skin4=reflect;
flags=tangent;
}


// C-Script stuff /////////////////////////////////////////////////////

define ScaleSkin2,SKILL2;
define ScaleSkin3,SKILL3;
define ScaleSkin4,SKILL4;

// uses: ScaleSkin2 ScaleSkin3 ScaleSkin4

action terrain_multi3
{
ent_terrain=me; //set this as the terrain entity for script stuff
my.material = mtl_terrainmulti3;

if (my.ScaleSkin2) {
my.skill41 = my.ScaleSkin2; }
else {
//entry: Skin2 default scale
//help: Number of tiles in x/y direction for Skin 2 (Base Texture).
//help: Set this to 1 for an untiled texture.
my.skill41 = 40; }

if (my.ScaleSkin3) {
my.skill42 = my.ScaleSkin3; }
else {
// entry: Skin3 default scale
// help: Number of tiles in x/y direction for Skin 3 (red masked texture).
my.skill42 = 40; }

if (my.ScaleSkin4) {
my.skill43 = my.ScaleSkin4; }
else {
// entry: Skin4 default scale
// help: Number of tiles in x/y direction for Skin 4 (green masked texture).
my.skill43 = 35; }

my.skill41 = float(my.skill41);
my.skill42 = float(my.skill42);
my.skill43 = float(my.skill43);
my.skill44 = float(my.skill1/1000);

}



starter mtl_terrain_init
{
bmap_to_mipmap(terrain_detail);
bmap_to_mipmap(grass_detail);
bmap_to_mipmap(mud);
bmap_to_cubemap(bmap_to_mipmap(reflect));
effect_load(mtl_terrainmulti3,"terrain.fx");
}



here is the terrain.fx file:
Code:
 //Ultimate terrain shader, based on work by Ventilator, SteemPipe, JCL and others
//by Matt Aufderheide Jan 2005

float4x4 matWorld;
float4x4 matWorldInv;
float4x4 matWorldView;
float4x4 matView;
float4x4 matWorldViewProj;

float4 vecSunDir;
float4 vecSunPos;
float4 vecSunDiffuse = float4(200.f/255.f, 200.f/255.f, 200.f/255.f, 1.f);
float4 vecFog;
float4 vecLight;
float4 vecViewPos;

Texture entSkin1; // Red/green for blending, blue for shadow
Texture entSkin2; // Basic tiled terrain texture
Texture entSkin3; // Red masked tiled texture
Texture entSkin4; // Green masked tiled texture

Texture mtlSkin1; // normalmap
Texture mtlSkin2; // detail
Texture mtlSkin3; // detail
Texture mtlSkin4; // detail

float4 vecSkill41;
float4 vecSkill1;//sun position

float4 vecLightPos[8];
float4 vecLightColor[8];
float3 vecFalloff = float3(0.f, 0.f, 1.5f);


sampler sMaskTex = sampler_state
{
Texture = <entSkin1>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Wrap;
Addressv = Wrap;
};

sampler sBaseTex = sampler_state
{
Texture = <entSkin2>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Wrap;
Addressv = Wrap;
};

sampler sRedTex = sampler_state
{
Texture = <entSkin3>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Wrap;
Addressv = Wrap;
};

sampler normal = sampler_state
{
Texture = <mtlSkin1>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Wrap;
Addressv = Wrap;
};

sampler detail = sampler_state
{
Texture = <mtlSkin2>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Wrap;
Addressv = Wrap;
};


sampler mud = sampler_state
{
Texture = <mtlSkin3>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Wrap;
Addressv = Wrap;
};

sampler reflect = sampler_state
{
Texture = (mtlSkin4);
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
};


sampler sGreenTex = sampler_state
{
Texture = <entSkin4>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Wrap;
Addressv = Wrap;
};




////////////////////////////////////////////////////////////////////////////
// normal map

struct VS_OUTPUT
{
float4 Pos : POSITION;
float2 Tex : TEXCOORD0;
float3 Light : TEXCOORD1;
float Fog: FOG;
};

VS_OUTPUT VS(float4 inPos : POSITION, float2 Tex : TEXCOORD, float3 Normal : NORMAL, float3 Tangent : TANGENT )
{
VS_OUTPUT Out = (VS_OUTPUT)0;
Out.Pos = mul(inPos, matWorldViewProj); // transform Position

// compute the 3x3 tranform matrix
// to transform from world space to tangent space
float3x3 worldToTangentSpace;
worldToTangentSpace[0] = mul(Tangent, matWorld);
worldToTangentSpace[1] = mul(cross(Tangent, Normal), matWorld);
worldToTangentSpace[2] = mul(Normal, matWorld);

Out.Tex = Tex.xy;

Out.Light.xyz = mul(worldToTangentSpace, vecSunPos);

float3 PosWorld = normalize(mul(inPos, matWorld));

// Add fog
float3 PositionWorld = mul(inPos, matWorld);
float ofog = 1 - (distance(PositionWorld, vecViewPos) - vecFog.x) * (vecFog.z*1.5);
Out.Fog = ofog;

return Out;
}

float4 PS(float2 Tex: TEXCOORD0, float3 Light : TEXCOORD1) : COLOR
{
float4 color = 1;// tex2D(sBaseTex, (Tex*8)); // fetch color map
float3 bumpNormal = 2 * (tex2D(normal, (Tex*24)) - 0.5); // bump map

float3 LightDir = normalize(Light); // L

float4 diff = saturate(dot(bumpNormal, LightDir)); // diffuse comp.

float shadow = saturate(4 * diff); // compute self-shadowing term


return 0.2 * color + shadow * (color * diff );
}


//////////////////////////////////////////////////////////////////////
// return the sun light on the surface
float4 DoSunLight(float3 N)
{
// modulate the sunlight by the surface angle
return vecSunDiffuse * dot(N,-vecSunDir);
}

// return the dynamic light on the surface
float4 DoPointLight(float3 P, float3 N, int i)
{
// calculate the light ray pointing from the light to the surface
float3 D = (float3)vecLightPos[i]-P;
// calculate the angle between surface and light ray
float NdotL = dot(N,normalize(D));
// modulate the light by the surface angle
float4 Color = vecLightColor[i] * NdotL;

// calculate the light attenuation factor
float fac = 0.f;
if (NdotL >= 0.f && vecLightPos[i].w > 0.f)
{
// get the distance factor
float LD = length(D)/vecLightPos[i].w;

if (LD < 1.f)
fac = 1.f - LD;

}
return (Color * fac);
}



//////////////////////////////////////////////////////////////////////
struct TMULTI_VS_OUT // Output to the pixelshader fragment
{
float4 Pos : POSITION;
float4 Color: COLOR0;
float Fog: FOG;
float2 MaskCoord : TEXCOORD0;
float2 BaseCoord : TEXCOORD1;
float2 RedCoord : TEXCOORD2;
float2 DetailCoord : TEXCOORD4;
float2 GreenCoord : TEXCOORD3;

};


TMULTI_VS_OUT TMulti_VS(
float4 inPos : POSITION,
float3 inNormal : NORMAL,
float2 inTexCoord0 : TEXCOORD0)
{
TMULTI_VS_OUT Out;

// transform the vector position to screen coordinates
Out.Pos = mul(inPos,matWorldViewProj);

// rotate and normalize the normal
float3 N = normalize(mul(inNormal,matWorldInv));
//float3 N = normalize(inNormal);
float3 P = mul(inPos,matWorld);

Out.Color=vecSkill41.w;
// Add 6 dynamic lights (maximum for vs 1.1)
for (int i=0; i<6; i++)
Out.Color += DoPointLight(P,N,i);

float3 PositionWorld = mul(inPos, matWorld);
float ofog = 1 - (distance(PositionWorld, vecViewPos) - vecFog.x) * vecFog.z;
Out.Fog = ofog;

// scale the texture coordinates for the masked textures
Out.MaskCoord = inTexCoord0.xy;
Out.DetailCoord = inTexCoord0.xy*200;
Out.BaseCoord = inTexCoord0.xy * vecSkill41.x;
Out.RedCoord = inTexCoord0.xy * vecSkill41.y;
Out.GreenCoord = inTexCoord0.xy * vecSkill41.z;

return Out;
}


float4 TMulti_PS(TMULTI_VS_OUT In): COLOR
{
// retrieve the pixels for the textures and the masks
float4 MaskColor = tex2D(sMaskTex,In.MaskCoord);
float4 BaseColor = tex2D(sBaseTex,In.BaseCoord);
float4 RedColor = tex2D(sRedTex,In.RedCoord);
float4 detail = tex2D(detail,In.DetailCoord);
float4 mudmap = tex2D(mud,In.BaseCoord);
float4 gloss = tex2D(mud,In.MaskCoord);

// blend the red and green textures over the base texture

float4 GreenColor = tex2D(sGreenTex,In.GreenCoord);
GreenColor.rgb *= detail.a;
float4 BaseRed = lerp(BaseColor,RedColor,MaskColor.r);
BaseRed.rgb *= detail.rgb;
float4 addmud = lerp(BaseRed,GreenColor,MaskColor.g);
float4 FinalColor=lerp(addmud,mudmap,MaskColor.w);


// Add the vertex light and shadow map, plus the entity ambient
FinalColor *= MaskColor.b + vecSkill41.w;

FinalColor *= (In.Color*2);

FinalColor.a = 1.0f; // prevent transparency
return FinalColor;
}

/////////////////////////////////////////////////////////////////////



struct VS_OUTPUT_2_0
{
float4 Pos : POSITION;
float2 Tex : TEXCOORD0;
float4 PPos : TEXCOORD1;
float3 PNorm : TEXCOORD2;
float Fog: FOG;
float3 att: TEXCOORD3;

float4 TanToCube0: TEXCOORD4;
float4 TanToCube1: TEXCOORD5;
float4 TanToCube2: TEXCOORD6;
};

VS_OUTPUT_2_0 VShader_2_0(float4 Pos : POSITION,
float3 Normal : NORMAL,
float3 Tex : TEXCOORD0,
float3 Tangent : TEXCOORD2)
{
VS_OUTPUT_2_0 Out = (VS_OUTPUT_2_0)0;

Out.PNorm = normalize(mul(Normal,matWorldView));
Out.PPos = mul(Pos, matWorldView);

Out.Pos = mul(Pos,matWorldViewProj);
Out.Tex = Tex;
Out.Fog = 10000;

float3 PosWorld = mul(Pos, matWorld);
float3 viewpos = PosWorld - vecViewPos;
Out.att = viewpos / 400;

return Out;
}


float4 PShader_2_0(VS_OUTPUT_2_0 In) : COLOR0
{
float3 P = normalize(In.PPos);
float3 N = normalize(tex2D(normal, In.Tex*100) * normalize(In.PNorm));

float3 V = -normalize(P);
float3 L = -normalize(vecSkill1);

float3 R = normalize(2 * dot(N, L) * N - L);
float3 G = normalize(2 * dot(N, V) * N - V);

float4 Diff = 0.2 * max(0, dot(N, L)) ;
float4 Spec = 0.8 * max(0, pow(dot(R, V),8));

float4 Glance = texCUBE(reflect, -G);

float4 Attenuation = saturate(dot(In.att, In.att));
float4 gloss = tex2D(sMaskTex, In.Tex);

return ((Glance + Spec + Diff)*(1 -Attenuation))*(gloss.w*0.15);
}



technique tmulti3
{
pass one
{
zenable=true;
zwriteenable=true;
sampler[0] = (sMaskTex);
sampler[1] = (sBaseTex);
sampler[2] = (sRedTex);
sampler[3] = (sGreenTex);
sampler[4] = (mud);

VertexShader = compile vs_1_1 TMulti_VS();
PixelShader = compile ps_2_0 TMulti_PS();
}

pass two
{
zenable=true;
zwriteenable=true;
alphablendenable=true;
srcblend=destcolor;
destblend=srccolor;
// compile shaders
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_0 PS();
}

pass three
{
zenable=true;
zwriteenable=true;
alphablendenable=true;

srcblend=one;
destblend=one;

VertexShader = compile vs_2_0 VShader_2_0();
PixelShader = compile ps_2_0 PShader_2_0();
}


}



Re: Ultimate Terrain Shader [Re: Matt_Aufderheide] #39836
01/20/05 20:38
01/20/05 20:38
Joined: Oct 2002
Posts: 8,939
planet.earth
ello Offline
Senior Expert
ello  Offline
Senior Expert

Joined: Oct 2002
Posts: 8,939
planet.earth
the rendermonkey glas adaption offers you environmentmapping using hlsl.
i have an fx file in my gallery-section. look out for texCUBE and reflect instructions.


www.earthcontrol.de
quoted: We want to maintain a clean, decent, American family suited forum look... which means you may post zombies or chainsaw massacres, but no erotic.
Re: Ultimate Terrain Shader [Re: Matt_Aufderheide] #39837
01/20/05 23:53
01/20/05 23:53
Joined: Dec 2004
Posts: 306
Planet Earth
Wiz Offline
Senior Member
Wiz  Offline
Senior Member

Joined: Dec 2004
Posts: 306
Planet Earth
I'm new to this shader thing and tried to apply this one to one of my terrains, but when I do so the hole terrain gets covered in white. This may just be an error in my image files, but maybe somebody can give me a correct answer?

I also have some errors whith other shaders, the most common one is my models turning out completely black. Anybody have a clue?

Re: Ultimate Terrain Shader [Re: Wiz] #39838
01/21/05 03:25
01/21/05 03:25
Joined: Oct 2003
Posts: 4,131
M
Matt_Aufderheide Offline OP
Expert
Matt_Aufderheide  Offline OP
Expert
M

Joined: Oct 2003
Posts: 4,131
It could be your card doesn't support shader model 2.0..what card do you have?
@ ello.. thanx I will take a look at it.

Re: Ultimate Terrain Shader [Re: Matt_Aufderheide] #39839
01/21/05 05:20
01/21/05 05:20
Joined: Jun 2004
Posts: 241
muralist Offline
Member
muralist  Offline
Member

Joined: Jun 2004
Posts: 241
Hi Matt,
I set up the scripts as follows:

in main wdl --

bind <terrain.fx>;
include <terrain.wdl>;

saved the fx part as terrain.fx

created the images

Errors when run:

<ent_terrain=me>
terrain.wdl 53:0 Error (63): Parameter unknown ent_terrain

<bmap_to_mipmap(terrain_detail)>
terrain.wdl 87:0 Error (63): Parameter unknown terrain_detail


///////////////
What could be the solution to the ent_terrain=me?

I see definintions of all the other bmaps except terrain_detail. Is this the cause of that error? Do I just create a terrain_detail bitmap?

Re: Ultimate Terrain Shader [Re: muralist] #39840
01/21/05 05:53
01/21/05 05:53
Joined: Oct 2003
Posts: 4,131
M
Matt_Aufderheide Offline OP
Expert
Matt_Aufderheide  Offline OP
Expert
M

Joined: Oct 2003
Posts: 4,131
Oh sory i forgot that .. you can either comment out this line, or you can put
entity* ent_terrain;

before this action. I use this so i can easily get access to the terrain entity in functions.

Re: Ultimate Terrain Shader [Re: Matt_Aufderheide] #39841
01/21/05 07:15
01/21/05 07:15
Joined: Jan 2002
Posts: 4,225
Germany / Essen
Uhrwerk Offline
Expert
Uhrwerk  Offline
Expert

Joined: Jan 2002
Posts: 4,225
Germany / Essen
Impressive, Matt, really impressive. I noticed you have fogged out the level very much. Did you reduce Clip_range in order to get a bearable framerate?


Always learn from history, to be sure you make the same mistakes again...
Re: Ultimate Terrain Shader [Re: Uhrwerk] #39842
01/21/05 07:17
01/21/05 07:17
Joined: Oct 2003
Posts: 4,131
M
Matt_Aufderheide Offline OP
Expert
Matt_Aufderheide  Offline OP
Expert
M

Joined: Oct 2003
Posts: 4,131
yes basically.. i could probably zoom it out more if i wanted.. but also its for atmosphere, this is on an Alien jungle planet.

Re: Ultimate Terrain Shader [Re: Matt_Aufderheide] #39843
01/21/05 07:52
01/21/05 07:52
Joined: Jun 2004
Posts: 241
muralist Offline
Member
muralist  Offline
Member

Joined: Jun 2004
Posts: 241
Thanks Matt.

What kinds of things can you do with scripting and the terrain?

Re: Ultimate Terrain Shader [Re: muralist] #39844
01/21/05 09:30
01/21/05 09:30
Joined: Oct 2003
Posts: 4,131
M
Matt_Aufderheide Offline OP
Expert
Matt_Aufderheide  Offline OP
Expert
M

Joined: Oct 2003
Posts: 4,131
Well. mostly i use it for move and trace commands.. such as
if you =! ent_terrain
{
my.invisible=on;
}

Page 1 of 2 1 2

Moderated by  Blink, Hummel, Superku 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1