// CSM Shadowmapping + Bloom + Colorgrade
// HDR version
#include "../common/constants.cg"
#include "../common/hdr.cg"
#include "../common/utils.cg"
#include "bloom.cg"
#include "common_fs.cg"
struct VertOut
{
float4 pos : POSITION;
float4 col : COLOR0;
float2 tc0 : TEXCOORD0;
};
struct FragOut
{
float4 col : COLOR;
};
float BlurTexture(sampler2D tex, float2 vin, float blur, sampler2D depthMap)
// With Z sampling
{
return tex2D(tex,vin).a;
}
float ComputeDepthBlur (float depth, float k)
{
float4 vDofVars = float4(0,0,1,1);
// k is the target depth
float f;
depth = 1f/(1-depth)-1f;
depth = 1/depth;
// note that k is 1/target
k = 1f/(1f/(1-k)-1f);
// approximating a thin lens system here.
// assuming an ideal image plane at v0
float v0 = 1.0;
// first, calculate the focal length of the lens
// or rather, the inverse of it
float foc = k + 1/v0;
// now we can calculate the actual imaging plane for our depth
float vx = foc - depth;
// one more constant comes into play
float d = 100.0; // d is aperture width.
f = d*abs(1/foc * (v0-1/foc))*abs(1-v0*vx);
// and as before vx is actually 1/length, to avoid doing a bunch of inverses.
/*if (depth < k)
{
f = (depth-k)/(0.7-0.9);;//(depth - vDofVars.y)/(vDofVars.y - vDofVars.x);
} else
{
//scale to 0...1
f = (k-depth)/(0.7-0.9);//(depth - vDofVars.y)/(vDofVars.z - vDofVars.y);
//clamp far to max blur
}*/
//f = abs((depth-k)/depth)*0.8;
f = clamp (f, 0, max(2.0f,20f*depth));
return f;// * 0.5f + 0.5f;
}
float4 DOFFilter (float2 tc0, sampler2D sceneMap, float depthVar)
{
float2 pixelSizeLow = float2(0.0007, 0.0013);
float2 pixelSizeHigh = float2(0.0005, 0.0009);
float2 vMaxCoC = float2(0.0, 25.0);
float4 cOut;
float discRad;
float discRadLow;
float centerDepth;
float lowScale = 1.84;
cOut = tex2D(sceneMap, tc0);
//float4 cDepth = tex2D(depthMap, tc0);
//depthVar = 0;
cOut.a = depthVar;//cDepth.a;
centerDepth=cOut.a;
//convert depth into blur radius
discRad = abs(cOut.a);
//discRad = abs(cOut.a*vMaxCoC.y - vMaxCoC.x);
discRadLow = discRad * lowScale;
cOut=0;
for(int t=0; t<16; t++)
{
//compute tap coords
float2 coordLow = tc0 + (pixelSizeLow * poissonDisk[t] * discRadLow);
float2 coordHigh = tc0 + (pixelSizeHigh * poissonDisk[t] * discRad);
//fetch high res tap
float4 tapLow = tex2D (sceneMap, coordLow);
float4 tapHigh = tex2D (sceneMap, coordHigh);
//mix high and low taps
float tapBlur = abs(tapHigh.a * 2.0 - 1.0); //put blur into 0...1
float4 tap = lerp(tapHigh, tapLow, tapBlur);
//SMARTblur
tap.a = (tap.a >= centerDepth) ? 1.0 : abs(tap.a * 2.0 - 1.0);
cOut.rgb += tap.rgb * tap.a;
cOut.a += tap.a;
}
return (cOut / cOut.a);
}
FragOut main(
VertOut vin,
uniform sampler2D sceneMap : TEXUNIT0,
uniform sampler2D velocityMap : TEXUNIT1,
/// Z in TEXUNIT5
uniform sampler2D bloomMap1 : TEXUNIT2,
uniform sampler2D bloomMap2 : TEXUNIT3,
uniform sampler2D bloomMap3 : TEXUNIT4,
#ifdef CSM_MRT
uniform sampler2D depthMap : TEXUNIT5,
uniform sampler2D shadowMap : TEXUNIT6,
uniform sampler3D gradeMap : TEXUNIT7,
#else
uniform sampler3D gradeMap : TEXUNIT5, // 3D texture for color grading
uniform sampler2D depthMap : TEXUNIT6,
#endif
uniform float alpha, // Amount of blur
uniform float exposure
)
{
FragOut fout;
float4 ambientColor,
sdColor; // Specular+diffuse
float4 color;
#ifdef CSM_MRT
// Original color
ambientColor=tex2D(sceneMap,vin.tc0);
sdColor=tex2D(shadowMap,vin.tc0);
float shadowAmount=BlurTexture(shadowMap, vin.tc0,smBlurAmount,depthMap);
color=ambientColor+shadowAmount*sdColor;
#else
// Single render-target (RT)
color=tex2D(sceneMap,vin.tc0);
#endif
float4 depthColor=tex2D(depthMap,vin.tc0);
float4 bloomColor=BloomCombineMaps3(bloomMap1,bloomMap2,bloomMap3,vin.tc0);
color=BloomMix(color,bloomColor);
// Show the 3 bloom stages and the end-result in 1 view
/*if(vin.tc0.y>0.5)
{
if(vin.tc0.x>0.666)color=tex2D(bloomMap3,vin.tc0);
else if(vin.tc0.x>0.333)color=tex2D(bloomMap2,vin.tc0);
else color=tex2D(bloomMap1,vin.tc0);
}*/
float depthV = ComputeDepthBlur(depthColor,tex2D(depthMap,float2(0.5f,0.5f)));
//float depthV = ComputeDepthBlur(depthColor,0.91f);
float4 DOFtest = DOFFilter(vin.tc0, sceneMap, depthV);
// HDR -> LDR tonemap
//color.rgb=ToneMapHDR(color,exposure);
DOFtest.rgb=ToneMapHDR(DOFtest,exposure);
// Color grading
//color.rgb=ColorGrade(color.rgb,gradeMap);
//DOFtest.rgb = ColorGrade(DOFtest.rgb,gradeMap);
//fout.col.rgb=color;
// Motion blur blend
//fout.col.a=alpha;
fout.col.rgb = DOFtest.rgb;
//fout.col.rgb = depthV;
fout.col.a = alpha;
//fout.col.rgb=depthColor;
//fout.col.rgb=10f*(depthColor-0.9);
return fout;
}