Terrain texturing shader(splatting)
24 posts • Page 1 of 3 • 1, 2, 3
Terrain texturing shader(splatting)
Hi,
Just started using Xors3d and know next to nothing about shaders. Anyone out there got any terrain splatting shader code they'd be prepared to share or something to get me started at least. It's the usual sort of thing I'm after ie using an rgba alphamap with 4 textures. The alphamap channels determine how much of each texture shows through.
Thanks
Just started using Xors3d and know next to nothing about shaders. Anyone out there got any terrain splatting shader code they'd be prepared to share or something to get me started at least. It's the usual sort of thing I'm after ie using an rgba alphamap with 4 textures. The alphamap channels determine how much of each texture shows through.
Thanks
-

KronosUK - Posts: 2
- Joined: Tue Feb 09, 2010 10:48 pm
Re: Terrain texturing shader(splatting)
Well, about splatting.
I haven't any working sample, but I can write a shader sample code for you.
May be you will need multiply color value, and you need add light code (I just don't know how many light sources you use and their types (directional, point or spot)).
I haven't any working sample, but I can write a shader sample code for you.
- Code: Select all
// objects world matrix
float4x4 matrixWorldViewProj : MATRIX_WORLDVIEWPROJ;
float4x4 matrixWorld : MATRIX_WORLD;
// diffuse textures for splatting
texture diffuseTexture1 : TEXTURE_0;
sampler diffuseSampler1 = sampler_state
{
Texture = <diffuseTexture1>;
AddressU = WRAP;
AddressV = WRAP;
AddressW = WRAP;
MinFilter = ANISOTROPIC;
MagFilter = ANISOTROPIC;
MipFilter = ANISOTROPIC;
MaxAnisotropy = 4;
};
texture diffuseTexture2 : TEXTURE_1;
sampler diffuseSampler2 = sampler_state
{
Texture = <diffuseTexture2>;
AddressU = WRAP;
AddressV = WRAP;
AddressW = WRAP;
MinFilter = ANISOTROPIC;
MagFilter = ANISOTROPIC;
MipFilter = ANISOTROPIC;
MaxAnisotropy = 4;
};
texture diffuseTexture3 : TEXTURE_2;
sampler diffuseSampler3 = sampler_state
{
Texture = <diffuseTexture3>;
AddressU = WRAP;
AddressV = WRAP;
AddressW = WRAP;
MinFilter = ANISOTROPIC;
MagFilter = ANISOTROPIC;
MipFilter = ANISOTROPIC;
MaxAnisotropy = 4;
};
texture diffuseTexture4 : TEXTURE_3;
sampler diffuseSampler4 = sampler_state
{
Texture = <diffuseTexture4>;
AddressU = WRAP;
AddressV = WRAP;
AddressW = WRAP;
MinFilter = ANISOTROPIC;
MagFilter = ANISOTROPIC;
MipFilter = ANISOTROPIC;
MaxAnisotropy = 4;
};
// alpha texture with blending values
texture alphaTexture : TEXTURE_4;
sampler alphaSampler = sampler_state
{
Texture = <alphaTexture>;
AddressU = WRAP;
AddressV = WRAP;
AddressW = WRAP;
MinFilter = ANISOTROPIC;
MagFilter = ANISOTROPIC;
MipFilter = ANISOTROPIC;
MaxAnisotropy = 4;
};
// vertex shader input data structure
struct VSInput
{
float4 position : POSITION;
float3 normal : NORMAL;
float2 texCoords : TEXCOORD0;
};
// vertex shader output data structure
struct VSOutput
{
float4 position : POSITION;
float3 normal : TEXCOORD1;
float2 texCoords : TEXCOORD0;
};
// vertex shader
VSOutput VSMain(VSInput input)
{
VSOutput output;
output.position = mul(input.position, matrixWorldViewProj);
output.normal = normalize(mul(input.normal, matrixWorld));
output.texCoords = input.texCoords;
return output;
}
// pixel shader
float4 PSMain(VSOutput input) : COLOR0
{
// getting diffuse colors
float4 diffuse1 = tex2D(diffuseSampler1, input.texCoords);
float4 diffuse2 = tex2D(diffuseSampler2, input.texCoords);
float4 diffuse3 = tex2D(diffuseSampler3, input.texCoords);
float4 diffuse4 = tex2D(diffuseSampler4, input.texCoords);
// getting blending weights
float4 alpha = tex2D(alphaSampler, input.texCoords);
// compute result color from all textures
float4 resultColor = diffuse1 * alpha.r + diffuse2 * alpha.g + diffuse3 * alpha.b + diffuse4 * alpha.a;
// return color value
return resultColor;
}
// effect technique
technique Splatting
{
pass p0
{
VertexShader = compile vs_2_0 VSMain();
PixelShader = compile ps_2_0 PSMain();
}
}
May be you will need multiply color value, and you need add light code (I just don't know how many light sources you use and their types (directional, point or spot)).
-

Knightmare - Posts: 335
- Joined: Thu Mar 12, 2009 1:22 am
Re: Terrain texturing shader(splatting)
Thanks very much Knightmare I will look at this over the weekend.
-

KronosUK - Posts: 2
- Joined: Tue Feb 09, 2010 10:48 pm
Re: Terrain texturing shader(splatting)
I found this very informative article about terrain texture splatting:
http://www.gamedev.net/reference/articl ... le2238.asp
Now I am trying to fiddle around with this, but since I am new to shader programming (using Blitz3D), it's still quite confusing for me. Is there any working demo code that demonstrates this kind of technique?
http://www.gamedev.net/reference/articl ... le2238.asp
Now I am trying to fiddle around with this, but since I am new to shader programming (using Blitz3D), it's still quite confusing for me. Is there any working demo code that demonstrates this kind of technique?
-

Mau - Posts: 40
- Joined: Thu Apr 29, 2010 10:32 am
Re: Terrain texturing shader(splatting)
Hi!
Xors3d have built-in splatting support for terrains, see here - viewtopic.php?f=7&t=253&start=20#p1448
Xors3d have built-in splatting support for terrains, see here - viewtopic.php?f=7&t=253&start=20#p1448
-

Knightmare - Posts: 335
- Joined: Thu Mar 12, 2009 1:22 am
Re: Terrain texturing shader(splatting)
Is this feature limited to automatically generated terrains only or can it be used with any manually created meshes as well?
-

Mau - Posts: 40
- Joined: Thu Apr 29, 2010 10:32 am
Re: Terrain texturing shader(splatting)
Only with engine terrains. But it uses a very simple shader and I can post its code here.
-

Knightmare - Posts: 335
- Joined: Thu Mar 12, 2009 1:22 am
Re: Terrain texturing shader(splatting)
This would be great. It would be very useful if you could post the splatting shader code, please.
I am porting my world editor from B3D to Xors. It allows to create and modify own terrain meshes. Now I am looking for a way to blend textures on that meshes, so using a shader method would be ideal, I think.
BTW: is it possible in any way to use more than four blend textures on a terrain or mesh?
I am porting my world editor from B3D to Xors. It allows to create and modify own terrain meshes. Now I am looking for a way to blend textures on that meshes, so using a shader method would be ideal, I think.
BTW: is it possible in any way to use more than four blend textures on a terrain or mesh?
-

Mau - Posts: 40
- Joined: Thu Apr 29, 2010 10:32 am
Re: Terrain texturing shader(splatting)
- Code: Select all
float4x4 worldViewProjMatrix : MATRIX_WORLDVIEWPROJ;
float4x4 worldViewMatrix : MATRIX_WORLDVIEW;
float4x4 texture1Matrix : MATRIX_TEXTURE0;
float4x4 texture2Matrix : MATRIX_TEXTURE1;
float4x4 texture3Matrix : MATRIX_TEXTURE2;
float4x4 texture4Matrix : MATRIX_TEXTURE3;
int filtering : TEXTURE_FILTERING;
int anisotropyLevel : ANISOTROPY_LEVEL;
bool haveLightmap : TERRAIN_LIGHTMAPPED;
float4 fogColor : FOG_COLOR;
float3 fogRange : FOG_RANGE;
texture diffuseMap1 : TEXTURE_0;
sampler samplerMap1 = sampler_state
{
Texture = <diffuseMap1>;
ADDRESSU = WRAP;
ADDRESSV = WRAP;
ADDRESSW = WRAP;
MAGFILTER = filtering;
MINFILTER = filtering;
MIPFILTER = filtering;
MAXANISOTROPY = anisotropyLevel;
};
texture diffuseMap2 : TEXTURE_1;
sampler samplerMap2 = sampler_state
{
Texture = <diffuseMap2>;
ADDRESSU = WRAP;
ADDRESSV = WRAP;
ADDRESSW = WRAP;
MAGFILTER = filtering;
MINFILTER = filtering;
MIPFILTER = filtering;
MAXANISOTROPY = anisotropyLevel;
};
texture diffuseMap3 : TEXTURE_2;
sampler samplerMap3 = sampler_state
{
Texture = <diffuseMap3>;
ADDRESSU = WRAP;
ADDRESSV = WRAP;
ADDRESSW = WRAP;
MAGFILTER = filtering;
MINFILTER = filtering;
MIPFILTER = filtering;
MAXANISOTROPY = anisotropyLevel;
};
texture diffuseMap4 : TEXTURE_3;
sampler samplerMap4 = sampler_state
{
Texture = <diffuseMap4>;
ADDRESSU = WRAP;
ADDRESSV = WRAP;
ADDRESSW = WRAP;
MAGFILTER = filtering;
MINFILTER = filtering;
MIPFILTER = filtering;
MAXANISOTROPY = anisotropyLevel;
};
texture diffuseMap5 : TEXTURE_4;
sampler samplerMap5 = sampler_state
{
Texture = <diffuseMap5>;
ADDRESSU = WRAP;
ADDRESSV = WRAP;
ADDRESSW = WRAP;
MAGFILTER = filtering;
MINFILTER = filtering;
MIPFILTER = filtering;
MAXANISOTROPY = anisotropyLevel;
};
texture lightMap : TEXTURE_7;
sampler samplerLightmap = sampler_state
{
Texture = <lightMap>;
ADDRESSU = WRAP;
ADDRESSV = WRAP;
ADDRESSW = WRAP;
MAGFILTER = filtering;
MINFILTER = filtering;
MIPFILTER = filtering;
MAXANISOTROPY = anisotropyLevel;
};
struct VSInput
{
float4 position : POSITION0;
float2 texCoords : TEXCOORD0;
};
struct VSOutput2
{
float4 position : POSITION0;
float2 texCoords1 : TEXCOORD0;
float2 texCoords2 : TEXCOORD1;
float2 texCoords3 : TEXCOORD2;
};
struct VSOutput3
{
float4 position : POSITION0;
float2 texCoords1 : TEXCOORD0;
float2 texCoords2 : TEXCOORD1;
float2 texCoords3 : TEXCOORD2;
float2 texCoords4 : TEXCOORD3;
};
struct VSOutput4
{
float4 position : POSITION0;
float2 texCoords1 : TEXCOORD0;
float2 texCoords2 : TEXCOORD1;
float2 texCoords3 : TEXCOORD2;
float2 texCoords4 : TEXCOORD3;
float2 texCoords5 : TEXCOORD4;
};
struct VSOutput2F
{
float4 position : POSITION0;
float2 texCoords1 : TEXCOORD0;
float2 texCoords2 : TEXCOORD1;
float2 texCoords3 : TEXCOORD2;
float4 position2 : TEXCOORD5;
};
struct VSOutput3F
{
float4 position : POSITION0;
float2 texCoords1 : TEXCOORD0;
float2 texCoords2 : TEXCOORD1;
float2 texCoords3 : TEXCOORD2;
float2 texCoords4 : TEXCOORD3;
float4 position2 : TEXCOORD5;
};
struct VSOutput4F
{
float4 position : POSITION0;
float2 texCoords1 : TEXCOORD0;
float2 texCoords2 : TEXCOORD1;
float2 texCoords3 : TEXCOORD2;
float2 texCoords4 : TEXCOORD3;
float2 texCoords5 : TEXCOORD4;
float4 position2 : TEXCOORD5;
};
float4 LightMap(float2 texCoords)
{
if(haveLightmap)
{
return tex2D(samplerLightmap, texCoords);
}
else
{
return float4(1.0f, 1.0f, 1.0f, 1.0f);
}
}
float FogValue(float4 position)
{
return clamp((fogRange.y - length(position.xyz)) / fogRange.z, 0.0f, 1.0f);
}
void VSMain2(in VSInput IN, out VSOutput2 OUT)
{
OUT.position = mul(IN.position, worldViewProjMatrix);
OUT.texCoords1 = mul(IN.texCoords, texture1Matrix);
OUT.texCoords2 = mul(IN.texCoords, texture2Matrix);
OUT.texCoords3 = IN.texCoords;
}
void VSMain2F(in VSInput IN, out VSOutput2F OUT)
{
OUT.position = mul(IN.position, worldViewProjMatrix);
OUT.position2 = mul(IN.position, worldViewMatrix);
OUT.texCoords1 = mul(IN.texCoords, texture1Matrix);
OUT.texCoords2 = mul(IN.texCoords, texture2Matrix);
OUT.texCoords3 = IN.texCoords;
}
void VSMain3(in VSInput IN, out VSOutput3 OUT)
{
OUT.position = mul(IN.position, worldViewProjMatrix);
OUT.texCoords1 = mul(IN.texCoords, texture1Matrix);
OUT.texCoords2 = mul(IN.texCoords, texture2Matrix);
OUT.texCoords3 = mul(IN.texCoords, texture3Matrix);
OUT.texCoords4 = IN.texCoords;
}
void VSMain3F(in VSInput IN, out VSOutput3F OUT)
{
OUT.position = mul(IN.position, worldViewProjMatrix);
OUT.position2 = mul(IN.position, worldViewMatrix);
OUT.texCoords1 = mul(IN.texCoords, texture1Matrix);
OUT.texCoords2 = mul(IN.texCoords, texture2Matrix);
OUT.texCoords3 = mul(IN.texCoords, texture3Matrix);
OUT.texCoords4 = IN.texCoords;
}
void VSMain4(in VSInput IN, out VSOutput4 OUT)
{
OUT.position = mul(IN.position, worldViewProjMatrix);
OUT.texCoords1 = mul(IN.texCoords, texture1Matrix);
OUT.texCoords2 = mul(IN.texCoords, texture2Matrix);
OUT.texCoords3 = mul(IN.texCoords, texture3Matrix);
OUT.texCoords4 = mul(IN.texCoords, texture4Matrix);
OUT.texCoords5 = IN.texCoords;
}
void VSMain4F(in VSInput IN, out VSOutput4F OUT)
{
OUT.position = mul(IN.position, worldViewProjMatrix);
OUT.position2 = mul(IN.position, worldViewMatrix);
OUT.texCoords1 = mul(IN.texCoords, texture1Matrix);
OUT.texCoords2 = mul(IN.texCoords, texture2Matrix);
OUT.texCoords3 = mul(IN.texCoords, texture3Matrix);
OUT.texCoords4 = mul(IN.texCoords, texture4Matrix);
OUT.texCoords5 = IN.texCoords;
}
float4 PSMain2(in VSOutput2 IN) : COLOR
{
float4 diffuse1 = tex2D(samplerMap1, IN.texCoords1);
float4 diffuse2 = tex2D(samplerMap2, IN.texCoords2);
float4 mask = tex2D(samplerMap3, IN.texCoords3);
return (diffuse1 * mask.x + diffuse2 * mask.y) * LightMap(IN.texCoords3);
}
float4 PSMain2F(in VSOutput2F IN) : COLOR
{
float4 diffuse1 = tex2D(samplerMap1, IN.texCoords1);
float4 diffuse2 = tex2D(samplerMap2, IN.texCoords2);
float4 mask = tex2D(samplerMap3, IN.texCoords3);
float4 result = (diffuse1 * mask.x + diffuse2 * mask.y) * LightMap(IN.texCoords3);
float fog = FogValue(IN.position2);
return fogColor * (1.0f - fog) + result * fog;
}
float4 PSMain3(in VSOutput3 IN) : COLOR
{
float4 diffuse1 = tex2D(samplerMap1, IN.texCoords1);
float4 diffuse2 = tex2D(samplerMap2, IN.texCoords2);
float4 diffuse3 = tex2D(samplerMap3, IN.texCoords3);
float4 mask = tex2D(samplerMap4, IN.texCoords4);
return (diffuse1 * mask.x + diffuse2 * mask.y + diffuse3 * mask.z) * LightMap(IN.texCoords4);
}
float4 PSMain3F(in VSOutput3F IN) : COLOR
{
float4 diffuse1 = tex2D(samplerMap1, IN.texCoords1);
float4 diffuse2 = tex2D(samplerMap2, IN.texCoords2);
float4 diffuse3 = tex2D(samplerMap3, IN.texCoords3);
float4 mask = tex2D(samplerMap4, IN.texCoords4);
float4 result = (diffuse1 * mask.x + diffuse2 * mask.y + diffuse3 * mask.z) * LightMap(IN.texCoords4);
float fog = FogValue(IN.position2);
return fogColor * (1.0f - fog) + result * fog;
}
float4 PSMain4(in VSOutput4 IN) : COLOR
{
float4 diffuse1 = tex2D(samplerMap1, IN.texCoords1);
float4 diffuse2 = tex2D(samplerMap2, IN.texCoords2);
float4 diffuse3 = tex2D(samplerMap3, IN.texCoords3);
float4 diffuse4 = tex2D(samplerMap4, IN.texCoords4);
float4 mask = tex2D(samplerMap5, IN.texCoords5);
return (diffuse1 * mask.x + diffuse2 * mask.y + diffuse3 * mask.z + diffuse4 * mask.w) * LightMap(IN.texCoords5);
}
float4 PSMain4F(in VSOutput4F IN) : COLOR
{
float4 diffuse1 = tex2D(samplerMap1, IN.texCoords1);
float4 diffuse2 = tex2D(samplerMap2, IN.texCoords2);
float4 diffuse3 = tex2D(samplerMap3, IN.texCoords3);
float4 diffuse4 = tex2D(samplerMap4, IN.texCoords4);
float4 mask = tex2D(samplerMap5, IN.texCoords5);
float4 result = (diffuse1 * mask.x + diffuse2 * mask.y + diffuse3 * mask.z + diffuse4 * mask.w) * LightMap(IN.texCoords5);
float fog = FogValue(IN.position2);
return fogColor * (1.0f - fog)+ result * fog;
}
technique Splatting2
{
pass p0
{
AlphaBlendEnable = false;
VertexShader = compile vs_2_0 VSMain2();
PixelShader = compile ps_2_0 PSMain2();
}
}
technique Splatting3
{
pass p0
{
AlphaBlendEnable = false;
VertexShader = compile vs_2_0 VSMain3();
PixelShader = compile ps_2_0 PSMain3();
}
}
technique Splatting4
{
pass p0
{
AlphaBlendEnable = false;
VertexShader = compile vs_2_0 VSMain4();
PixelShader = compile ps_2_0 PSMain4();
}
}
technique Splatting2Fog
{
pass p0
{
AlphaBlendEnable = false;
VertexShader = compile vs_2_0 VSMain2F();
PixelShader = compile ps_2_0 PSMain2F();
}
}
technique Splatting3Fog
{
pass p0
{
AlphaBlendEnable = false;
VertexShader = compile vs_2_0 VSMain3F();
PixelShader = compile ps_2_0 PSMain3F();
}
}
technique Splatting4Fog
{
pass p0
{
AlphaBlendEnable = false;
VertexShader = compile vs_2_0 VSMain4F();
PixelShader = compile ps_2_0 PSMain4F();
}
}
Here are 6 techniques in shader. For 2, 3 and 4 diffuse textures there area techniques both with and without the fog.
Mau wrote:BTW: is it possible in any way to use more than four blend textures on a terrain or mesh?
Yes, you can use more than 4 textures, you just need to modify a shader.
-

Knightmare - Posts: 335
- Joined: Thu Mar 12, 2009 1:22 am
Re: Terrain texturing shader(splatting)
Hm, I can't get it to work correctly. The code below results in a very bright mesh and only the texture of the heighest texture level is shown (which is the rock texture in this case). But it's far to bright.
In the code, I am creating a simple 5x5 dummy terrain plane for testing:
What I also didn't understand yet is how the mask texture should look like. If you use 3 different terrain textures, they are defined by red, green and blue pixels in the mask, as far as I understand. But what if 4 or 5 different textures are used? What colors in the mask will represent those textures then?
In the code, I am creating a simple 5x5 dummy terrain plane for testing:
- Code: Select all
; Include header file
Include "xors3d.bb"
; set application window caption
xAppTitle "Texture Splatting Test"
xGraphics3D 800, 600, 32, False, True
Cam% = xCreateCamera()
xPositionEntity Cam, 0,5, -5
xTurnEntity Cam,50,0,0
Terr% = xCreateMesh ()
Surf% = xCreateSurface(Terr)
;Tex_Terrain% = xLoadTexture("tex_test.jpg")
;xEntityTexture Terr, Tex_Terrain
Tex_Grass% = xLoadTexture("tex_grass.jpg")
Tex_Dirt% = xLoadTexture("tex_dirt.jpg")
Tex_Sand% = xLoadTexture("tex_sand.jpg")
Tex_Rock% = xLoadTexture("tex_rock.jpg")
Tex_Mask% = xLoadTexture("tex_mask.png")
FX_Splatting% = xLoadFXFile("texture splatting.fx")
xSetEntityEffect Terr, FX_Splatting
xSetEffectTechnique(Terr, "Splatting4")
; I TRIED THIS FIRST, BUT DIDN'T WORK
;xSetEffectTexture Terr, "diffuseMap1", Tex_Grass, 0
;xSetEffectTexture Terr, "diffuseMap2", Tex_Dirt, 0
;xSetEffectTexture Terr, "diffuseMap3", Tex_Sand, 0
;xSetEffectTexture Terr, "diffuseMap4", Tex_Rock, 0
;xSetEffectTexture Terr, "diffuseMap5", Tex_Mask, 0
xEntityTexture Terr, Tex_Grass,0, 0
xEntityTexture Terr, Tex_Dirt, 0, 1
xEntityTexture Terr, Tex_Sand, 0, 2
xEntityTexture Terr, Tex_Rock, 0, 3
xEntityTexture Terr, Tex_Mask, 0, 4
; CREATE A FLAT PLANE FOR TERRAIN
gTerrCols% = 5
gTerrRows% = 5
gTileSize# = 1.0
u# = 0
v# = 0
x# = -(gTerrCols*gTileSize)/2
y# = 0
z# = -(gTerrRows*gTileSize)/2
Dim vx%(255,255)
; CREATE VERTICES
For row% = 0 To gTerrRows
For col% = 0 To gTerrCols
y = Rnd(0,1)
u = col * (1.0/gTerrCols)
v = 1.0 - (row * (1.0/gTerrRows))
vx(col,row) = xAddVertex(Surf, x + col*gTileSize,y,z + row*gTileSize, u,v)
Next
Next
; CREATE TRIANGLES
For row% = 0 To gTerrRows-1
For col% = 0 To gTerrCols-1
xAddTriangle(Surf, vx(col,row),vx(col,row+1),vx(col+1,row+1))
xAddTriangle(Surf, vx(col,row),vx(col+1,row+1),vx(col+1,row))
Next
Next
xUpdateNormals Terr
While Not xKeyDown(1)
If xKeyHit(17) Then gShowWire = Not gShowWire : xWireFrame gShowWire
xTurnEntity Terr,0,.1,0
xRenderWorld : xFlip
Wend
What I also didn't understand yet is how the mask texture should look like. If you use 3 different terrain textures, they are defined by red, green and blue pixels in the mask, as far as I understand. But what if 4 or 5 different textures are used? What colors in the mask will represent those textures then?
-

Mau - Posts: 40
- Joined: Thu Apr 29, 2010 10:32 am
24 posts • Page 1 of 3 • 1, 2, 3
Who is online
Users browsing this forum: No registered users and 1 guest

