| 1 | /* Offset mapping including a shadow element and multiple lights in one pass */  | 
|---|
| 2 | void integratedshadows_vp(float4 position   : POSITION,  | 
|---|
| 3 |               float3 normal      : NORMAL,  | 
|---|
| 4 |               float2 uv         : TEXCOORD0,  | 
|---|
| 5 |               float3 tangent     : TANGENT0,  | 
|---|
| 6 |               // outputs  | 
|---|
| 7 |               out float4 oPosition    : POSITION,  | 
|---|
| 8 |               out float2 oUv          : TEXCOORD0,  | 
|---|
| 9 |               out float3 oLightDir    : TEXCOORD1, // tangent space  | 
|---|
| 10 |              out float3 oEyeDir       : TEXCOORD2, // tangent space  | 
|---|
| 11 |                          out float3 oSpotDirection : TEXCOORD3, // tangent space | 
|---|
| 12 |               out float3 oLightDir1    : TEXCOORD4, // tangent space  | 
|---|
| 13 |               out float3 oSpotDirection1    : TEXCOORD5, // tangent space  | 
|---|
| 14 |                          out float4 oShadowUV1 : TEXCOORD6, | 
|---|
| 15 |                          out float4 oShadowUV2 : TEXCOORD7, | 
|---|
| 16 |               // parameters  | 
|---|
| 17 |               uniform float4 lightPosition, // object space  | 
|---|
| 18 |               uniform float4 lightPosition1, // object space  | 
|---|
| 19 |               uniform float3 eyePosition,   // object space  | 
|---|
| 20 |                           uniform float3 spotDirection, // object space | 
|---|
| 21 |                           uniform float3 spotDirection1, // object space | 
|---|
| 22 |               uniform float4x4 worldViewProj, | 
|---|
| 23 |                           uniform float4x4 worldMatrix, | 
|---|
| 24 |                           uniform float4x4 texViewProj1, | 
|---|
| 25 |                           uniform float4x4 texViewProj2)  | 
|---|
| 26 | {   | 
|---|
| 27 |    // calculate output position  | 
|---|
| 28 |    oPosition = mul(worldViewProj, position);  | 
|---|
| 29 |  | 
|---|
| 30 |    float4 worldPos = mul(worldMatrix, position); | 
|---|
| 31 |    oShadowUV1 = mul(texViewProj1, worldPos); | 
|---|
| 32 |    oShadowUV2 = mul(texViewProj2, worldPos); | 
|---|
| 33 |     | 
|---|
| 34 |     | 
|---|
| 35 |  | 
|---|
| 36 |    // pass the main uvs straight through unchanged  | 
|---|
| 37 |    oUv = uv;  | 
|---|
| 38 |  | 
|---|
| 39 |    // calculate tangent space light vector  | 
|---|
| 40 |    // Get object space light direction  | 
|---|
| 41 |    float3 lightDir = normalize(lightPosition.xyz -  (position * lightPosition.w)); | 
|---|
| 42 |    float3 lightDir1 = normalize(lightPosition1.xyz -  (position * lightPosition1.w)); | 
|---|
| 43 |    float3 eyeDir = eyePosition - position.xyz;  | 
|---|
| 44 |      | 
|---|
| 45 |    // Calculate the binormal (NB we assume both normal and tangent are  | 
|---|
| 46 |    // already normalised)  | 
|---|
| 47 |    // NB looks like nvidia cross params are BACKWARDS to what you'd expect  | 
|---|
| 48 |    // this equates to NxT, not TxN  | 
|---|
| 49 |    float3 binormal = cross(tangent, normal);  | 
|---|
| 50 |      | 
|---|
| 51 |    // Form a rotation matrix out of the vectors  | 
|---|
| 52 |    float3x3 rotation = float3x3(tangent, binormal, normal);  | 
|---|
| 53 |      | 
|---|
| 54 |    // Transform the light vector according to this matrix  | 
|---|
| 55 |    lightDir = normalize(mul(rotation, lightDir));  | 
|---|
| 56 |    lightDir1 = normalize(mul(rotation, lightDir1));  | 
|---|
| 57 |    eyeDir = normalize(mul(rotation, eyeDir));  | 
|---|
| 58 |  | 
|---|
| 59 |    oLightDir = lightDir;  | 
|---|
| 60 |    oLightDir1 = lightDir1;  | 
|---|
| 61 |    oEyeDir = eyeDir;  | 
|---|
| 62 |    oSpotDirection = normalize(mul(rotation, -spotDirection)); | 
|---|
| 63 |    oSpotDirection1 = normalize(mul(rotation, -spotDirection1)); | 
|---|
| 64 | } | 
|---|
| 65 |  | 
|---|
| 66 | // Expand a range-compressed vector | 
|---|
| 67 | float3 expand(float3 v) | 
|---|
| 68 | { | 
|---|
| 69 |         return (v - 0.5) * 2; | 
|---|
| 70 | } | 
|---|
| 71 |  | 
|---|
| 72 | void integratedshadows_fp( | 
|---|
| 73 |         float2 uv : TEXCOORD0, | 
|---|
| 74 |         float3 lightDir : TEXCOORD1, | 
|---|
| 75 |         float3 eyeDir : TEXCOORD2, | 
|---|
| 76 |         float3 spotDir : TEXCOORD3, | 
|---|
| 77 |         float3 lightDir1 : TEXCOORD4, | 
|---|
| 78 |         float3 spotDir1 : TEXCOORD5, | 
|---|
| 79 |         float4 shadowUV1 : TEXCOORD6, | 
|---|
| 80 |         float4 shadowUV2 : TEXCOORD7, | 
|---|
| 81 |         uniform float3 lightDiffuse, | 
|---|
| 82 |         uniform float4 scaleBias, | 
|---|
| 83 |     uniform float4 spotParams, | 
|---|
| 84 |         uniform float3 lightDiffuse1, | 
|---|
| 85 |     uniform float4 spotParams1, | 
|---|
| 86 |         uniform sampler2D normalHeightMap : register(s0), | 
|---|
| 87 |         uniform sampler2D diffuseMap : register(s1), | 
|---|
| 88 |         uniform sampler2D shadowMap1 : register(s2), | 
|---|
| 89 |         uniform sampler2D shadowMap2 : register(s3), | 
|---|
| 90 |         out float4 oColour : COLOR) | 
|---|
| 91 | { | 
|---|
| 92 |         // get the height using the tex coords | 
|---|
| 93 |         float height = tex2D(normalHeightMap, uv).a; | 
|---|
| 94 |  | 
|---|
| 95 |         // scale and bias factors        | 
|---|
| 96 |         float scale = scaleBias.x; | 
|---|
| 97 |         float bias = scaleBias.y; | 
|---|
| 98 |  | 
|---|
| 99 |         // calculate displacement        | 
|---|
| 100 |         float displacement = (height * scale) + bias; | 
|---|
| 101 |          | 
|---|
| 102 |         float3 uv2 = float3(uv, 1); | 
|---|
| 103 |  | 
|---|
| 104 |         float3 scaledEyeDir = eyeDir * displacement; | 
|---|
| 105 |          | 
|---|
| 106 |         // calculate the new tex coord to use for normal and diffuse | 
|---|
| 107 |         float2 newTexCoord = (scaledEyeDir + uv2).xy; | 
|---|
| 108 |          | 
|---|
| 109 |         // get the new normal and diffuse values | 
|---|
| 110 |         float3 normal = expand(tex2D(normalHeightMap, newTexCoord).xyz); | 
|---|
| 111 |         float3 diffuse = tex2D(diffuseMap, newTexCoord).xyz; | 
|---|
| 112 |          | 
|---|
| 113 |         float3 col1 = diffuse * saturate(dot(normal, lightDir)) * lightDiffuse; | 
|---|
| 114 |         // factor in spotlight angle | 
|---|
| 115 |         float rho = saturate(dot(spotDir, lightDir)); | 
|---|
| 116 |         // factor = (rho - cos(outer/2) / cos(inner/2) - cos(outer/2)) ^ falloff | 
|---|
| 117 |         float spotFactor = pow( | 
|---|
| 118 |                 saturate(rho - spotParams.y) / (spotParams.x - spotParams.y), spotParams.z); | 
|---|
| 119 |         col1 = col1 * spotFactor; | 
|---|
| 120 |         float3 col2 = diffuse * saturate(dot(normal, lightDir1)) * lightDiffuse1; | 
|---|
| 121 |         // factor in spotlight angle | 
|---|
| 122 |         rho = saturate(dot(spotDir1, lightDir1)); | 
|---|
| 123 |         // factor = (rho - cos(outer/2) / cos(inner/2) - cos(outer/2)) ^ falloff | 
|---|
| 124 |         spotFactor = pow( | 
|---|
| 125 |                 saturate(rho - spotParams1.y) / (spotParams1.x - spotParams1.y), spotParams1.z); | 
|---|
| 126 |         col2 = col2 * spotFactor; | 
|---|
| 127 |  | 
|---|
| 128 |         // shadow textures | 
|---|
| 129 |         col1 = col1 * tex2Dproj(shadowMap1, shadowUV1); | 
|---|
| 130 |         col2 = col2 * tex2Dproj(shadowMap2, shadowUV2); | 
|---|
| 131 |  | 
|---|
| 132 |         oColour = float4(col1 + col2, 1); | 
|---|
| 133 |  | 
|---|
| 134 | } | 
|---|
| 135 |  | 
|---|