struct PS_INPUT { #ifdef DEPTH_SHADOWCASTER float3 unused : TEXCOORD0; float depth : TEXCOORD1; #else float2 uv0 : TEXCOORD0; float3 Normal : TEXCOORD1; float3 vPos : TEXCOORD2; #ifdef DEPTH_SHADOWRECEIVER float4 lightSpacePos : TEXCOORD3; #endif #endif }; #define SHADOW_BIAS 0 //--------------------------------------------- //Vertex Shader Output //--------------------------------------------- struct VS_OUTPUT { float4 Position : POSITION; PS_INPUT ps; }; SamplerState g_samLinear { Filter = MIN_MAG_MIP_LINEAR; AddressU = Wrap; AddressV = Wrap; }; #include "shadows.hlsl" #define BIAS 0 struct VS_OUT { float4 pos : POSITION; float3 diffuseUV : TEXCOORD0; // xy = UV, z = fog/depth #if !SHADOWCASTER float3 col : COLOR; #endif #if DEPTH_SHADOWCASTER float depth : TEXCOORD1; #endif #if DEPTH_SHADOWRECEIVER float4 lightSpacePos0 : TEXCOORD2; float4 lightSpacePos1 : TEXCOORD3; float4 lightSpacePos2 : TEXCOORD4; #endif }; VS_OUT main_vp( float4 pos : POSITION, float3 normal : NORMAL, float4 uv0 : TEXCOORD0, uniform float4x4 worldViewProj, uniform float4 lightPosition, uniform float3 lightDiffuse #if FOG , uniform float2 fogParams // x = fog start, y = fog distance #endif #if DEPTH_SHADOWCASTER , uniform float4 depthRange // x = min, y = max, z = range, w = 1/range #elif DEPTH_SHADOWRECEIVER , uniform float4 depthRange0 // x = min, y = max, z = range, w = 1/range , uniform float4 depthRange1 // x = min, y = max, z = range, w = 1/range , uniform float4 depthRange2 // x = min, y = max, z = range, w = 1/range #endif #if DEPTH_SHADOWRECEIVER , uniform float4x4 texWorldViewProjMatrix0 , uniform float4x4 texWorldViewProjMatrix1 , uniform float4x4 texWorldViewProjMatrix2 #endif ) { VS_OUT outp; // project position to the screen outp.pos = mul(worldViewProj, pos); #if !SHADOWCASTER // Get object space light direction float3 lightDir = normalize(lightPosition.xyz - (pos.xyz * lightPosition.w).xyz); outp.col = lightDiffuse.xyz * max(dot(lightDir, normal.xyz), 0.0); # if FOG outp.diffuseUV.z = linearFog(outp.pos.z, fogParams.x, fogParams.y); # endif #endif // pass through other texcoords exactly as they were received outp.diffuseUV.xy = uv0.xy; #if DEPTH_SHADOWCASTER outp.depth = (BIAS + outp.pos.z - depthRange.x) * depthRange.w; #endif #if DEPTH_SHADOWRECEIVER // Calculate the position of vertex in light space outp.lightSpacePos0 = mul(texWorldViewProjMatrix0, pos); outp.lightSpacePos1 = mul(texWorldViewProjMatrix1, pos); outp.lightSpacePos2 = mul(texWorldViewProjMatrix2, pos); // make linear outp.lightSpacePos0.z = (outp.lightSpacePos0.z - depthRange0.x) * depthRange0.w; outp.lightSpacePos1.z = (outp.lightSpacePos1.z - depthRange1.x) * depthRange1.w; outp.lightSpacePos2.z = (outp.lightSpacePos2.z - depthRange2.x) * depthRange2.w; // pass cam depth outp.diffuseUV.z = outp.pos.z; #endif return outp; } float4 caster_fp( VS_OUT In, uniform texture2D diffuseMap : register(s0), #if DEPTH_SHADOWRECEIVER uniform Texture2D shadowMap0 : register(s1), uniform Texture2D shadowMap1 : register(s2), uniform Texture2D shadowMap2 : register(s3), #endif uniform float3 materialAmbient #if SHADOWCASTER , uniform float3 shadowColour #endif #if FOG , uniform float3 fogColour #endif #if DEPTH_SHADOWRECEIVER , uniform float inverseShadowmapSize0 , uniform float inverseShadowmapSize1 , uniform float inverseShadowmapSize2 , uniform float4 pssmSplitPoints #endif ) : SV_Target { // look up the diffuse map layer float4 texDiffuse = diffuseMap.Sample(g_samLinear, In.diffuseUV.xy); #if SHADOWCASTER # if DEPTH_SHADOWCASTER // early-out with depth (we still include alpha for those cards that support it) return float4(In.depth.xxx, 1); # else return float4(shadowColour.xyz, texDiffuse.a); # endif #else // compute the ambient contribution (pulled from the diffuse map) float3 vAmbient = texDiffuse.xyz * materialAmbient.xyz; float3 vColor3 = texDiffuse.rgb * In.col.rgb; # if DEPTH_SHADOWRECEIVER float camDepth = In.diffuseUV.z; float shadow = calcPSSMDepthShadow(shadowMap0, shadowMap1, shadowMap2, In.lightSpacePos0, In.lightSpacePos1, In.lightSpacePos2, inverseShadowmapSize0, inverseShadowmapSize1, inverseShadowmapSize2, pssmSplitPoints, camDepth); vColor3 *= shadow; /* vAmbient = float3(0,0,0); vColor3 = calcPSSMDebugShadow(shadowMap0, shadowMap1, shadowMap2, In.lightSpacePos0, In.lightSpacePos1, In.lightSpacePos2, inverseShadowmapSize0, inverseShadowmapSize1, inverseShadowmapSize2, pssmSplitPoints, camDepth); */ # endif float4 vColor; vColor = float4(vColor3 + vAmbient, texDiffuse.a); # if FOG // if fog is active, interpolate between the unfogged color and the fog color // based on vertex shader fog value vColor.rgb = lerp(vColor.rgb, fogColour, In.diffuseUV.z).rgb; # endif return vColor; #endif }