Updated Tofu Buzzard's improved DoF

Ansariel 2013-02-20 23:40:29 +01:00
parent 591957ce34
commit a80c18f036
2 changed files with 50 additions and 81 deletions

View File

@ -46,33 +46,35 @@ VARYING vec2 vary_fragcoord;
vec4 dofSample(sampler2DRect tex, vec2 tc)
{
tc.x = min(tc.x, dof_width);
tc.y = min(tc.y, dof_height);
tc.x = min(tc.x, dof_width);
tc.y = min(tc.y, dof_height);
return texture2DRect(tex, tc);
return texture2DRect(tex, tc);
}
void main()
{
vec2 tc = vary_fragcoord.xy;
vec4 dof = dofSample(diffuseRect, vary_fragcoord.xy*res_scale);
vec4 diff = texture2DRect(lightMap, vary_fragcoord.xy);
vec4 diff = texture2DRect(lightMap, tc.xy);
vec4 dof = dofSample(diffuseRect, tc.xy*res_scale);
dof.a = 0.0;
float a = min(abs(diff.a*2.0-1.0) * max_cof*res_scale*res_scale, 1.0);
float a = min(abs(diff.a*2.0-1.0) * max_cof*res_scale, 1.0);
// help out the transition from low-res dof buffer to full-rez full-focus buffer
if (a > 0.25 && a < 0.75)
{ //help out the transition a bit
{
float sc = a/res_scale;
vec4 col;
col = texture2DRect(lightMap, vary_fragcoord.xy+vec2(sc,sc));
col += texture2DRect(lightMap, vary_fragcoord.xy+vec2(-sc,sc));
col += texture2DRect(lightMap, vary_fragcoord.xy+vec2(sc,-sc));
col += texture2DRect(lightMap, vary_fragcoord.xy+vec2(-sc,-sc));
col = diff;
col.rgb += texture2DRect(lightMap, tc.xy+vec2(sc,sc)).rgb;
col.rgb += texture2DRect(lightMap, tc.xy+vec2(-sc,sc)).rgb;
col.rgb += texture2DRect(lightMap, tc.xy+vec2(sc,-sc)).rgb;
col.rgb += texture2DRect(lightMap, tc.xy+vec2(-sc,-sc)).rgb;
diff = mix(diff, col*0.25, a);
diff = mix(diff, col*0.2, a);
}
frag_color = mix(diff, dof, a);

View File

@ -40,86 +40,53 @@ uniform float res_scale;
VARYING vec2 vary_fragcoord;
void dofSample(inout vec4 diff, inout float w, float min_sc, vec2 tc)
float weightByColor(vec4 s)
{
vec4 s = texture2DRect(diffuseRect, tc);
float sc = abs(s.a*2.0-1.0)*max_cof;
if (sc > min_sc) //sampled pixel is more "out of focus" than current sample radius
{
float wg = 0.25;
// de-weight dull areas to make highlights 'pop'
wg += s.r+s.g+s.b;
diff += wg*s;
w += wg;
}
// de-weight dull areas to make highlights 'pop'
const float base_weight = 0.26; // how much all areas get *regardless* of their 'pop'
return base_weight + (s.r + s.g + s.b);
}
void dofSampleNear(inout vec4 diff, inout float w, float min_sc, vec2 tc)
void dofSample(inout vec4 diff, inout float w, vec2 tc)
{
vec4 s = texture2DRect(diffuseRect, tc);
float wg = 0.25;
// de-weight dull areas to make highlights 'pop'
wg += s.r+s.g+s.b;
diff += wg*s;
float sweight = weightByColor(s);
w += wg;
// modulate weight by how similarly-focused the origin and sample-point are
sweight *= 1.0 - abs(s.a - diff.a);
diff.rgb += sweight * s.rgb;
w += sweight;
}
void main()
{
vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy);
vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy);
{
float sc = (diff.a*2.0-1.0)*max_cof;
float w = 1.0;
const float PI = 3.14159265358979323846264;
float w = weightByColor(diff);
diff.rgb *= w;
// sample quite uniformly spaced points within a circle, for a circular 'bokeh'
if (sc > 0.5)
{
while (sc > 0.5)
{
int its = int(max(1.0,(sc*PI)));
for (int i=0; i<its; ++i)
{
float ang = sc+i*2*PI/its; // sc is added for rotary perturbance
float samp_x = sc*sin(ang);
float samp_y = sc*cos(ang);
// you could test sample coords against an interesting non-circular aperture shape here, if desired.
dofSampleNear(diff, w, sc, vary_fragcoord.xy + vec2(samp_x,samp_y));
}
sc -= 2.0;
}
}
else if (sc < -0.5)
{
sc = abs(sc);
while (sc > 0.5)
{
int its = int(max(1.0,(sc*PI)));
for (int i=0; i<its; ++i)
{
float ang = sc+i*2*PI/its; // sc is added for rotary perturbance
float samp_x = sc*sin(ang);
float samp_y = sc*cos(ang);
// you could test sample coords against an interesting non-circular aperture shape here, if desired.
dofSample(diff, w, sc, vary_fragcoord.xy + vec2(samp_x,samp_y));
}
sc -= 2.0;
}
}
diff /= w;
float sc = (diff.a*2.0-1.0)*max_cof;
const float PI = 3.14159265358979323846264;
// sample quite uniformly spaced points within a circle, for a circular 'bokeh'
sc = abs(sc);
while (sc > 0.5)
{
int its = int(max(1.0,(sc*PI)));
for (int i=0; i<its; ++i)
{
float ang = sc+i*2*PI/its; // sc is added for rotary perturbance
float samp_x = sc*sin(ang);
float samp_y = sc*cos(ang);
dofSample(diff, w, vary_fragcoord.xy + vec2(samp_x,samp_y));
}
frag_color = diff;
sc -= 2.0;
}
diff.rgb /= w;
frag_color = diff;
}