Skip to content

Commit

Permalink
[depth of field] fixed an oultine bug
Browse files Browse the repository at this point in the history
  • Loading branch information
PanosK92 committed Sep 18, 2024
1 parent c1cabaa commit 1902e59
Showing 1 changed file with 23 additions and 29 deletions.
52 changes: 23 additions & 29 deletions data/shaders/depth_of_field.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//====================

// constants
static const float BLUR_RADIUS = 10.0f; // maximum radius of the blur
static const float BASE_FOCAL_LENGTH = 50.0; // in mm, base focal length
static const float SENSOR_HEIGHT = 24.0; // in mm, assuming full-frame sensor
static const float EDGE_DETECTION_THRESHOLD = 0.1f; // adjust to control edge sensitivity
static const float BLUR_RADIUS = 10.0f; // maximum radius of the blur
static const float BASE_FOCAL_LENGTH = 50.0; // in mm, base focal length
static const float SENSOR_HEIGHT = 24.0; // in mm, assuming full-frame sensor
static const float EDGE_DETECTION_THRESHOLD = 0.001f; // adjust to control edge sensitivity
static const uint AVERAGE_DEPTH_SAMPLE_COUNT = 10;
static const float AVERAGE_DEPTH_RADIUS = 0.1f;
static const float AVERAGE_DEPTH_RADIUS = 0.5f;

float compute_coc(float2 uv, float focus_distance, float aperture)
float compute_coc(float2 uv, float2 texel_size, float2 resolution, float focus_distance, float aperture)
{
float2 resolution_out;
tex_uav.GetDimensions(resolution_out.x, resolution_out.y);
float2 texel_size = 1.0 / resolution_out;
float depth = get_linear_depth(uv);
float depth = get_linear_depth(uv);

// edge detection
float depth_diff = 0;
for (int i = -1; i <= 1; i++)
{
for (int j = -1; j <= 1; j++)
{
if (i == 0 && j == 0)
continue;

float2 offset = float2(i, j) * texel_size;
float neighbor_depth = get_linear_depth(uv + offset);
depth_diff += abs(depth - neighbor_depth);
Expand All @@ -65,7 +59,7 @@ float compute_coc(float2 uv, float focus_distance, float aperture)
float coc_diameter = abs(aperture * (s2 - s1) * f) / (s2 * (s1 - f));

// convert the diameter to pixels
float coc_pixels = coc_diameter * (resolution_out.y / SENSOR_HEIGHT);
float coc_pixels = coc_diameter * (resolution.y / SENSOR_HEIGHT);

// adjust coc based on focus distance to enhance the effect
float distance_factor = saturate(focus_distance / 50.0);
Expand All @@ -82,14 +76,13 @@ float gaussian_weight(float x, float sigma)
return exp(-0.5 * (x * x) / (sigma * sigma)) / (sigma * sqrt(2.0 * 3.14159265));
}

float3 gaussian_blur(float2 uv, float coc, float2 resolution_out)
float3 gaussian_blur(float2 uv, float coc, float2 texel_size)
{
float2 texel_size = 1.0f / resolution_out;
float sigma = max(1.0, coc * BLUR_RADIUS);
int samples = clamp(int(sigma * 0.5), 1, BLUR_RADIUS); // adaptive sampling
float sigma = max(1.0, coc * BLUR_RADIUS);
int samples = clamp(int(sigma * 0.5), 1, BLUR_RADIUS); // adaptive sampling

float3 color = 0.0f;
float total_weight = 0.0;
float3 color = 0.0f;
float total_weight = FLT_MIN;
for (int i = -samples; i <= samples; i++)
{
for (int j = -samples; j <= samples; j++)
Expand All @@ -100,13 +93,13 @@ float3 gaussian_blur(float2 uv, float coc, float2 resolution_out)
if (distance <= sigma)
{
float weight = gaussian_weight(distance, sigma);
color += tex.Sample(samplers[sampler_bilinear_clamp], uv + offset).rgb * weight;
color += tex.SampleLevel(samplers[sampler_bilinear_clamp], uv + offset, 0.0f).rgb * weight;
total_weight += weight;
}
}
}

return color / (total_weight + FLT_MIN);
return color / total_weight;
}

float get_average_depth_circle(float2 center, float2 resolution_out)
Expand All @@ -129,17 +122,18 @@ float get_average_depth_circle(float2 center, float2 resolution_out)
[numthreads(THREAD_GROUP_COUNT_X, THREAD_GROUP_COUNT_Y, 1)]
void main_cs(uint3 thread_id : SV_DispatchThreadID)
{
float2 resolution_out;
tex_uav.GetDimensions(resolution_out.x, resolution_out.y);
const float2 uv = (thread_id.xy + 0.5f) / resolution_out;

float2 resolution;
tex_uav.GetDimensions(resolution.x, resolution.y);
const float2 uv = (thread_id.xy + 0.5f) / resolution;
const float2 texel_size = 1.0 / resolution;

// get focal depth from camera
float focal_depth = get_average_depth_circle(float2(0.5, 0.5f), resolution_out);
float focal_depth = get_average_depth_circle(float2(0.5, 0.5f), resolution);
float aperture = pass_get_f3_value().x;

// do the actual blurring
float coc = compute_coc(uv, focal_depth, aperture);
float3 blurred_color = gaussian_blur(uv, coc, resolution_out);
float coc = compute_coc(uv, texel_size, resolution, focal_depth, aperture);
float3 blurred_color = gaussian_blur(uv, coc, texel_size);
float4 original_color = tex[thread_id.xy];
float3 final_color = lerp(original_color.rgb, blurred_color, coc);

Expand Down

0 comments on commit 1902e59

Please sign in to comment.