Previously
In my last blog post I talked about how to implement a simple shadow map this time I will talk about a way to improve the quality of the shadows. Last time we discovered that the shadows were very blocky, rigid, and weren’t very nice looking. These were hard edge shadows and we can fix that by using something known as Percentage Closer Filtering (PCF). PCF is a method that determines how much light a pixel should have based on the other pixels around it, this should give us some nicer, softer shadows that will be great for your project. So, let’s get down to it and implement PCF shadows.
Implementation
So, in our pixel shader we need to define how the range of PCF filtering we want to have. The range will determine how many pixels around the current pixel we want to look at, so if we wanted a range of one it would check the current pixel and the 8 other pixels surrounding it. For demonstration purposes I’m going to use a range of one.
Next, we need to loop through our range and get the shadow level from the map. You can do this with 2 simple for loops starting at your negative range going to your positive range.
for (int x = -PCF_RANGE; x <= PCF_RANGE; x++)
From there you want to perform the same shadow map calculations from last time inside the loop and add it to a float variable. The last thing you need to do from there is divide that variable by the number of pixels you check and you now have PCF shadows.
Additional tweaks
You might have noticed that there’s some blotchy ness to the shadows similar to a wave pattern from light to dark. This obviously is bad but it can easily be fixed with a shadow bias and takes less than 2 seconds to implement. The bias is a value that will help remove that wave pattern and all that needs to be done is subtract the bias from your coordinates z value and you’re done, that’s all it takes. Now finding the right bias value will take some time but the general rule is the smaller you can get it the better.
In addition to the bias if you are using the High Level Shader Language (HLSL) you can have the gpu determine the shadow level for you. You can do this by changing the Sampler state into a Sampler Comparison State so you don’t have to check the values yourself. And that’s it, you’re done you’ve implemented PCF shadow maps, got rid of the shadow waves and it only took 10 minutes. The screenshot below is there to help you if you got lost at any point during this blog.
Gage Dietz

Top comments (0)