Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- float4x4 World;
- float4x4 View;
- float4x4 Projection;
- float SpecularPower = 16;
- float3 LightDirection;
- float4x4 LightView;
- float4x4 LightProjection;
- float Bias;
- float ShadowMapSize = 2048;
- Texture2D ShadowMap;
- sampler ShadowMapSampler = sampler_state {
- texture = <ShadowMap>;
- magfilter = POINT;
- minfilter = POINT;
- mipfilter = POINT;
- AddressU = CLAMP;
- AddressV = CLAMP;
- };
- // The input for the VertexShader
- struct VertexShaderInput
- {
- float4 Position : POSITION;
- float3 Normal : NORMAL;
- };
- // The output from the vertex shader, used for later processing
- struct VertexShaderOutput
- {
- float4 Position : SV_POSITION;
- float3 Normal : TEXCOORD0;
- float4 LightViewPosition : TEXCOORD1;
- float4 LightDirection : TEXCOORD2;
- };
- struct PixelShaderOutput
- {
- float4 Color : SV_TARGET0;
- };
- //between 3 and 7 for decent results?
- float CalcShadowTermSoftPCF(float fLightDepth, float ndotl, float2 vTexCoord, int iSqrtSamples)
- {
- float fShadowTerm = 0.0f;
- float variableBias = clamp(0.0005 * tan(acos(ndotl)), 0.00001, Bias);
- float shadowMapSize = ShadowMapSize.x;
- float fRadius = iSqrtSamples - 1; //mad(iSqrtSamples, 0.5, -0.5);//(iSqrtSamples - 1.0f) / 2;
- [unroll]
- for (float y = -fRadius; y <= fRadius; y++)
- {
- [unroll]
- for (float x = -fRadius; x <= fRadius; x++)
- {
- float2 vOffset = 0;
- vOffset = float2(x, y);
- vOffset /= shadowMapSize;
- //vOffset *= 2;
- //vOffset /= variableBias*200;
- float2 vSamplePoint = vTexCoord + vOffset;
- float fDepth = ShadowMap.Sample(ShadowMapSampler, vSamplePoint).r;
- float fSample = (fLightDepth <= fDepth + Bias);
- // Edge tap smoothing
- float xWeight = 1;
- float yWeight = 1;
- if (x == -fRadius)
- xWeight = 1 - frac(vTexCoord.x * shadowMapSize);
- else if (x == fRadius)
- xWeight = frac(vTexCoord.x * shadowMapSize);
- if (y == -fRadius)
- yWeight = 1 - frac(vTexCoord.y * shadowMapSize);
- else if (y == fRadius)
- yWeight = frac(vTexCoord.y * shadowMapSize);
- fShadowTerm += fSample * xWeight * yWeight;
- }
- }
- fShadowTerm /= (fRadius*fRadius*4);
- return fShadowTerm;
- }
- // The VertexShader.
- VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
- {
- VertexShaderOutput output = (VertexShaderOutput)0;
- float4 worldPosition = mul(input.Position, World);
- float4 viewPosition = mul(worldPosition, View);
- output.Position = mul(viewPosition, Projection);
- output.Normal = (mul(normalize(input.Normal), World));
- output.LightDirection.xyz = -LightDirection;
- output.LightDirection.w = 1;
- output.LightViewPosition = mul(input.Position, World);
- output.LightViewPosition = mul(output.LightViewPosition, LightView);
- output.LightViewPosition = mul(output.LightViewPosition, LightProjection);
- return output;
- }
- float CalcShadowTermPCF(float light_space_depth, float ndotl, float2 shadow_coord)
- {
- float shadow_term = 0;
- //float2 v_lerps = frac(ShadowMapSize * shadow_coord);
- float variableBias = clamp(0.001 * tan(acos(ndotl)), 0, Bias);
- //safe to assume it's a square
- float size = 1 / ShadowMapSize.x;
- float samples[4];
- samples[0] = (light_space_depth - variableBias < ShadowMap.Sample(ShadowMapSampler, shadow_coord).r);
- samples[1] = (light_space_depth - variableBias < ShadowMap.Sample(ShadowMapSampler, shadow_coord + float2(size, 0)).r);
- samples[2] = (light_space_depth - variableBias < ShadowMap.Sample(ShadowMapSampler, shadow_coord + float2(0, size)).r);
- samples[3] = (light_space_depth - variableBias < ShadowMap.Sample(ShadowMapSampler, shadow_coord + float2(size, size)).r);
- shadow_term = (samples[0] + samples[1] + samples[2] + samples[3]) / 4.0;
- //shadow_term = lerp(lerp(samples[0],samples[1],v_lerps.x),lerp(samples[2],samples[3],v_lerps.x),v_lerps.y);
- return shadow_term;
- }
- // The Pixel Shader
- PixelShaderOutput PixelShaderFunction(VertexShaderOutput input)
- {
- PixelShaderOutput Output = (PixelShaderOutput)0;
- float3 reflectionVector = -reflect(input.LightDirection, input.Normal);
- float specular = normalize(reflectionVector);
- float4 diffuse = saturate(dot(input.LightDirection, input.Normal));
- specular = pow(abs(specular), SpecularPower) * diffuse;
- float NdL = saturate(dot(input.Normal, input.LightDirection));
- float ourDepth = (input.LightViewPosition.z / input.LightViewPosition.w);
- float2 ShadowTexCoord = mad(0.5f , input.LightViewPosition.xy / input.LightViewPosition.w , float2(0.5f, 0.5f));
- ShadowTexCoord.y = 1.0f - ShadowTexCoord.y;
- float shadowContribution = 0;
- shadowContribution = CalcShadowTermSoftPCF(ourDepth, NdL, ShadowTexCoord, 4);
- Output.Color = float4(0, 0.5, 0.8, 1) * (diffuse + specular * 1) * shadowContribution; ;
- return Output;
- }
- // Our Techinique
- technique Technique1
- {
- pass Pass0
- {
- VertexShader = compile vs_5_0 VertexShaderFunction();
- PixelShader = compile ps_5_0 PixelShaderFunction();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement