DYTSrouce/resources/shaders/osgOcean_dof_combiner.frag

84 lines
2.9 KiB
GLSL
Raw Normal View History

2025-01-04 04:12:51 +00:00
#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;
}