84 lines
2.9 KiB
GLSL
84 lines
2.9 KiB
GLSL
|
#extension GL_ARB_texture_rectangle : enable
|
||
|
|
||
|
uniform sampler2DRect osgOcean_FullColourMap; // full resolution image
|
||
|
uniform sampler2DRect osgOcean_FullDepthMap; // full resolution depth map
|
||
|
uniform sampler2DRect osgOcean_BlurMap; // downsampled and filtered image
|
||
|
|
||
|
uniform vec2 osgOcean_ScreenRes;
|
||
|
uniform vec2 osgOcean_ScreenResInv;
|
||
|
uniform vec2 osgOcean_LowRes;
|
||
|
|
||
|
#define NUM_TAPS 4
|
||
|
|
||
|
// maximum CoC radius and diameter in pixels
|
||
|
const vec2 vMaxCoC = vec2(5.0,10);
|
||
|
|
||
|
// scale factor for maximum CoC size on low res. image
|
||
|
const float radiusScale = 0.4;
|
||
|
|
||
|
// contains poisson-distributed positions on the unit circle
|
||
|
vec2 poisson[8];
|
||
|
|
||
|
void main(void)
|
||
|
{
|
||
|
poisson[0] = vec2( 0.0, 0.0);
|
||
|
poisson[1] = vec2( 0.527837, -0.085868);
|
||
|
poisson[2] = vec2(-0.040088, 0.536087);
|
||
|
poisson[3] = vec2(-0.670445, -0.179949);
|
||
|
poisson[4] = vec2(-0.419418, -0.616039);
|
||
|
poisson[5] = vec2( 0.440453, -0.639399);
|
||
|
poisson[6] = vec2(-0.757088, 0.349334);
|
||
|
poisson[7] = vec2( 0.574619, 0.685879);
|
||
|
|
||
|
// pixel size (1/image resolution) of full resolution image
|
||
|
vec2 pixelSizeHigh = osgOcean_ScreenResInv;
|
||
|
|
||
|
// pixel size of low resolution image
|
||
|
vec2 pixelSizeLow = 4.0 * pixelSizeHigh;
|
||
|
|
||
|
vec4 color = texture2DRect( osgOcean_FullColourMap, gl_TexCoord[0].st ); // fetch center tap
|
||
|
// float centerDepth = color.a; // save its depth
|
||
|
float centerDepth = texture2DRect( osgOcean_FullDepthMap, gl_TexCoord[0].st ).r; // save its depth
|
||
|
|
||
|
// convert depth into blur radius in pixels
|
||
|
float discRadius = abs(centerDepth * vMaxCoC.y - vMaxCoC.x);
|
||
|
|
||
|
// compute disc radius on low-res image
|
||
|
float discRadiusLow = discRadius * radiusScale;
|
||
|
|
||
|
vec4 colorAccum = vec4(0.0);
|
||
|
float depthAccum = 0.0;
|
||
|
|
||
|
for(int t = 0; t < NUM_TAPS; t++)
|
||
|
{
|
||
|
vec2 coordHigh = gl_TexCoord[0].st + ( osgOcean_ScreenRes * (pixelSizeHigh * poisson[t] * discRadius ));
|
||
|
vec2 coordLow = gl_TexCoord[1].st + ( osgOcean_LowRes * (pixelSizeLow * poisson[t] * discRadiusLow ));
|
||
|
|
||
|
// fetch low-res tap
|
||
|
vec4 tapLow = texture2DRect( osgOcean_BlurMap, coordLow );
|
||
|
|
||
|
// fetch high-res tap
|
||
|
vec4 tapHigh = texture2DRect( osgOcean_FullColourMap, coordHigh );
|
||
|
|
||
|
float tapHighDepth = texture2DRect( osgOcean_FullDepthMap, coordHigh ).r;
|
||
|
|
||
|
// put tap blurriness into [0, 1] range
|
||
|
float tapBlur = abs(tapHighDepth * 2.0 - 1.0);
|
||
|
|
||
|
// mix low- and hi-res taps based on tap blurriness
|
||
|
vec4 tapColor = mix(tapHigh, tapLow, tapBlur);
|
||
|
|
||
|
// apply leaking reduction: lower weight for taps that are
|
||
|
// closer than the center tap and in focus
|
||
|
float tapDepth = (tapHighDepth >= centerDepth) ? 1.0 : abs(tapHighDepth * 2.0 - 1.0);
|
||
|
|
||
|
// accumulate
|
||
|
colorAccum += tapColor * tapDepth;
|
||
|
depthAccum += tapDepth;
|
||
|
}
|
||
|
|
||
|
// normalize and return result
|
||
|
gl_FragColor = colorAccum / depthAccum;
|
||
|
}
|
||
|
|