Zaslal: PcMaster
Popis: HLSL .fx ShadowMap + PCF
Jazyk: C++
Vloženo: 28.2.2010, 18:09
Stáhnout jako soubor
float Script : STANDARDSGLOBAL < string UIWidget = "none"; string ScriptClass = "scene"; string ScriptOrder = "postprocess"; string ScriptOutput = "color"; string Script = "Technique=Main;"; > = 0.8; float4 ClearColor <string UIWidget="None";> = {0,0,0,0.0}; float ClearDepth <string UIWidget="None";> = 1.0; float4 ShadowClearColor <string UIWidget="None";> = {1.0,1.0,1.0,1.0}; float4x4 WorldXf : World <string UIWidget="None";>; float4x4 WorldViewProjXf : WorldViewProjection <string UIWidget="None";>; float4x4 WorldITXf : WorldInverseTranspose <string UIWidget="None";>; float4x4 LampViewXf : View <string frustum = "light0";>; float4x4 LampProjXf : Projection <string frustum = "light0";>; /////////////////////////////////////////////////////////////// /// TWEAKABLES ////////////////////////////// /////////////////////////////////////////////////////////////// float ShadBias < string UIWidget = "slider"; float UIMin = -0.1; float UIMax = +0.1; float UIStep = 0.00005; string UIName = "Shadow Bias"; > = 0.0001; float SpotLightCone < string UIWidget = "slider"; float UIMin = 0.0; float UIMax = 90.0; float UIStep = 0.1; string UIName = "Cone Angle"; > = 45.0f; float3 SpotLightPos : POSITION < string UIName = "Light Posistion"; string Object = "SpotLight"; string Space = "World"; > = {-1.0f, 1.0f, 0.0f}; //////////////////////////////////////////////////////// /// TEXTURES ////////////////////////// //////////////////////////////////////////////////////// #define SHADOW_SIZE 1024 texture ShadMap : RENDERCOLORTARGET < float2 Dimensions = { SHADOW_SIZE, SHADOW_SIZE }; string Format = ("r32f") ; string UIWidget = "None"; >; sampler ShadSampler = sampler_state { texture = <ShadMap>; AddressU = CLAMP; AddressV = CLAMP; MipFilter = NONE; MinFilter = POINT; MagFilter = POINT; }; texture ShadDepthTarget : RENDERDEPTHSTENCILTARGET < float2 Dimensions = { SHADOW_SIZE, SHADOW_SIZE }; string format = "D24S8"; string UIWidget = "None"; >; struct VertexIn1 { float4 Position : POSITION0; }; struct VertexIn2 { float4 Position : POSITION0; float3 Normal : NORMAL0; }; struct VertexOut1 { float4 Position : POSITION; //float4 LightSpacePos : TEXCOORD0; float Depth : TEXCOORD0; }; struct VertexOut2 { float4 Position : POSITION; float4 LightSpacePos : TEXCOORD0; float4 WorldPos : TEXCOORD1; float3 Normal : TEXCOORD2; }; // Converts position into light view space float4 GetPositionFromLight(float4 position) { float4x4 LightWVP = mul(mul(WorldXf, LampViewXf), LampProjXf); return mul(position, LightWVP); } VertexOut1 shadowVS(VertexIn1 IN) { VertexOut1 OUT = (VertexOut1)0; OUT.Position = GetPositionFromLight(IN.Position); //OUT.LightSpacePos = GetPositionFromLight(IN.Position); OUT.Depth = 1.0 - (OUT.Position.z / OUT.Position.w); return OUT; } float4 shadowPS(VertexOut1 IN) : COLOR { // MS says that this will increase precision and can actually be done in VS // watch out for "1.0 -" in next pass too :) // if we do it HERE, the precision is terrible // if we do it in VS, it is OK :O // return 1.0 - (IN.LightSpacePos.z / IN.LightSpacePos.w); return float4(IN.Depth, 0, 0, 1); } VertexOut2 mainCamVS(VertexIn2 IN) { VertexOut2 OUT = (VertexOut2)0; OUT.Position = mul(IN.Position, WorldViewProjXf); OUT.LightSpacePos = GetPositionFromLight(IN.Position); OUT.WorldPos = mul(IN.Position, WorldXf); OUT.Normal = mul(IN.Normal, WorldITXf); return OUT; } float4 useShadowPS(VertexOut2 IN) : COLOR { // calculate the depth of the fragment in the lightspace float depthFromCurrentDepth = IN.LightSpacePos.z / IN.LightSpacePos.w; // project the fragment into the lightspace and the shadowmap float sum = 0; float x, y; for (y = -1.5; y <= 1.5; y += 1.0) { for (x = -1.5; x <= 1.5; x += 1.0) { float2 proj = float2(0.5, -0.5) * IN.LightSpacePos.xy/IN.LightSpacePos.w + float2(0.5, 0.5) + float2(x,y) / SHADOW_SIZE; // get a depth sample from the shadowmap float s = 1.0 - tex2D(ShadSampler, proj).r; sum += 1-step(s, depthFromCurrentDepth - ShadBias); } } float shadow = sum / 16.0; float3 toLight = normalize(SpotLightPos - IN.WorldPos); // diffuse lighting float d = dot(toLight, normalize(IN.Normal)); // spotlight cone fadeout float3 toLightLightSpace = normalize(-IN.LightSpacePos.xyz/IN.LightSpacePos.w); float c = dot(toLightLightSpace, float3(0, 0, -1)); return shadow * d * sin(3.14159 * SpotLightCone / 180.0) * c; } //////////////////////////////////////////////////////////////////// /// TECHNIQUES ///////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// technique Main < string Script = "Pass=MakeShadow;" "Pass=UseShadow;"; > { pass MakeShadow < string Script = "RenderColorTarget0=ShadMap;" "RenderDepthStencilTarget=ShadDepthTarget;" "RenderPort=light0;" "ClearSetColor=ShadowClearColor;" "ClearSetDepth=ClearDepth;" "Clear=Color;" "Clear=Depth;" "Draw=geometry;"; > { VertexShader = compile vs_2_0 shadowVS(); ZEnable = true; ZWriteEnable = true; ZFunc = LessEqual; CullMode = None; PixelShader = compile ps_2_0 shadowPS(); } pass UseShadow < string Script = "RenderColorTarget0=;" "RenderDepthStencilTarget=;" "RenderPort=;" "ClearSetColor=ClearColor;" "ClearSetDepth=ClearDepth;" "Clear=Color;" "Clear=Depth;" "Draw=geometry;"; > { VertexShader = compile vs_3_0 mainCamVS(); ZEnable = true; ZWriteEnable = true; ZFunc = LessEqual; CullMode = None; PixelShader = compile ps_3_0 useShadowPS(); } }
© 2006 Michal Tuláček, Syntax Highlight - GeSHi (thx bref)