0
\$\begingroup\$

I am implementing depth of field. My fragment shader has the following code in it:

#version 430

uniform sampler2D depth_tex; // texture uniform
uniform sampler2D colour_tex; // texture uniform


uniform int img_width;
uniform int img_height;
uniform float model_distance;
uniform float near;
uniform float far;

uniform int cam_factor; 


vec2 img_size = vec2(img_width, img_height);

in vec2 ftexcoord;

layout(location = 0) out vec4 frag_colour;

float to_distance(float depth_colour)
{
    float dist = (2.0*near*far) / (far + near - depth_colour*(far - near)); 
    return dist;
}

float to_depth(float dist)
{
    float depth = (far*(dist - 2.0*near) + near*dist)/(dist*(far - near));
    return depth;
}

vec4 get_blurred_pixel(vec2 tc)
{   
    float depth_colour = texture(depth_tex, tc).r;

    float distance_to_pixel = to_distance(depth_colour);

    float x = clamp(distance_to_pixel, 0.0, 2*model_distance) / (2*model_distance);

    // tent function
    if(x > 0.5)
         x = 1.0 - x;

    x = 1.0 - pow(x, 1.0/10.0);

   const float pi_times_2 = 6.28318530718; // Pi*2
    
    float directions = 16.0; // BLUR directions (Default 16.0 - More is better but slower)
    float quality = 10.0; // BLUR quality (Default 4.0 - More is better but slower)
    float size = 8.0; // BLUR size (radius)
        vec2 radius = vec2(size/img_size.x * cam_factor, size/img_size.y * cam_factor);

   vec4 blurred_colour = texture(colour_tex, tc);
    
    for( float d=0.0; d<pi_times_2; d+= pi_times_2/directions)
        for(float i=1.0/quality; i<=1.0; i+=1.0/quality)
            blurred_colour += texture( colour_tex, tc + vec2(cos(d),sin(d))*radius*x*i);    
    
    // Output to screen
    blurred_colour /= quality * directions - 15.0;

    return blurred_colour;
}

// https://www.shadertoy.com/view/Xltfzj
// https://www.blitzcoder.org/forum/topic.php?id=124
void main()
{
    frag_colour.rgb = get_blurred_pixel(ftexcoord).rgb;
    frag_colour.a = 1.0;    
}

The lines where I use x as a blur factor are:

float x = clamp(distance_to_pixel, 0.0, 2*model_distance) / (2*model_distance);

// tent function
if(x > 0.5)
     x = 1.0 - x;

x = 1.0 - pow(x, 1.0/10.0);

This code works for far distances, but not for close distances. I cannot figure out why it does not work for close distances. Please let me know if you need more code. Thanks for your time.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Can you describe or show the specific way in which this "does not work for short distances"? Often the specific symptoms can help diagnose the cause. \$\endgroup\$
    – DMGregory
    Commented Nov 15, 2022 at 0:55
  • 2
    \$\begingroup\$ Also, a couple of screenshots would greatly help understand the visual issue you're encountering. \$\endgroup\$
    – liggiorgio
    Commented Nov 15, 2022 at 19:11

1 Answer 1

1
\$\begingroup\$

Thanks for the guidance.

I found a solution. The solution was to scale and translate the variable before calling pow().

float x = clamp(distance_to_pixel, 0.0, 2*model_distance) / (2*model_distance);

// tent function
if(x > 0.5)
    x = 1.0 - x; // from 0 to 0.5

x *= 2.0; // from 0 to 1
x *= 2.0; // from 0 to 2
x -= 1.0; // from -1 to 1

x = abs(x);
x = pow(x, 10.0);

Here is an image showing the blurred foreground and background, and the focus on the lady character:

enter image description here

enter image description here

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .