Ok I have a first version of the code working...
MATERIAL mtl_terraintex3
{
skin1 = ter_tex4; //defined bmap
skin2 = ter_tex5; //defined bmap
skin3 = ter_blend1; //defined bmap
skin4 = ter_blend2; //defined bmap
effect = "
//enable: DirectX Lighting
//help: Use the DirectX Formula for dynamic lights.
//help: Otherwise use the Conitec Formula that produces smoother light.
//id: 11
//#define DXLIGHTING
//enable: DirectX Fog
//help: Use the DirectX Formula for z-based fog.
//help: Otherwise use the Conitec Formula that produces distance-based fog.
//id: 12
#define DXFOG
//I deleted the shader fallback to 1_0 because 2_0 is needed
//I deleted the shadowmapsupport to get more textures working
#include <transform>
#include <sun>
#include <lights>
#include <fog>
#include <normal>
Texture entSkin1; // RGBA Texture for base mask
Texture entSkin2; // Base texture
Texture entSkin3; // Red masked tiled texture
Texture entSkin4; // Green masked tiled texture
Texture mtlSkin1; // blue masked tiled texture
Texture mtlSkin2; // alpha masked tiled texture
Texture mtlSkin3; // First extreme blending mask (with addition values)
Texture mtlSkin4; // Second extreme blending mask (with subtraction values)
float4 vecSkill41; //first three elements used for the texturescales
//fourth used as input for percentual blending
float fAmbient;
sampler sMaskTex = sampler_state { Texture = <entSkin1>; };
sampler sBaseTex = sampler_state { Texture = <entSkin2>; };
sampler sRedTex = sampler_state { Texture = <entSkin3>; };
sampler sGreenTex = sampler_state { Texture = <entSkin4>; };
sampler sBlueTex = sampler_state { Texture = <mtlSkin1>; };
sampler sAlphaTex = sampler_state { Texture = <mtlSkin2>; };
sampler sb1maskTex = sampler_state { Texture = <mtlSkin3>; };
sampler sb2maskTex = sampler_state { Texture = <mtlSkin4>; };
//////////////////////////////////////////////////////////////////////
struct out_terraintex3 // Output to the pixelshader fragment
{
float4 Pos : POSITION;
float4 Color : COLOR0;
float Fog : FOG;
float2 MaskCoord: TEXCOORD0;
float2 BaseCoord: TEXCOORD1;
float2 RedCoord : TEXCOORD2;
float2 GreenCoord: TEXCOORD3;
float2 BlueCoord: TEXCOORD4;
float2 AlphaCoord: TEXCOORD5;
float2 B1Coord: TEXCOORD6;
float2 B2Coord: TEXCOORD7;
};
out_terraintex3 vs_terraintex3(
float4 inPos : POSITION,
float3 inNormal : NORMAL,
float2 inTexCoord0 : TEXCOORD0)
{
out_terraintex3 Out;
Out.Pos = DoTransform(inPos); // transform to screen coordinates
// rotate and normalize the normal
float3 N = DoNormal(inNormal);
float3 P = mul(inPos,matWorld);
Out.Color = fAmbient + DoSunLight(N); // Add ambient and sun light
for (int i=0; i<6; i++) // Add 6 dynamic lights (maximum for vs 1.1)
Out.Color += DoLight(P,N,i);
Out.Fog = DoFog(inPos); // Add fog
// scale the texture coordinates for the masked textures
Out.MaskCoord = inTexCoord0.xy;
Out.BaseCoord = inTexCoord0.xy * vecSkill41.x;
Out.RedCoord = inTexCoord0.xy * vecSkill41.y;
Out.GreenCoord = inTexCoord0.xy * vecSkill41.z;
Out.BlueCoord = inTexCoord0.xy * vecSkill41.y; //condition: redtex same scales as bluetex
Out.AlphaCoord = inTexCoord0.xy * vecSkill41.z;//condition: greentex same scales as alphatex
Out.B1Coord = inTexCoord0.xy;
Out.B2Coord = inTexCoord0.xy;
return Out;
}
float4 ps_terraintex3_13(out_terraintex3 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 GreenColor = tex2D(sGreenTex,In.GreenCoord);
float4 BlueColor = tex2D(sBlueTex,In.BlueCoord);
float4 AlphaColor = tex2D(sAlphaTex,In.AlphaCoord);
float4 B1MaskColor = tex2D(sb1maskTex,In.B1Coord);
float4 B2MaskColor = tex2D(sb2maskTex,In.B2Coord);
// blend the textures over the base texture
//Add or subtract the other masks
//min-max for avoiding to low or high values
float4 BaseRed = lerp(BaseColor,RedColor,max(min(MaskColor.r+(B1MaskColor.r-B2MaskColor.r)*vecSkill41[3],255),0));
float4 BaseGreen = lerp(BaseRed,GreenColor,max(min(MaskColor.g+(B1MaskColor.g-B2MaskColor.g)*vecSkill41[3],255),0));
float4 BaseBlue = lerp(BaseGreen,BlueColor,max(min(MaskColor.b+(B1MaskColor.b-B2MaskColor.b)*vecSkill41[3],255),0));
float4 FinalColor = lerp(BaseBlue,AlphaColor,max(min(MaskColor.a+(B1MaskColor.a-B2MaskColor.a)*vecSkill41[3],255),0));
// Add the vertex light
FinalColor *= In.Color;
FinalColor.a = 1.0f; // prevent transparency
return FinalColor;
}
technique terraintex3_13
{
pass one
{
sampler[0] = (sMaskTex);
sampler[1] = (sBaseTex);
sampler[2] = (sRedTex);
sampler[3] = (sGreenTex);
sampler[4] = (sBlueTex);
sampler[5] = (sAlphaTex);
sampler[6] = (sb1maskTex);
sampler[7] = (sb2maskTex);
VertexShader = compile vs_2_0 vs_terraintex3();
PixelShader = compile ps_2_0 ps_terraintex3_13();
}
}
// fallback if nothing works
technique fallback { pass one { } }
";
}
ACTION terrain_base {
var proc;
MY.MATERIAL = mtl_terraintex3;
my.skill41 = float(15);
my.skill42 = float(15);
my.skill43 = float(15);
WHILE (1) {
WHILE (proc < 100) {
proc += time;
MY.SKILL44 = float(proc/100);
WAIT (1);
}
WHILE (proc > 0) {
proc -= time;
MY.SKILL44 = float(proc/100);
WAIT (1);
}
}
}
I changed the shaderversion to 2_0 because I needed more Texturecoords. If there is another possibility to avoid this, please explain it to me!
This has only a very simple blending system by now, I'll try to improve it.
It simply adds the components of the first blending mask to the normal mask, and subtracts the components of the second one. So the blending mask should only contain additions or subtractions to the original mask. I used the skill44 for a percentual value the contains how much the blending is done. The big disadvantage is that this changes all textures the same time, so in this version of the code, it only makes sense to have single colored blending masks.
I would need more entityskills to give a value for each texture.
The second disadvantage is that this produces a fluently (sorry for my english)
"morphing" of the textures. For filling a terrain with snow, this doesn't make sense, but I had no idea to create a "random" morphing so that it doesn't change the same kind at every point of the region.
The action is very simple and only for showing the effect.
Please post your ideas to improve the shader
