float4x4 viewProjectionMatrix: register(c0); float4 lightPosition: register(c4); float4 view_position: register(c5); float4x4 proj_matrix: register(c6); float distanceScale: register(c10); float time_0_X: register(c11); float3 lookAt; float factor; struct VS_OUTPUT { float4 Pos: POSITION; float3 normal: TEXCOORD0; float3 lightVec: TEXCOORD1; float3 viewVec: TEXCOORD2; float4 shadowCrd: TEXCOORD3; float3 texCoord: TEXCOORD4; }; VS_OUTPUT main(float4 Pos: POSITION, float3 normal: NORMAL, float3 texCoord: TEXCOORD0){ VS_OUTPUT Out; // Animate the light position. // Comment out this code to use a static light. // In real applications this work is better done on // the CPU as it's constant for the whole scene. float3 lightPosition; lightPosition.x = cos(1.321 * time_0_X); lightPosition.z = sin(0.923 * time_0_X); lightPosition.xz = 100 * normalize(lightPosition.xz); lightPosition.y = 100; // Flip, scale and translate our model to suit our scene // In real applications, this work should normally be // done at load time, alternatively if animation is desired, // be altered by a world matrix. normal = normal.xyz; Out.Pos = mul(viewProjectionMatrix, Pos); // World-space lighting Out.normal = normal; Out.lightVec = distanceScale * (lightPosition - Pos.xyz); Out.viewVec = view_position - Pos.xyz; Out.texCoord = texCoord; // Create view vectors for the light, looking at (0,0,0) // In real applications this work is better done on // the CPU as it's constant for the whole scene. float3 dirZ = -normalize(lightPosition); float3 up = float3(0.0,0.0,1.0); float3 dirX = cross(up, dirZ); float3 dirY = cross(dirZ, dirX); // Transform into light's view space. // In real applications we would be better off using a 4x4 // matrix instead, but for this shader it's cheaper to // just transpose and rotate into light's view space. float4 pos; Pos.xyz -= lightPosition; pos.x = dot(dirX, Pos); pos.y = dot(dirY, Pos); pos.z = dot(dirZ, Pos); pos.w = 1; // Project it. For this sample using the normal projection // matrix suffices, however, real applications will typically // use a separate projection matrix for each light depending // on its properties such as FOV and range. float4 sPos = mul(proj_matrix, pos); // Use projective texturing to map the position of each fragment // to its corresponding texel in the shadow map. sPos.z += 10; Out.shadowCrd.x = 0.5 * (sPos.z + sPos.x); Out.shadowCrd.y = 0.5 * (sPos.z - sPos.y); Out.shadowCrd.z = 0; Out.shadowCrd.w = sPos.z; return Out; }