struct VS_INPUT { float4 Position : POSITION; float3 Normal : NORMAL; float2 UV : TEXCOORD0; }; struct VS_OUTPUT { float4 Position : POSITION; float3 Pos : TEXCOORD0; float3 Normal : TEXCOORD1; float2 UV : TEXCOORD2; float2 Scaled : TEXCOORD3; float2 Clouds : TEXCOORD4; }; VS_OUTPUT main_vp ( VS_INPUT i, uniform float4x4 worldViewProj, uniform float4x4 world, uniform float cloudtime ) { VS_OUTPUT o; //Calculate output position o.Position = mul(worldViewProj, i.Position); //hand over uvs to pixel shader o.UV = i.UV; o.Scaled = i.UV * 512; //hand over input position and normal to pixel shader o.Pos = i.Position; o.Normal = i.Normal; //Calculate new uvs for fake scattering float4 tmp = mul(world, i.Position); o.Clouds.x = (tmp.x+10000)/5000 + (cloudtime/320.0f); o.Clouds.y = (tmp.z+10000)/5000 + (cloudtime/160.0f); return o; } float4 main_fp ( VS_OUTPUT i, //get the 3 nearest lights uniform float3 lightDiffuse, uniform float4 lightAtt, uniform float4 LightPos, uniform float3 lightDiffuse2, uniform float4 lightAtt2, uniform float4 LightPos2, uniform float3 lightDiffuse3, uniform float4 lightAtt3, uniform float4 LightPos3, //ambientlight color uniform float4 ambient, //input textures uniform sampler2D ground : register(s0), uniform sampler2D splat1 : register(s1), uniform sampler2D splat2 : register(s2), uniform sampler2D splat3 : register(s3), uniform sampler2D splat4 : register(s4), uniform sampler2D coverage : register(s5), uniform sampler2D colerage : register(s6), uniform sampler2D cloudTex : register(s7) ): COLOR0 { //We love ogre workaround (normaly the paramters should go directly into an array) float3 alightDiffuse[3] = {lightDiffuse,lightDiffuse2,lightDiffuse3}; float4 alightAtt[3] = {lightAtt,lightAtt2,lightAtt3}; float4 aLightPos[3] = {LightPos,LightPos2,LightPos3}; //Read in textures for splatintensity and color modulation float4 coveragemap = tex2D(coverage, i.UV); float4 coleragemap = tex2D(colerage, i.UV); float4 wolken = tex2D(cloudTex, i.Clouds); //Splat textures TEX1 is the ground texture which is splatted all over the ground float4 TEX1 = tex2D(ground, i.Scaled); float4 TEX2 = tex2D(splat1, i.Scaled); float4 TEX3 = tex2D(splat2, i.Scaled); float4 TEX4 = tex2D(splat3, i.Scaled); float4 TEX5 = tex2D(splat4, i.Scaled); float3 normal = normalize(i.Normal); //Blend textures with intensity and alpha channel float4 diffColor = lerp(lerp(lerp(lerp(TEX1,TEX2,coveragemap.r*TEX2.a),TEX3,coveragemap.g*TEX3.a),TEX4,coveragemap.b*TEX4.a),TEX5,coveragemap.a*TEX5.a); //add ambient light and color blending float4 oColor = diffColor * ambient * coleragemap; //for every light calculate diffuse lighting for (int j = 0; j < 3; j++) { if (any(alightDiffuse[j])) { //Ogre stores type of light in the .w component 0 = directional Lights (POS=DIRECTION), 1 = point lights float3 lightDir = aLightPos[j].xyz - (i.Pos * aLightPos[j].w); float dist = length(lightDir); lightDir = normalize(lightDir); float iD = saturate(dot(normal, lightDir)); //calculate pointlight attenuation float att = 1 / (alightAtt[j].y + alightAtt[j].z * dist + alightAtt[j].w * dist * dist); //add light oColor.rgb += att * (diffColor.rgb * alightDiffuse[j] * iD); } } //modulate clouds shadows oColor *= wolken; return saturate(oColor); }