Spot Light with Soft Shadow Shader

This post shows some shaders used to create a Shadow effect using the classic technic Shadow Mapping. The objective of this post is not to explaint how shadows are calculated, we are only going to show the shaders, the creation of the render targets for example will not be shown.

The first step in shadow mapping is to create the depth map of each light, the following shader shows the process. (draw each object of your scene as if the camera is in the light position )

VertexToPixel MyVertexShader(half4 inPos: POSITION0)
	VertexToPixel Output = (VertexToPixel)0;
	Output.Position = mul(inPos, WVP);
	Output.ScreenPos = Output.Position .zw;
	return Output;

PixelToFrame MyPixelShader(VertexToPixel PSIn) : COLOR0
	PixelToFrame Output = (PixelToFrame)0;
	Output.Color = PSIn.ScreenPos.x/PSIn.ScreenPos.y;
	return Output;

The idea of this shader is just to output the Z/W of the objects seen from the light perspective.

With the depth map in hands, the following shader shows how to calculate the spot light effect (draw all the objects using this shader =P).

float4 PixelShaderFunctionPCFAttenuation(VertexShaderOutput input) : COLOR0
    //read depth calculated before
    float depthVal = tex2D(depthSampler,input.TexCoord).r; ///storead as Z/W

    //compute screen-space position
    float4 position;
    position.x = input.TexCoord1.x * 2.0f - 1.0f;
    position.y = -(input.TexCoord1.y * 2.0f - 1.0f);
    position.z = depthVal;
    position.w = 1.0f;
    //transform to world space
    position = mul(position, InvertViewProjection);
    position /= position.w;    

    //surface-to-light vector
    float3 lightVector = lightPosition - position;  

    //compute attenuation based on distance - linear attenuation
    float attenuation = saturate(1.0f - length(lightVector)/lightRadius);   

    //normalize light vector
    lightVector = normalize(lightVector);       

    //find screen position as seen by the light
    float4 lightScreenPos = mul(position, xLightViewProjection);
    lightScreenPos /= lightScreenPos.w;

    //find sample position in shadow map
    float2 lightSamplePos;
    lightSamplePos.x = lightScreenPos.x/2.0f+0.5f;
    lightSamplePos.y = (-lightScreenPos.y/2.0f+0.5f);

    // Offset the coordinate by half a texel so we sample it correctly
    lightSamplePos += (0.5f / shadowBufferSize);

    float SdL = dot(lightDirection, -lightVector);   	

    if(SdL > lightAngleCosine)
		float shadowOcclusion  = 0;
			shadowOcclusion = CalcShadowTermSoftPCF(lightScreenPos.z, lightSamplePos, 7); ///soft shadow effect
			shadowOcclusion = 1;

        float spotIntensity = pow(SdL, lightDecayExponent);   

        //compute diffuse light
        float NdL = max(0,dot(normal,lightVector));
        float3 diffuseLight = NdL * Color.rgb;  

        //reflection vector
        float3 reflectionVector = normalize(reflect(-lightVector, normal));
        //camera-to-surface vector
        float3 directionToCamera = normalize(cameraPosition - position);
        //compute specular light
        float specularLight = specularIntensity * pow( saturate(dot(reflectionVector, directionToCamera)), specularPower);  

        attenuation *= spotIntensity;  

        //take into account attenuation and lightIntensity.
        return shadowOcclusion * attenuation * lightIntensity * float4(diffuseLight.rgb,specularLight);

The idea is simple, it is pretty much the same of the commom spot lights shaders, the only difference is the Soft shadow term. (Check our sample about light types without shadow )

The following part shows how the soft term is calculated:

// Calculates the shadow term using PCF soft-shadowing
float CalcShadowTermSoftPCF(float fLightDepth, float2 vShadowTexCoord, int iSqrtSamples)
	float fShadowTerm = 0.0f;  

	float fRadius = (iSqrtSamples - 1.0f) / 2;
	float fWeightAccum = 0.0f;

	for (float y = -fRadius; y<= fRadius; y++)
		for (float x = -fRadius; x <= fRadius; x++)
			float2 vOffset = 0;
			vOffset = float2(x, y);				
			vOffset /= shadowBufferSize;
			float2 vSamplePoint = vShadowTexCoord + vOffset;			
			float fDepth = tex2D(ShadowMapSampler, vSamplePoint).x;			
			float fSample = (fLightDepth <= fDepth + BIAS);
			// Edge tap smoothing
			float xWeight = 1;
			float yWeight = 1;
			if (x == -fRadius)
				xWeight = 1 - frac(vShadowTexCoord.x * shadowBufferSize);
			else if (x == fRadius)
				xWeight = frac(vShadowTexCoord.x * shadowBufferSize);
			if (y == -fRadius)
				yWeight = 1 - frac(vShadowTexCoord.y * shadowBufferSize);
			else if (y == fRadius)
				yWeight = frac(vShadowTexCoord.y * shadowBufferSize);
			fShadowTerm += fSample * xWeight * yWeight;
			fWeightAccum = xWeight * yWeight;
	fShadowTerm /= (iSqrtSamples * iSqrtSamples);
	fShadowTerm *= 1.55f;	
	return fShadowTerm;

You can use this soft term will all light types. Experiment changing the parameter iSqrtSamples.

  1. #1 by read the full info here on 20 de julho de 2017 - 10:41 pm

    the time to study or stop by the subject material or websites we’ve linked to below the

  2. #2 by frameless glass showers on 21 de julho de 2017 - 5:54 am

    we like to honor lots of other internet sites around the web, even though they arent linked to us, by linking to them. Under are some webpages worth checking out

  3. #3 by Wilton on 21 de julho de 2017 - 7:06 am

    All this was possible due to her very performing acting in her first film, Om Shanti Om.
    It caused a hit with celebrities in the hip hop music in the U.
    With this kind of dedication and services, the fame and glory of this brand is only to improve over the years.

  4. #4 by additional hints on 21 de julho de 2017 - 7:23 am

    Wonderful story, reckoned we could combine some unrelated data, nevertheless seriously worth taking a appear, whoa did one find out about Mid East has got additional problerms also

  5. #5 by on 21 de julho de 2017 - 7:38 am

    We have purchased this one brand of bracelet various times. Every a person is extremely pretty, established very well, cannot tarnish additionally significant depending on that one particular you buy as well as which people give that it to.

  6. #6 by office enclosures on 21 de julho de 2017 - 8:24 am

    check below, are some totally unrelated web sites to ours, nonetheless, they are most trustworthy sources that we use

  7. #7 by horse emoji app on 21 de julho de 2017 - 10:05 am

    below youll locate the link to some internet sites that we consider you need to visit

  8. #8 by keyboard horse on 21 de julho de 2017 - 10:37 am

    that could be the finish of this report. Here youll uncover some internet sites that we feel youll value, just click the links over

  9. #9 by on 21 de julho de 2017 - 12:51 pm

    We have bought the brand name regarding bracelet various instances. Every single one is ultra sweet, prepared very well, does not tarnish to significant depending on what an you purchase additionally who a person bring this towards.

  10. #10 by on 21 de julho de 2017 - 12:52 pm

    We have purchased that brand out of bracelet a few circumstances. Every single a person is super attractive, established well, cannot tarnish and also meaningful depending on which kind of definitely one you purchase and/or just who shoppers offer that in order to.

  11. #11 by on 21 de julho de 2017 - 3:03 pm

    Your product or service was with such a great pricing I never believed that the high quality would be so exceptional. It is breathtaking. Your mother is going to love that it on Christmas morning once she opens up gifts therefore appears like I spent alot more, however pricing is really very good!!

  12. #12 by on 21 de julho de 2017 - 3:22 pm

    Hi there, just wanted to tell you, I enjoyed this
    post. It was practical. Keep on posting!

  13. #13 by خرید اپل ایدی on 21 de julho de 2017 - 3:30 pm

    usually posts some extremely fascinating stuff like this. If you are new to this site

1 314 315 316
(não será publicado)