# Soft shadows for point lights (my implementation)

Discussion in 'General Discussion' started by LifeKILLED, Dec 24, 2015.

1. ### LifeKILLED

Joined:
Nov 15, 2013
Posts:
3
I made the realization of soft shadows for point lights. In order to make it work , you need to find in folder "...\Unity5\Editor\Data\CGIncludes" file "UnityShadowLibrary.cginc" and edit it.

To see the result , you need to find a folder of your project . In it find the folder "Library". Remove from this folder directory "ShaderCache" and restart Unity. Yes, I restarted Unity after each compilation.

See in "UnityShadowLibrary.cginc". We need this cut:

Code (csharp):
1.
3.
4.         float z = 1.0/128.0;
6.         shadowVals.x = SampleCubeDistance (vec+float3( z, z, z));
7.         shadowVals.y = SampleCubeDistance (vec+float3(-z,-z, z));
8.         shadowVals.z = SampleCubeDistance (vec+float3(-z, z,-z));
9.         shadowVals.w = SampleCubeDistance (vec+float3( z,-z,-z));
11.
13.
14.     #else
15.
16.
What do we see ? Artfully created a small offset vector. Works quickly, looks terrible:

First of course you need to choose the offset is not in all three dimensions, but in a plane perpendicular to the vector from light. Thus, we will work with the cubemap as a flat texture. So you need to be less than the sample for best results.
To obtain the virtual vector we start axes X and Y, then store them in different sequences , thereby selecting a point on the same virtual plane. No matrix , everything fast and simple.
And second - we need some random. It was effect like Disk Bloor.

Code (csharp):
1.
3.
4.         // Smaller number is more blur
5.         float downscale = 32.0f;
6.
7.         // Random vector
8.         const float3 rndseed = float3(12.9898,78.233,45.5432);
9.         float3 randomvec = float3( dot(vec,rndseed) , dot(vec.yzx,rndseed) , dot(vec.zxy,rndseed) );
10.         randomvec = frac(sin(randomvec) * 43758.5453);
11.
12.         // Vectors of X and Y axis for virtual planar
13.         float3 xvec = normalize(cross(vec,randomvec));
14.         float3 yvec = normalize(cross(vec,xvec));
15.
16.
17.         // Two offsets
18.         float3 vec1 = xvec / downscale;
19.         float3 vec2 = yvec / downscale;
20.
22.
23.         // Four samples
28.
31.
32.     #else
33.
34.
And see:

Here there are the same four samples , but the difference is enormous. Pixels are no longer visible. With good textures dithering was invisible. You can see what now there's not a bias problem.

And now - warning! We can make Area Light like effect:

Code (csharp):
1.
3.
5.
6.         float downscale = 32.0f;
7.         float areascalefactor  = 10.0f;
8.
9.         const float3 rndseed = float3(12.9898,78.233,45.5432);
10.         float3 randomvec = float3( dot(vec,rndseed) , dot(vec.yzx,rndseed) , dot(vec.zxy,rndseed) );
11.         randomvec = frac(sin(randomvec) * 43758.5453);
12.
13.         float3 xvec = normalize(cross(vec,randomvec));
14.         float3 yvec = normalize(cross(vec,xvec));
15.
16.         float3 vec1 = xvec / downscale;
17.         float3 vec2 = yvec / downscale;
18.
20.
22.
23.             // Lookup
28.
29.             // Choose distances sum
31.
32.             // Change bloor factor
33.             downscale *= 2.0f / (1.0 + (shadowdist > 0.0f) ? (shadowdist * areascalefactor ) : 0.0f);
34.
35.             vec1 = xvec / downscale;
36.             vec2 = yvec / downscale;
37.
38.         #endif
39.
40.         // Continue old operations
45.
48.
49.     #else
50.
51.