#include "../shaderenv.h" struct fragment { // normalized screen position float4 pos: WPOS; float4 texCoord: TEXCOORD0; float3 view: COLOR0; }; struct pixel { float4 color: COLOR0; }; float2 myreflect(float2 pt, float2 n) { // distance to plane float d = dot(n, pt); // reflect around plane float2 rpt = pt - d * 2.0f * n; return rpt; } /** function for standard deferred shading */ float4 shade(fragment IN, uniform float4 color, uniform float4 position, uniform float3 normal, uniform float emmisive, float3 lightDir) { // diffuse intensity const float angle = saturate(dot(normal, lightDir)); float4 lightDiffuse = glstate.light[0].diffuse; float4 diffuse = angle * lightDiffuse; // global ambient const float4 ambient = glstate.light[0].ambient; float4 outColor; //if (color.w > 1e19f) outColor = color; if (emmisive > 1.5f) outColor = color; else outColor = (ambient + diffuse) * color; return outColor; //return saturate((((ambient + diffuse)) * (1.0f - emmisive) + emmisive) * color); } /** The mrt shader for standard rendering */ pixel main(fragment IN, uniform sampler2D colors, uniform sampler2D positions, uniform sampler2D normals, uniform float3 lightDir ) { pixel OUT; float4 norm = tex2D(normals, IN.texCoord.xy); float4 color = tex2Dlod(colors, float4(IN.texCoord.xy, 0, 0)); float4 position = tex2D(positions, IN.texCoord.xy); // an ambient color term float amb = color.w; float3 normal = normalize(norm.xyz); float4 col = shade(IN, color, position, normal, amb, lightDir); OUT.color = col; //////////// //-- write out logaritmic luminance for tone mapping const float3 w = float3(0.299f, 0.587f, 0.114f); float lum = dot(OUT.color.rgb, w); float logLum = log(1e-5f + lum); float logLumOffset = MINLOGLUM * INV_LOGLUM_RANGE; float logLumScaled = logLum * INV_LOGLUM_RANGE - logLumOffset; OUT.color.w = logLumScaled; return OUT; } float CalcShadowTerm(fragment IN, uniform sampler2D shadowMap, uniform float w, uniform float2 lightSpacePos, uniform float depth, uniform float2 samples[NUM_PCF_TABS], uniform sampler2D noiseTexture ) { //float shadowDepth = tex2D(shadowMap, lightSpacePos).x; //return step(depth, shadowDepth); float total_d = 0.0; for (int i = 0; i < NUM_PCF_TABS; ++ i) { const float2 offset = samples[i]; #if 1 //////////////////// //-- add random noise: reflect around random normal vector (warning: slow!) float2 mynoise = tex2D(noiseTexture, IN.texCoord.xy).xy; const float2 offsetTransformed = myreflect(offset, mynoise); #else const float2 offsetTransformed = offset; #endif // weight with projected coordinate to reach similar kernel size for near and far float2 texcoord = lightSpacePos + offsetTransformed * w; float shadowDepth = tex2D(shadowMap, texcoord).x; total_d += step(depth, shadowDepth); } total_d /= (float)NUM_PCF_TABS; return total_d; } pixel main_shadow(fragment IN, uniform sampler2D colors, uniform sampler2D positions, uniform sampler2D normals, uniform sampler2D shadowMap, uniform float4x4 shadowMatrix, uniform float maxDepth, uniform float sampleWidth, uniform sampler2D noiseTexture, uniform float2 samples[NUM_PCF_TABS], uniform float3 lightDir ) { pixel OUT; float4 norm = tex2D(normals, IN.texCoord.xy); float4 color = tex2Dlod(colors, float4(IN.texCoord.xy, 0, 0)); float4 position = tex2D(positions, IN.texCoord.xy); const float3 normal = normalize(norm.xyz); // hack: an emmisive color term float emmisive = color.w; // diffuse intensity const float angle = saturate(dot(normal, lightDir)); //float4 lightDiffuse = float4(1.0f, 1.0f, 0.9f, 1.0f); const float4 lightDiffuse = glstate.light[0].diffuse; //float4(1.0f, 1.0f, 0.9f, 1.0f); float4 diffuse = lightDiffuse * angle; // calc diffuse illumination + shadow term if ((emmisive < 1.5f) // hack: prevent shadowing the sky && (angle > 1e-3f) // shadow only if diffuse color has some minimum intensity ) { position *= maxDepth; position.w = 1.0f; float4 lightSpacePos = mul(shadowMatrix, position); lightSpacePos /= lightSpacePos.w; float shadowTerm = CalcShadowTerm(IN, shadowMap, sampleWidth, lightSpacePos.xy, lightSpacePos.z, samples, noiseTexture); diffuse *= shadowTerm; } // light ambient term const float4 ambient = glstate.light[0].ambient; // base lighting OUT.color = (emmisive > 1.5f) ? color: (ambient + diffuse) * color; //////////// //-- write out logaritmic luminance for tone mapping const float3 w = float3(0.299f, 0.587f, 0.114f); float lum = dot(OUT.color.rgb, w); float logLum = log(1e-5f + lum); float logLumOffset = MINLOGLUM * INV_LOGLUM_RANGE; float logLumScaled = logLum * INV_LOGLUM_RANGE - logLumOffset; OUT.color.w = logLumScaled; return OUT; }