| float4x4 World; |
| float4x4 View; |
| float4x4 Projection; |
| |
| //color of the light |
| float3 Color; |
| |
| //position of the camera, for specular light |
| float3 cameraPosition; |
| |
| //this is used to compute the world-position |
| float4x4 InvertViewProjection; |
| |
| //this is the position of the light |
| float3 lightPosition; |
| |
| //how far does this light reach |
| float lightRadius; |
| |
| //control the brightness of the light |
| float lightIntensity = 1.0f; |
| |
| //controls the view angle |
| float lightAngleCosine = 45; |
| |
| //specify direction of spotlight |
| float3 lightDirection; |
| |
| // diffuse color, and specularIntensity in the alpha channel |
| texture colorMap; |
| // normals, and specularPower in the alpha channel |
| texture normalMap; |
| //depth |
| texture depthMap; |
| |
| sampler colorSampler = sampler_state |
| { |
| Texture = (colorMap); |
| AddressU = CLAMP; |
| AddressV = CLAMP; |
| MagFilter = LINEAR; |
| MinFilter = LINEAR; |
| Mipfilter = LINEAR; |
| }; |
| sampler depthSampler = sampler_state |
| { |
| Texture = (depthMap); |
| AddressU = CLAMP; |
| AddressV = CLAMP; |
| MagFilter = POINT; |
| MinFilter = POINT; |
| Mipfilter = POINT; |
| }; |
| sampler normalSampler = sampler_state |
| { |
| Texture = (normalMap); |
| AddressU = CLAMP; |
| AddressV = CLAMP; |
| MagFilter = POINT; |
| MinFilter = POINT; |
| Mipfilter = POINT; |
| }; |
| |
| |
| struct VertexShaderInput |
| { |
| float3 Position : POSITION0; |
| }; |
| |
| struct VertexShaderOutput |
| { |
| float4 Position : POSITION0; |
| float4 ScreenPosition : TEXCOORD0; |
| }; |
| |
| VertexShaderOutput VertexShaderFunction(VertexShaderInput input) |
| { |
| VertexShaderOutput output; |
| //processing geometry coordinates |
| float4 worldPosition = mul(float4(input.Position,1), World); |
| float4 viewPosition = mul(worldPosition, View); |
| output.Position = mul(viewPosition, Projection); |
| output.ScreenPosition = output.Position; |
| return output; |
| } |
| |
| float2 halfPixel; |
| float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 |
| { |
| input.ScreenPosition.xy /= input.ScreenPosition.w; |
| |
| float2 texCoord = 0.5f * (float2(input.ScreenPosition.x,-input.ScreenPosition.y) + 1); |
| texCoord -=halfPixel; |
| |
| float4 normalData = tex2D(normalSampler,texCoord); |
| float3 normal = 2.0f * normalData.xyz - 1.0f; |
| |
| float specularPower = normalData.a * 255; |
| float specularIntensity = tex2D(colorSampler, texCoord).a; |
| |
| float depthVal = tex2D(depthSampler,texCoord).r; |
| |
| //compute screen-space position |
| float4 position; |
| position.xy = input.ScreenPosition.xy; |
| position.z = depthVal; |
| position.w = 1.0f; |
| |
| //transform to world space |
| position = mul(position, InvertViewProjection); |
| position /= position.w; |
| |
| |
| float3 lightVector = lightPosition - position; |
| float attenuation = saturate(1.0f - length(lightVector)/lightRadius); |
| lightVector = normalize(lightVector); |
| float dotCos = dot(lightDirection, -lightVector); |
| |
| if(dotCos > lightAngleCosine) |
| { |
| float spotIntensity = pow(dotCos,2); |
| |
| float NdL = max(0,dot(normal,lightVector)); |
| float3 diffuseLight = NdL * Color.rgb; |
| |
| float3 reflectionVector = normalize(reflect(-lightVector, normal)); |
| float3 directionToCamera = normalize(cameraPosition - position); |
| float specularLight = specularIntensity * pow( saturate(dot(reflectionVector, directionToCamera)), specularPower); |
| |
| attenuation *= spotIntensity; |
| return attenuation * lightIntensity * float4(diffuseLight.rgb,specularLight); |
| } |
| else |
| { |
| return float4(0,0,0,0); |
| } |
| return float4(0,0,0,0); |
| } |
| |
| technique Technique1 |
| { |
| pass Pass1 |
| { |
| VertexShader = compile vs_2_0 VertexShaderFunction(); |
| PixelShader = compile ps_2_0 PixelShaderFunction(); |
| } |
| } |
| |