I have finally gotten a chance to implement the soft shadow algorithm which I have been blathering on about. I used Pocketmoon’s soft shadow Cg contest entry and simply rewrote the fragment shader.
Here is the code:
EDIT: Code seems to be really hard to copy and paste out of a browser. You can get the code from here: http://www.io.com/~fenix/cg_shimmerFP.cg
// ***** *** *** * * * * ****** ***
// * * * * ** * * * * * *
// * * * * * * * * * * *
// * * * * * * * * * * *
// * * * * * * * * * * *
// * * * * * * * * * * *
// * * * * * * * * * * *
// * * * * ** * * * * *
// ***** * * * * ****** ***
////Copyright (c) 2002 Rob James - see license.txt for details
//A lot of additional work by Jason Wilkins
//(Nakoruru, fenix AT io DOT com). This
//code is almost completely rewritten, but
//I would not feel comfortable taking
//copyright unless Rob told me I could.struct v2f
{
float4 HPosition : POSITION;
float4 Color0 : COLOR0;
float4 Color1 : COLOR1;
float4 TC0 : TEXCOORD0;
float4 TC1 : TEXCOORD1;
float4 TC2 : TEXCOORD2; // normal
float4 TC3 : TEXCOORD3; // world space light vec
};fragout main (v2f IN, uniform samplerRECT tex0 : texunit0)
{
const float surf = (length(IN.TC1.xyz) / 6.5);float shadow;
#define SHADOW_SMOOTHSTEP smoothstep(-0.005, -0.001, surf - occl)
//Sample 1
float occl = f1texRECTproj(tex0, IN.TC0.xyw);
shadow = SHADOW_SMOOTHSTEP;float scale = 200.0 * sqrt(1 - (occl / surf));
#define SAMPLE(x, y) (IN.TC0.xyw + float3((x), (y), 0))
//sample 2
occl = f1texRECTproj(tex0, SAMPLE(scale, scale));
shadow += SHADOW_SMOOTHSTEP;//sample 3
occl = f1texRECTproj(tex0, SAMPLE(-scale, -scale));
shadow += SHADOW_SMOOTHSTEP;//sample 4
occl = f1texRECTproj(tex0, SAMPLE(-scale, scale));
shadow += SHADOW_SMOOTHSTEP;//sample 5
occl = f1texRECTproj(tex0, SAMPLE(scale, -scale));
shadow += SHADOW_SMOOTHSTEP;shadow /= 5.0;
fragout OUT;
OUT.col.xyz = IN.Color0.xyz * (1.0 - shadow);
return OUT;
}
It takes 5 shadow samples in a quincunx pattern.
I ended up using a square root in the pattern scaling function when I realized that linear scaling resulted in a prenumbra that was the same size no matter how far away from the light the occluder and surface are. It looks right, but I am too tired to figure out why
Thanks to Pocketmoon, it was not too hard for me to just jump in and modify the shader, except I would appreciate it more if your program reported compiler errors
The code is kinda sloppy. I wanna change it to make adding additional samples easier, but I am only half way there.
The smoothstep is an attempt to smooth out the shadow acne, but it doesn’t work
I have not spent enough time trying to understand how Pocketmoon’s anti-acne cream works.
I took out the specular lighting because I thought it was distracting.
EDIT: More details…
I removed the ddx, ddy stuff. It was completely screwing up the shape of the shadows. I wonder why it was there to begin with.
To use this code you should get the soft shadow contest entry from the www.cgshaders.com sight and replace the fragment shader with this code.
Make sure the gamma is high on your monitor. I did not want to fool the eye too much so I have no ambient light (it would soften the shadows unfairly).
I’ll make some screen shots later. Cannot wait to see how fast this will run on NV30!
MORE EDIT:
The reason the shadows do not seem as soft as they should is that even though the shadows are soft, they are not any bigger they seem to be ‘stenciled’ inside what would be the hard shadow if there was only one sample. I have some ideas as to why that is the case… (by stenciled I do not mean stencil buffer, just that for some reasons the shadows are the same shape as a hardshadow, which is wrong).
EVEN MORE EDIT:
Changed the code to make the light size more managable. The 200.0 is the light size. MAke it bigger to make shadows softer.
Figured out why the shadows do not seem to get bigger like they should. It is because the center point is the point used to determine how big the sample pattern is. Because of this, if the center sample does not hit an occluder then the sample pattern will be reduced to a point sample (5 samples from the same point). The code probably needs to be changed to determine sample size by some heuristic that would allow it to catch occluder edges that are not straight towards the light.
[This message has been edited by Nakoruru (edited 10-11-2002).]
[This message has been edited by Nakoruru (edited 10-11-2002).]