Updated Tofu Buzzard's improved DoF
parent
591957ce34
commit
a80c18f036
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue