diff --git a/paint/shaders/bloom_downsample_pass.kong b/paint/shaders/bloom_downsample_pass.kong index 66a1622e..ee15d50c 100644 --- a/paint/shaders/bloom_downsample_pass.kong +++ b/paint/shaders/bloom_downsample_pass.kong @@ -32,15 +32,21 @@ fun bloom_downsample_pass_vert(input: vert_in): vert_out { return output; } +fun clamp_coord(coord: float2, texel_size: float2): float2 { + var lo: float2 = texel_size * 0.5; + var hi: float2 = float2(1.0, 1.0) - lo; + return float2(clamp(coord.x, lo.x, hi.x), clamp(coord.y, lo.y, hi.y)); +} + fun downsample_dual_filter(tex_coord: float2, texel_size: float2): float3 { var delta: float3 = float3(texel_size.xy, texel_size.x) * float3(0.5, 0.5, -0.5); var result: float3; - result = sample_lod(tex, sampler_linear, tex_coord, 0.0).rgb * 4.0; - result += sample_lod(tex, sampler_linear, tex_coord - delta.xy, 0.0).rgb; - result += sample_lod(tex, sampler_linear, tex_coord - delta.zy, 0.0).rgb; - result += sample_lod(tex, sampler_linear, tex_coord + delta.zy, 0.0).rgb; - result += sample_lod(tex, sampler_linear, tex_coord + delta.xy, 0.0).rgb; + result = sample_lod(tex, sampler_linear, clamp_coord(tex_coord, texel_size), 0.0).rgb * 4.0; + result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord - delta.xy, texel_size), 0.0).rgb; + result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord - delta.zy, texel_size), 0.0).rgb; + result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord + delta.zy, texel_size), 0.0).rgb; + result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord + delta.xy, texel_size), 0.0).rgb; return result * (1.0 / 8.0); } diff --git a/paint/shaders/bloom_upsample_pass.kong b/paint/shaders/bloom_upsample_pass.kong index 5aeea559..fec74c90 100644 --- a/paint/shaders/bloom_upsample_pass.kong +++ b/paint/shaders/bloom_upsample_pass.kong @@ -30,18 +30,24 @@ fun bloom_upsample_pass_vert(input: vert_in): vert_out { return output; } +fun clamp_coord(coord: float2, texel_size: float2): float2 { + var lo: float2 = texel_size * 1.5; + var hi: float2 = float2(1.0, 1.0) - lo; + return float2(clamp(coord.x, lo.x, hi.x), clamp(coord.y, lo.y, hi.y)); +} + fun upsample_dual_filter(tex_coord: float2, texel_size: float2): float3 { var delta: float2 = texel_size * constants.sample_scale; var result: float3; - result = sample_lod(tex, sampler_linear, tex_coord + float2(-delta.x * 2.0, 0.0), 0.0).rgb; - result += sample_lod(tex, sampler_linear, tex_coord + float2(-delta.x, delta.y), 0.0).rgb * 2.0; - result += sample_lod(tex, sampler_linear, tex_coord + float2(0.0, delta.y * 2.0), 0.0).rgb; - result += sample_lod(tex, sampler_linear, tex_coord + delta, 0.0).rgb * 2.0; - result += sample_lod(tex, sampler_linear, tex_coord + float2(delta.x * 2.0, 0.0), 0.0).rgb; - result += sample_lod(tex, sampler_linear, tex_coord + float2(delta.x, -delta.y), 0.0).rgb * 2.0; - result += sample_lod(tex, sampler_linear, tex_coord + float2(0.0, -delta.y * 2.0), 0.0).rgb; - result += sample_lod(tex, sampler_linear, tex_coord - delta, 0.0).rgb * 2.0; + result = sample_lod(tex, sampler_linear, clamp_coord(tex_coord + float2(-delta.x * 2.0, 0.0), texel_size), 0.0).rgb; + result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord + float2(-delta.x, delta.y), texel_size), 0.0).rgb * 2.0; + result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord + float2(0.0, delta.y * 2.0), texel_size), 0.0).rgb; + result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord + delta, texel_size), 0.0).rgb * 2.0; + result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord + float2(delta.x * 2.0, 0.0), texel_size), 0.0).rgb; + result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord + float2(delta.x, -delta.y), texel_size), 0.0).rgb * 2.0; + result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord + float2(0.0, -delta.y * 2.0), texel_size), 0.0).rgb; + result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord - delta, texel_size), 0.0).rgb * 2.0; return result * (1.0 / 12.0); } diff --git a/paint/sources/config.c b/paint/sources/config.c index 0161652d..e45612b4 100644 --- a/paint/sources/config.c +++ b/paint/sources/config.c @@ -72,7 +72,7 @@ void config_save() { json_encode_f32("window_scale", g_config->window_scale); json_encode_f32("rp_supersample", g_config->rp_supersample); json_encode_bool("rp_ssao", g_config->rp_ssao); - json_encode_bool("rp_bloom", g_config->rp_bloom); + json_encode_f32("rp_bloom", g_config->rp_bloom); json_encode_f32("rp_vignette", g_config->rp_vignette); json_encode_f32("rp_grain", g_config->rp_grain); json_encode_string("lut_path", g_config->lut_path); @@ -178,7 +178,7 @@ void config_init() { #endif g_config->window_vsync = true; g_config->window_frequency = sys_display_frequency(); - g_config->rp_bloom = false; + g_config->rp_bloom = 0.0; g_config->rp_vignette = 0.2; g_config->rp_grain = 0.09; g_config->lut_path = ""; diff --git a/paint/sources/render/render_path_base.c b/paint/sources/render/render_path_base.c index 31e48fde..0284b698 100644 --- a/paint/sources/render/render_path_base.c +++ b/paint/sources/render/render_path_base.c @@ -185,7 +185,7 @@ void render_path_base_commands(void (*draw_commands)(void)) { } void render_path_base_draw_bloom(char *source, char *target) { - if (g_config->rp_bloom == false) { + if (g_config->rp_bloom == 0.0) { return; } diff --git a/paint/sources/types.h b/paint/sources/types.h index 2bda9434..61340804 100644 --- a/paint/sources/types.h +++ b/paint/sources/types.h @@ -93,7 +93,7 @@ typedef struct config { // Render path f32 rp_supersample; bool rp_ssao; - bool rp_bloom; + f32 rp_bloom; f32 rp_vignette; f32 rp_grain; char *lut_path; // .cube diff --git a/paint/sources/ui/box_preferences.c b/paint/sources/ui/box_preferences.c index 9800c05e..fcdb8094 100644 --- a/paint/sources/ui/box_preferences.c +++ b/paint/sources/ui/box_preferences.c @@ -663,10 +663,10 @@ void box_preferences_viewport_tab() { } ui_handle_t *h_bloom = ui_handle(__ID__); - h_bloom->b = g_config->rp_bloom; - g_config->rp_bloom = ui_check(h_bloom, tr("Bloom"), ""); + h_bloom->f = g_config->rp_bloom; + g_config->rp_bloom = ui_slider(h_bloom, tr("Bloom"), 0.0, 1.0, true, 100.0, true, UI_ALIGN_RIGHT, true); if (h_bloom->changed) { - config_apply(); + g_context->ddirty = 2; } } diff --git a/paint/sources/uniforms.c b/paint/sources/uniforms.c index 080142ab..1fdf0e03 100644 --- a/paint/sources/uniforms.c +++ b/paint/sources/uniforms.c @@ -53,7 +53,8 @@ f32 uniforms_ext_f32_link(object_t *object, material_data_t *mat, char *link) { return render_path_base_bloom_sample_scale; } else if (string_equals(link, "_bloom_strength")) { - return g_context->viewport_mode == VIEWPORT_MODE_PATH_TRACE ? 0.2 : 0.02; + f32 base = g_context->viewport_mode == VIEWPORT_MODE_PATH_TRACE ? 0.2 : 0.02; + return base * g_config->rp_bloom; } else if (string_equals(link, "_brush_scale_x")) { return 1 / (float)g_context->brush_scale_x;