I am really sorry as my work is not going to be open source, I will leave clues behind on how to get PSSM and LiPSM working so you can do it yourself but no code (cause I'm getting paid)
For the shadow camera:
1)Well first you need a view matrix
2)and crop it with an orthogonal projection matrix so it tightly bounds your REAL view frustum
3)pull the Depth back a bit so objects between the camera frustum and the light can cast shadows
Read up on unit cube clipping (imagine you shorten the camera frustum if its outside of level bounds so you get better shadows when looking out of the level)
You have a special shader which writes to your shadow map (which must be R16G16F or R32G32F) with linear (0,1 range) depth where red=depth and green=depth*depth
Depending on your implementation of lighting and shadowing (forward or deferred) the vsm shader is going to be different, its important to knock down the number of matrix transforms, you should only need one matrix transform to get a position on the shadowmap. NOTE: in opengl you need to inverse (*-1.f) the 12th float in the projection matrix when you pass to a GLSL shader (you will need to invert Y sometimes)
Remember matrix transformed coords will be in range 1 to -1 and texcoords are 1 to 0
The equation for splits was very complicated to come up with and attempt to solve... it took into account the FoV, aspect ratio, resolution of the screen and shadow map but it turned out they cancel each other out if you want a definite amount of splits in your view frustum
FOR 2 SPLITS:
(d*e_x-m_x*n)*(d*e_y-m_y*n)/n^2 = (f*e_x-m_x*d)*(f*e_y-m_y*d)/d^2
Ok so what do these stand for?
d = the split position we want to find
n = near value of the rendering camera
f = far value
Now for the next you need to actually transform the camera frustum into shadowspace and get the vectors from the camera to each far frustum corner. Then divide by the far value (because we want an progression/expansion of the size of the shadowmap as the depth of the split increases)
e_x = extent in X direction (largest vector take smallest)
e_y = extent in Y
NOTE: the max in X is 0 if all vectors are negative in X and min is 0 if all vectors positive
same for the Y axis. This is as if you max'ed and min'ed the vector from the camera to the camera itself
m_x = the smallest absolute vector in X (absolute value for the min comparisons but later restored the sign)
m_y = similar thing for Y
All this simplifies into a quartic
(e_x*e_y)*d^4-(e_x*m_y+e_y*m_x)*d^3+f*(m_x*e_y+m_y*e_x)*d-f*e_x*e_y=0
which I am trying to solve as we speak
This is how far I've got
![Image](http://img191.imageshack.us/img191/5001/screenshot4y.png)
OLD CODE:
hi all I need a simple one file model that has a LoT of geometry detail or transparent stuff like fences, sharp points etc. anything that would require a very good shadowing technique to show all the detail.
If you donate a suitable model, you get full source code before I post it here (you can request seeing it at any moment).
It is going to be Parallel Split Light Space Variance Shadow Maps, a shadowing technique that updates every frame, splitting the camera frustum into 2 to 4 smaller ones taking into account projected pixel sizes so the over and under sampling distribution in each frustum is the same. Then each of these frustums is rotated, scaled and sheared to turn into a cube, the objects closer to the camera will be bigger on the shadow map. LiPSM is an improvement over PSM and here the frustum transforming into a cube is interpolated, by a variable. This leads to finer control over how much "perspective" is put on the shadow map, this variable would correspond to the over&&under sampling distribution to try and even it out. Variance Shadow Mapping is used to achieve very soft shadows using the difference of squares, this requires sampling and blurring so adding perspective will force me to adjust the bluring.
The equations I have so far:
VSM = (squareDepth-Depth^2)/(squareDepth+shadowVertPosition.z-2*Depth*shadowVertPosition.z)
This equation only works for the duelling frusta and if the light looks the same way as the camera (angle between light and camera == 0) and camera angle 90 degrees
(shadowmapRes/ScreenResX)^n=CameraFarValue
n/numberOfSplits = x
then the depth at which the split takes place is (shadowmapRes/ScreenResX)^(x*splitNumber)
for screen resolution of 800 and shadowmap of 2k with 4 splits (4k shadowmap overall) the X constant is 1.837154775
we calculate over sampling like this
beginning of frustum[smaller end] (x^splitNumber/2048)/(x^(splitNumber-1)/800)
end of frustum[bigger end] (x^splitNumber/2048)/(x^(splitNumber-1)/800)
you get under sampling if value is above 1 and over sampling when below 1, if the splits are perfectly calculated the beginning and end values should be the same for each frustum as they are in my case (0.39 and 2. something, dont remember now)
I can produce a graph describing that distribution, next part is to get my equation to accept different camera angles and then light to camera angles. But now in this perfect situation I will search to apply LiPSM with an equation that bring the over and undersampling closer to 1.