//Vertex shader for shadowed Bumps void main( float4 Position : POSITION, //in object space float3 Normal : NORMAL, //in object space float2 TexCoord : TEXCOORD0, float3 T : TEXCOORD1, //in object space float3 B : TEXCOORD2, //in object space float3 N : TEXCOORD3, //in object space out float4 oPosition : POSITION, //in projection space out float4 oCosine : COLOR0, //cosine of the angle between the light vector and the normal to the tangent plane out float4 oLightVector2D0 : TEXCOORD0, //projection of the light vector onto the tangent plane out float4 oLightVector2D1 : TEXCOORD1, //projection of the light vector onto the tangent plane out float4 oTexCoord0 : TEXCOORD2, out float4 oTexCoord1 : TEXCOORD3, uniform float4x4 WorldViewProj, uniform float3 LightVector //normalized vector from shading position to light (in object space) ) { // pass texture coordinates for fetching the horizon maps oTexCoord0.xy = TexCoord.xy; oTexCoord1.xy = TexCoord.xy; // compute the 3x3 tranform from tangent space to object space float3x3 objToTangentSpace; objToTangentSpace[0] = T; objToTangentSpace[1] = B; objToTangentSpace[2] = N; // transform light vector from object space to tangent space float3 lightVectorInTangentSpace = mul(objToTangentSpace, LightVector); // pass cosine of the angle between the light vector and the normal to the tangent plane // it is simply the z component of the light vector in tangent space float cosAngle = lightVectorInTangentSpace.z; oCosine = cosAngle.xxxx; //map light vector to [0,1] lightVectorInTangentSpace = 0.5 * lightVectorInTangentSpace + 0.5.xxx; // pass texture coordinates for fetching the basis maps oLightVector2D0.xy = lightVectorInTangentSpace.xy; oLightVector2D1.xy = lightVectorInTangentSpace.xy; // transform position to projection space oPosition = mul(WorldViewProj, Position); } ------------------------------------- //Fragment shader for shadowed Bumps void main( float4 Position : POSITION, //in projection space float4 LightVector2D0 : TEXCOORD0, //projection of the light vector onto the tangent plane float4 LightVector2D1 : TEXCOORD1, //projection of the light vector onto the tangent plane float4 TexCoord0 : TEXCOORD2, float4 TexCoord1 : TEXCOORD3, out float4 Color : COLOR, uniform sampler2D BasisMap0, uniform sampler2D BasisMap1, uniform sampler2D HorizonMap0, uniform sampler2D HorizonMap1) { //fetch basis maps float4 basis0 = tex2D(BasisMap0, LightVector2D0); float4 basis1 = tex2D(BasisMap1, LightVector2D1); //fetch horizon maps float4 horizon0 = tex2D(HorizonMap0, TexCoord0); float4 horizon1 = tex2D(HorizonMap1, TexCoord1); //compute the cosine limit by summing the contribution of the horizon maps in every of the 8 direction //note that only 2 of this 8 products are non zero float cosineLimit = dot(basis0.xyz, horizon0.xyz) + basis0.w * horizon0.w + dot(basis1.xyz, horizon1.xyz) + basis1.w * horizon1.w; Color = cosineLimit.xxxx; }