// Shadow map always comes in texture unit 0, // so we have to decal all other textures if any... sampler2D indirectTexture : TEXUNIT0; sampler2D sourceTexture : TEXUNIT1; sampler2D visibilityTexture : TEXUNIT2; sampler2D noisyTexture : TEXUNIT3; struct Vertex { float4 position : POSITION; // Fragment's position in screen-space float2 texCoord : TEXCOORD0; // Fragment's texture coordinates float2 subTexCoord : TEXCOORD1; // Fragment's texture coordinates float3 normal : TEXCOORD2; // Fragment's normal in eye-space float3 halfVector : TEXCOORD3; // Fragment's half angle vector in eye-space float3 lightVector : TEXCOORD4; // Fragment's light vector in eye-space float4 wposition : TEXCOORD5; // Vertex position in world-space }; struct Fragment { float4 color : COLOR0; }; Fragment main(Vertex p_In, uniform float4 p_LightDiffuse, // Light diffuse component uniform float p_LightPower, // Light power uniform float4 p_Diffuse, // Material diffuse component uniform float4 p_LightSpecular, // Light specular component uniform float4 p_Specular, // Material specular component + specular exponent uniform float4 p_Ambient, uniform float epsilonX, uniform float epsilonY, uniform float sourceTextureSize, uniform float sqrtNumSamples, uniform float greyRange, uniform float absGreyMin ) { Fragment l_Out; l_Out.color = float4(0.0, 0.0, 0.0, 0.0); float2 epsilon = float2(epsilonX, epsilonY); float4 value = tex2D(indirectTexture, p_In.subTexCoord).xyzw; float2 coords = p_In.texCoord - ( value.xy - epsilon ); if (value.w != 0.0) { float2 unifcoord; float2 scale; unifcoord = (p_In.texCoord - value.xy) * float2(sourceTextureSize, sourceTextureSize); //scale = coords * float2(sourceTextureSize, sourceTextureSize) / float2(sqrtNumSamples, sqrtNumSamples); //float2 newcoord = float2(1.0, 1.0) - value.zw + scale; //float4 diffuseColor = tex2D(sourceTexture, newcoord).xyzw; float4 diffuseColor = tex2D(sourceTexture, unifcoord / float2(sqrtNumSamples, sqrtNumSamples) - epsilon).xyzw; // Normalized normal. float3 l_Normal = normalize(p_In.normal); // Normalized light vector. float3 l_LightVector = normalize(p_In.lightVector); // Normalized half angle vector. float3 l_HalfVector = normalize(p_In.halfVector); // Ambient component //------------------ float3 ambientColor = float3(p_Ambient.xyz); if (diffuseColor.w != 0.0) { float4 visibility = tex2D(visibilityTexture, p_In.subTexCoord).xyzw; //greyRange = greyRange - 0.20; visibility.xyzw = (visibility.xyzw * float4(greyRange, greyRange, greyRange, greyRange)) - float4(absGreyMin, absGreyMin, absGreyMin, absGreyMin); float e = lerp(visibility.x, visibility.y, unifcoord.x); float f = lerp(visibility.w, visibility.z, unifcoord.x); float g = 1.0 - clamp(lerp(e, f, unifcoord.y), 0.0, 1.0); ambientColor += float3(g, g, g); } l_Out.color.rgb = (ambientColor * diffuseColor.rgb); // Diffuse component // ----------------- // Angle between normal and light vector float l_CosNL = clamp(dot(l_Normal, l_LightVector), 0.0, 1.0); // No light can reach back surfaces... if (l_CosNL == 0) { l_CosNL = clamp(-dot(l_Normal, l_LightVector), 0.0, 1.0); } l_Out.color.rgb += (p_Diffuse.rgb * diffuseColor.rgb) * p_LightDiffuse.rgb * l_CosNL + float3(tex2D(noisyTexture,float2(p_In.wposition.x,p_In.wposition.z)/ 10000.0).x * 0.15, tex2D(noisyTexture,float2(p_In.wposition.z,p_In.wposition.x)/10000.0).x * 0.25,0.0); // Specular component // ------------------ // Apply cosine power distribution around mirror direction float l_CosNH = clamp(dot(l_Normal, l_HalfVector), 0.0, 1.0) + clamp(-dot(l_Normal, l_HalfVector), 0.0, 1.0); float l_SpecularPower = pow(l_CosNH, p_Specular.a); float3 l_Specular = (p_Specular.rgb * diffuseColor.rgb) * p_LightSpecular.rgb * l_SpecularPower; // Add specular component //l_Out.color.rgb += l_Specular.rgb; // Modulate by light incoming power l_Out.color.rgb *= p_LightPower; l_Out.color.a = diffuseColor.a; } return l_Out; }