////////////////////////////// MOVING GRASS
// Vertex program to wave some grass about
// Assumes UV texture coords of v==0 indicates the top of the grass
void grass_vp(float4 position : POSITION,
float3 normal : NORMAL,
float2 uv : TEXCOORD0,
out float4 oPosition : POSITION,
out float2 oUv : TEXCOORD0,
out float4 oColour : COLOR,
uniform float4x4 worldViewProj,
uniform float4 camObjPos,
uniform float4 ambient,
uniform float4 objSpaceLight,
uniform float4 lightColour,
uniform float4 offset)
{
float4 mypos = position;
//offset = float4(0.5, 0, 0, 0);
float4 factor = float4(1,1,1,1) - uv.yyyy;
mypos = mypos + offset * factor;
oPosition = mul(worldViewProj, mypos);
oUv = uv;
// Color
// get vertex light direction (support directional and point)
float3 light = normalize(objSpaceLight.xyz - (mypos.xyz * objSpaceLight.w));
// grass is just 2D quads, so if light passes underneath we need to invert the normal
// abs() will have the same effect
float diffuseFactor = abs(dot(normal.xyz, light));
oColour = ambient + diffuseFactor * lightColour;
}
void grass_fp( float2 uv : TEXCOORD0,
float4 colour : COLOR,
out float4 oColour : COLOR,
uniform sampler2D diffuseMap
)
{
float4 texColor = tex2D(diffuseMap, uv.xy);
oColour = float4(texColor.rgb * colour.rgb, texColor.a);
}
void grassTex_vp(
float4 position : POSITION,
float4 normal : NORMAL,
float2 uv : TEXCOORD0,
out float4 oPosition : POSITION,
out float2 oUv : TEXCOORD0,
//out float4 oNormal : NORMAL,
uniform float4x4 worldViewProj,
uniform float4 ambient,
uniform float4 objSpaceLight,
uniform float4 lightColour,
uniform float4 offset)
{
// Position
float4 mypos = position;
float4 factor = float4(1,1,1,1) - uv.yyyy;
mypos = mypos + offset * factor;
oPosition = mul(worldViewProj, mypos);
// Texture Coord
oUv.xy = uv.xy;
}
/// grass_vp ambient
void grassAmbient_vp(
float4 position : POSITION,
float4 normal : NORMAL,
float2 uv : TEXCOORD0,
out float4 oPosition : POSITION,
out float2 oUv : TEXCOORD0,
out float4 oColour : COLOR,
//out float4 oNormal : NORMAL,
//uniform float4 camObjPos,
uniform float4x4 worldViewProj,
uniform float4 ambient,
uniform float4 offset)
{
// Position
float4 mypos = position;
float4 factor = float4(1,1,1,1) - uv.yyyy;
mypos = mypos + offset * factor;
oPosition = mul(worldViewProj, mypos);
// Texture Coord
oUv.xy = uv.xy;
/*
// Normal
// Make vec from vertex to camera
float4 EyeVec = camObjPos - mypos;
// Dot the v to eye and the normal to see if they point
// in the same direction or opposite
float aligned = dot(normal, EyeVec); // -1..1
// If aligned is negative, we need to flip the normal
if (aligned < 0)
normal = -normal;
//oNormal = normal;
*/
// Color
oColour = ambient;
}
void grassAmbient_fp( float2 uv : TEXCOORD0,
float4 colour : COLOR,
out float4 oColour : COLOR,
uniform sampler2D diffuseMap
)
{
float4 texColor = tex2D(diffuseMap, uv.xy);
oColour = float4(colour.rgb, texColor.a);
}
//////////////////////// GRASS SHADOW CASTER
// Shadow caster vertex program.
void grasscaster_vp(float4 position : POSITION,
float2 uv : TEXCOORD0,
out float4 oPosition : POSITION,
out float2 oUv : TEXCOORD0,
out float2 oDepth : TEXCOORD1,
uniform float4x4 worldViewProj,
uniform float4 offset,
uniform float4 texelOffsets)
{
float4 mypos = position;
float4 factor = float4(1,1,1,1) - uv.yyyy;
mypos = mypos + offset * factor;
oPosition = mul(worldViewProj, mypos);
// fix pixel / texel alignment
oPosition.xy += texelOffsets.zw * oPosition.w;
oDepth.x = oPosition.z;
oDepth.y = oPosition.w;
oUv = uv;
}
void grasscaster_fp(float2 uv : TEXCOORD0,
float2 depth : TEXCOORD1,
out float4 result : COLOR,
uniform sampler2D diffuseMap
)
{
float alpha = tex2D(diffuseMap, uv).a;
if (alpha > 0.001)
{
result = float4(1.0f, 1.0f, 1.0f, 0.0f);
}
else
{
float finalDepth = depth.x / depth.y;
// just smear across all components
// therefore this one needs high individual channel precision
result = float4(finalDepth.xxx, 1.0f);
}
}
//////////////////////// GRASS SHADOW RECEIVER
void grassreceiver_vp(
float4 position : POSITION,
float4 normal : NORMAL,
float2 uv : TEXCOORD0,
out float4 oPosition : POSITION,
out float4 oShadowUV : TEXCOORD0,
out float3 oUv : TEXCOORD1,
out float4 oColour : COLOR,
//out float4 oNormal : NORMAL,
uniform float4x4 world,
uniform float4x4 worldViewProj,
uniform float4x4 texViewProj,
uniform float4 camObjPos,
uniform float4 objSpaceLight,
uniform float4 lightColour,
uniform float4 offset)
{
float4 mypos = position;
float4 factor = float4(1,1,1,1) - uv.yyyy;
mypos = mypos + offset * factor;
oPosition = mul(worldViewProj, mypos);
oUv.xy = uv.xy;
// Transform position to world space
float4 worldPos = mul(world, mypos);
// calculate shadow map coords
oShadowUV = mul(texViewProj, worldPos);
// Make vec from vertex to camera
float4 EyeVec = camObjPos - mypos;
// Dot the v to eye and the normal to see if they point
// in the same direction or opposite
float alignedEye = dot(normal, EyeVec); // -1..1
// If aligned is negative, we need to flip the normal
if (alignedEye < 0)
normal = -normal;
//oNormal = normal;
// get vertex light direction (support directional and point)
float3 lightVec = normalize(objSpaceLight.xyz - (mypos.xyz * objSpaceLight.w));
// Dot the v to light and the normal to see if they point
// in the same direction or opposite
float alignedLight = dot(normal.xyz, lightVec); // -1..1
// If aligned is negative, shadowing/lighting is not possible.
oUv.z = (alignedLight < 0)? 0 : 1 ;
float diffuseFactor = max(alignedLight, 0);
//oColour = diffuseFactor * lightColour;
oColour = lightColour;
}
void grassreceiver_fp(
float4 shadowUV : TEXCOORD0
, float3 uv : TEXCOORD1
, float4 vertexLight : COLOR
, out float4 oColour : COLOR
, uniform sampler2D shadowMap : register(s0)
, uniform sampler2D diffuseMap : register(s1)
//, uniform float inverseShadowmapSize
, uniform float fixedDepthBias
, uniform float gradientClamp
, uniform float gradientScaleBias
)
{
if (shadowUV.z > 0)
{
float4 diffuse = tex2D(diffuseMap, uv.xy);
if (diffuse.a > 0.001)
{
oColour = float4(0.0f, 0.0f, 0.0f, 0.0f);
}
else
{
// point on shadowmap (no gradient as cg1.4 compiler is unable to handle that complexity)
shadowUV = shadowUV / shadowUV.w;
float4 shadowDepths = tex2D(shadowMap, shadowUV.xy);
float gradientFactor = gradientClamp * gradientScaleBias;
float depthAdjust = gradientFactor + fixedDepthBias * shadowDepths.x;
float centerdepth = shadowDepths.x + depthAdjust;
oColour = (centerdepth > shadowUV.z) ? float4(vertexLight.rgb, diffuse.a) : float4(0, 0, 0, diffuse.a);
}
}
else
{
oColour = float4(0.0f, 0.0f, 0.0f, 0.0f);
}
}