= 0.8; /********* tweakables ********************/ float4x4 WorldViewProj : WorldViewProjection < string UIWidget="None"; >; float3 SurfColor < string UIWidget = "color"; string UIName = "Surface"; > = {1,.9,.8}; float4 LightPos : Position < string Object = "PointLight"; string Space = "World"; > = {100.0f, 100.0f, 100.0f, 0.0f}; float GeomInset < string UIWidget = "slider"; float UIMin = 0; float UIMax = 0.02; float UIStep = 0.001; string UIName = "Geometric Inset"; > = 0.003; float ShadowExtrudeDist < string UIName = "Extrusion Distance"; string UIWidget = "slider"; float UIMin = 1.0; float UIMax = 100.0; float UIStep = 0.1; > = 100.0f; /************ structs and connections *****************************/ struct appdata { float4 Position : POSITION; float2 UV : TEXCOORD0; float3 Normal : NORMAL; }; /* data passed from vertex shader to pixel shader */ struct vertexOutput { float4 HPosition : POSITION; // float4 TexCoord0 : TEXCOORD0; // dot prods against half-angle float4 diffCol : COLOR0; }; /*********** vertex shader ******/ vertexOutput extrudeVS( appdata IN) { vertexOutput OUT; // Create normalized vector from vertex to light float4 Lvec = normalize( IN.Position - LightPos ); // N dot L to decide if point should be moved away // from the light to extrude the volume float ldn = dot( -Lvec.xyz, IN.Normal.xyz ); ////////////////////////////////////////////////////////// // Inset the position along the normal vector direction // This moves the shadow volume points inside the model // slightly to minimize poping of shadowed areas as // each facet comes in and out of shadow. float4 inset_pos = float4(((IN.Position.xyz - (IN.Normal * GeomInset)).xyz),IN.Position.w); // scale the vector from light to vertex float4 extrusion_vec = Lvec * ShadowExtrudeDist; // if ldn < 0 then the vertex faces away from the light, so // move it. It will be moved along the direction from // light to vertex to extrude the shadow volume. // Consts_0512 = { 0.0f, 0.5f, 1.0f, 2.0f }; // So this does toggle = N dot L < 0 ? 1.0 : 0.0 float toggle = (float) (ldn < 0.0); // Move the back-facing shadow volume points float4 new_position = extrusion_vec*toggle + inset_pos; OUT.HPosition = mul( new_position, WorldViewProj); //////////////////////////////////////////////////////// OUT.diffCol = float4(IN.UV.xy,0,1); // OUT.TexCoord0 = IN.TexCoord0.xyyy; return( OUT ); } vertexOutput backingVS(appdata IN) { vertexOutput OUT; OUT.HPosition = mul(IN.Position, WorldViewProj); OUT.diffCol = float4(0.1,0.1,0.1,1); // OUT.TexCoord0 = float4(0, 0, 0, 1); return( OUT ); } vertexOutput simpleVS( appdata IN) { vertexOutput OUT; float4 Lvec = normalize( IN.Position - LightPos ); float ldn = abs(dot(-Lvec.xyz, IN.Normal.xyz )); OUT.HPosition = mul( IN.Position, WorldViewProj ); OUT.diffCol = float4((ldn*SurfColor),1); // OUT.TexCoord0 = float4(0,0,0,1); return( OUT ); } /*************** techniques *******************/ technique stencilShadow < string Script = "Pass=layZ;" "Pass=back;" "Pass=front;" "Pass=lighting;"; > { pass layZ < string Script = "Draw=geometry;"; > { VertexShader = compile vs_1_0 backingVS(); ZEnable = true; ZWriteEnable = true; CullMode = None; StencilEnable = false; } pass back < string Script = "Draw=geometry;"; > { VertexShader = compile vs_1_1 extrudeVS(); ZEnable = true; ZWriteEnable = true; ZFunc = lessequal; CullMode = CW; StencilEnable = True; StencilPass = Keep; StencilFail = Keep; StencilZFail = IncrSat; StencilFunc = Always; ColorWriteEnable = 0; } pass front < string Script = "Draw=geometry;"; > { VertexShader = compile vs_1_1 extrudeVS(); ZEnable = true; ZWriteEnable = true; ZFunc = lessequal; CullMode = CCW; // TwoSidedStencilMode = false; // needed? StencilEnable = True; StencilPass = Keep; StencilFail = Keep; StencilZFail = DecrSat; StencilFunc = Always; ColorWriteEnable = 0; } pass lighting < string Script = "Draw=geometry;"; > { VertexShader = compile vs_1_1 simpleVS(); ZEnable = true; // ZWriteEnable = true; CullMode = None; StencilEnable = True; StencilPass = Keep; StencilZFail = Keep; StencilFail = Keep; StencilRef = 0; StencilFunc = Equal; } } ///////////////////// technique showVolume < string Script = "Pass=layZ;"; > { pass layZ < string Script = "Draw=geometry;"; > { VertexShader = compile vs_1_1 extrudeVS(); ZEnable = true; ZWriteEnable = true; CullMode = CCW; // None; StencilEnable = false; } } //////////////////// technique simple < string Script = "Pass=layZ;"; > { pass layZ < string Script = "Draw=geometry;"; > { VertexShader = compile vs_1_1 simpleVS(); ZEnable = true; ZWriteEnable = true; CullMode = None; StencilEnable = false; } } /********************************** eof ***/ ]]>