1 registered members (TipmyPip),
18,388
guests, and 6
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
dual pass Projective Shadow Mapping
#222324
08/18/08 21:11
08/18/08 21:11
|
Joined: Apr 2008
Posts: 235 TEXCOORD3
Foxfire
OP
Member
|
OP
Member
Joined: Apr 2008
Posts: 235
TEXCOORD3
|
Hello! As a celebration of my recent status, I am releasing my sual pass Projective Shadow Mapping shader!!!
I will try and get my website up asap so you can easily download the efffect but i'll post it here too.
The effect runs at about 62 fps compared to 40 fps: 3-stage shadow mapper. The effect's downside is its shadow bluring quality that uses only a partial box blur projective divide due to arithmetic slot limits.
A future model (version 2.0) will feature a linear search algorithem for smoothing the shadows that are pixelated due to texture sampler size restrictions from the projective look up.
Please enjoy and do not distribute or modify. I can't stop you from doing these things but if I find the content being abused, I will not contribte in the future.
-Mike-
http://www.groundtacticsgame.com/Alienware m17x R Custom laptop specs: Intel Core 2 Extreme Quad CPU Q9300 2x Nvidia 280GTX 2GB vram 6GB ddr3 memory@ 1333Mhz 512GB SSD 1200p 17' screen runs Crysis Warhead on max settings at 1200p at 90 fps
|
|
|
Re: dual pass Projective Shadow Mapping
[Re: Foxfire]
#222328
08/18/08 21:26
08/18/08 21:26
|
Joined: Apr 2008
Posts: 235 TEXCOORD3
Foxfire
OP
Member
|
OP
Member
Joined: Apr 2008
Posts: 235
TEXCOORD3
|
//Projective Shadow Mapping by Michael Auerbach (c) 2008//
/* This shader is a 2 stage shader that takes a pre-rendered depth map to calculate the depth differences of each screen-space pixel at 2 different perspectives. Although expensive at first, projective shadow mapping is a far more natural and efficient way of rendering shadows in complex scenes.
This shader is also optimized to run in one pass and only requires 1 pre- -rendering stage and no post-processing.
Future improvments would be supporting more than one render-target, matrix, and light source per mesh. Additional optimizations must be included.
version 1.0
FULLY commented
preformance:
~60fps @ 3072 shader modules w/ 2048 visable polygons w/ alpha overlays @ 1024 pixels^2
*/
///////////////////////////// //----Vars and Samplers----// /////////////////////////////
//--Tweakables-------------// static const float dark_term = 0.3;//Multiplication value for pixels in shadow static const float light_term = 0.8;//Multiplication value for illuminated pixels static const float edge_smooth = 0.995;//shadow vertex blending and real/map depth offset //--higher = sharper shadow detection/z-errors //--lower = smoother shadows around surfaces/shadow offset erors
//--Application fed data--// const float4x4 matWorldViewProj; // World*view*projection matrix const float4x4 matWorld; // World matrix const float4x4 matMtl; // Precalculated texture projection matrix (screen adjusted matViewProj of light source)
//--Textures (app fed)----// texture TargetMap;//render target of pre-rendered depth map texture entSkin1;//entity skin1 (color map) texture mtlSkin1;//projection texture
//--Samplers--------------// sampler depth_map = sampler_state { Texture = <TargetMap>;//depth buffer AddressU = 4;//use *border* value float4(0,0,0,0) AddressV = 4;//use *border* value float4(0,0,0,0) MinFilter = 3;//D3DTEXF_ANISOTROPIC filter. GAUSSIANQUAD(7) is also very nice but expensive MipFilter = 3;//D3DTEXF_ANISOTROPIC filter. GAUSSIANQUAD(7) is also very nice but expensive MagFilter = 3;//D3DTEXF_ANISOTROPIC filter. GAUSSIANQUAD(7) is also very nice but expensive }; sampler projection_map = sampler_state { Texture = <mtlSkin1>;//projection texture AddressU = 3;//clamp coords AddressV = 3;//clamp coords }; sampler base_map = sampler_state { Texture = <entSkin1>;//color map AddressU = 1;//repeat coords AddressV = 1;//repeat coords }; ///////////////////////////// //--VS/PS data structures--// /////////////////////////////
//App fed Vertex input structure: struct Vertex_in { float4 Pos: POSITION; float2 Tex: TEXCOORD0; };
//Vertex shader output: struct Vertex_out { float4 Pos: POSITION; float2 Tex: TEXCOORD0; float4 Depth: TEXCOORD2;//a float4 for proj. tex coords. };
//////////////////////////////////// //--Shadow mapping vertex shader--// ////////////////////////////////////
Vertex_out ShadowMapping_VS (Vertex_in IN) { //Create a temp output struct Vertex_out OUT;
//Transform the vertex from object space to clip space: OUT.Pos = mul(IN.Pos, matWorldViewProj); //Send tex coords to PS OUT.Tex = IN.Tex; //Calculate the projective texture coordinates OUT.Depth = mul( mul(IN.Pos,matWorld), matMtl ); //return temp output struct return OUT; }
//////////////////////////////////// //--distance comparison function--// ////////////////////////////////////
//future improvments: //-use a simple rate equation to interpolate 45 degree pixel coords: //result would smooth diagonal lines and create a much more refined pixel search //note: above must be done in regard of projection transformation
float fetch_shadow(float4 coord) { //return fDark if light Depth < view Depth for pixel //(if less, an object obstructed the light view,creating a depth value that is in front of the view pixel) return tex2Dproj(depth_map,coord).r < (coord.z*edge_smooth)? dark_term : light_term; }
/////////////////////////////////// //--Shadow mapping pixel shader--// ///////////////////////////////////
float4 ShadowMapping_PS (Vertex_out IN) : COLOR0 { // Calculate the shadow term float shadow_term = fetch_shadow(IN.Depth);
//result; set to diffuse value (texture) float4 r0 = tex2D(base_map,IN.Tex); //projection texture: rgb == color, a == gamma (support for hdr soon) float4 projection = tex2Dproj(projection_map,IN.Depth).rgba; //multiply result by projection color if in light (avoids using else for aliasing reasons) if((shadow_term == light_term)&&(IN.Depth.z > 0)) { r0.rgb *= projection.rgb; } //partial box blur //quality is considerably lower than a 2 stage shadow shader shadow_term += fetch_shadow(float4(IN.Depth.x * 1.001,IN.Depth.y * 1.001,IN.Depth.z,IN.Depth.w)); shadow_term += fetch_shadow(float4(IN.Depth.x * 0.999,IN.Depth.y * 1.001,IN.Depth.z,IN.Depth.w)); shadow_term += fetch_shadow(float4(IN.Depth.x * 1.001,IN.Depth.y * 0.999,IN.Depth.z,IN.Depth.w)); shadow_term += fetch_shadow(float4(IN.Depth.x * 0.999,IN.Depth.y * 0.999,IN.Depth.z,IN.Depth.w)); shadow_term += fetch_shadow(float4(IN.Depth.x * 1.002,IN.Depth.y,IN.Depth.z,IN.Depth.w)); shadow_term += fetch_shadow(float4(IN.Depth.x * 0.998,IN.Depth.y,IN.Depth.z,IN.Depth.w)); //average sumed color values shadow_term /= 7; //multiply shadow term by projection gamma shadow_term *= projection.a; //if depth is behind light, set shadow term to fDark (v1.0,set to 0) if((IN.Depth.z < 0)) { shadow_term = 0; } //multiply result by shadow term r0.rgb *= shadow_term; //return ((tex*shadow*gamma*proj_color),tex alpha value) return r0; }
///////////////// //--Technique--// /////////////////
technique techShadow { pass p0 { ZWriteEnable = True;//allow z-writing for overlay shadows AlphaTestEnable = True;//test alpha for overlay value - reomves black edges of overlays AlphaFunc = Greater;//must be greater to replace overlay/alpha AlphaRef = 97;//give some room for error in overlay textures //compile both shaders VertexShader = compile vs_2_0 ShadowMapping_VS(); PixelShader = compile ps_2_0 ShadowMapping_PS(); } }
http://www.groundtacticsgame.com/Alienware m17x R Custom laptop specs: Intel Core 2 Extreme Quad CPU Q9300 2x Nvidia 280GTX 2GB vram 6GB ddr3 memory@ 1333Mhz 512GB SSD 1200p 17' screen runs Crysis Warhead on max settings at 1200p at 90 fps
|
|
|
Re: dual pass Projective Shadow Mapping
[Re: Foxfire]
#222330
08/18/08 21:29
08/18/08 21:29
|
Joined: Apr 2008
Posts: 235 TEXCOORD3
Foxfire
OP
Member
|
OP
Member
Joined: Apr 2008
Posts: 235
TEXCOORD3
|
Here we go. Some info: entSkin1 == texture mtlSkin1 == projection texture (rgba, rgb == color, a == gamma&gradient (hdr)) targetmap == raw depth data from a light or view source
requires VS/PS 2.0
requires a GPU that supports zwriteenable for projective shadowing, see CAPPS
enjoy, -Michael Auerbach-
oh yeah, I used TEXCOORD2 to overwrite the tangent flag in case someone set this.
Last edited by Foxfire; 08/18/08 21:31.
http://www.groundtacticsgame.com/Alienware m17x R Custom laptop specs: Intel Core 2 Extreme Quad CPU Q9300 2x Nvidia 280GTX 2GB vram 6GB ddr3 memory@ 1333Mhz 512GB SSD 1200p 17' screen runs Crysis Warhead on max settings at 1200p at 90 fps
|
|
|
Re: dual pass Projective Shadow Mapping
[Re: Nowherebrain]
#222358
08/18/08 23:29
08/18/08 23:29
|
Joined: Apr 2008
Posts: 235 TEXCOORD3
Foxfire
OP
Member
|
OP
Member
Joined: Apr 2008
Posts: 235
TEXCOORD3
|
hey,
ok, first off, this example only requires 2 view stages. It is about 40% faster than previous models. It supports projective texturing as well.
I use multiplication for the box-blur to make the blur independent of the viewing distance.
You MAY change the code but not the header with my copyright.
http://www.groundtacticsgame.com/Alienware m17x R Custom laptop specs: Intel Core 2 Extreme Quad CPU Q9300 2x Nvidia 280GTX 2GB vram 6GB ddr3 memory@ 1333Mhz 512GB SSD 1200p 17' screen runs Crysis Warhead on max settings at 1200p at 90 fps
|
|
|
|