paint: improve blur tool
This commit is contained in:
@@ -34,10 +34,6 @@ fun get_blur_tool_weight(i: int): float { \
|
||||
";
|
||||
|
||||
void make_blur_run(node_shader_t *kong) {
|
||||
// node_shader_write_frag(kong, "var tex_coord_inp: float2 = gbuffer2[uint2(sp.x * constants.gbuffer_size.x, sp.y * constants.gbuffer_size.y)].ba;");
|
||||
node_shader_write_frag(kong, "var tex_coord_inp4: float4 = gbuffer2[uint2(uint(sp.x * constants.gbuffer_size.x), uint(sp.y * constants.gbuffer_size.y))];");
|
||||
node_shader_write_frag(kong, "var tex_coord_inp: float2 = tex_coord_inp4.ba;");
|
||||
|
||||
node_shader_write_frag(kong, "var basecol: float3 = float3(0.0, 0.0, 0.0);");
|
||||
node_shader_write_frag(kong, "var roughness: float = 0.0;");
|
||||
node_shader_write_frag(kong, "var metallic: float = 0.0;");
|
||||
@@ -59,67 +55,65 @@ void make_blur_run(node_shader_t *kong) {
|
||||
node_shader_write_frag(kong, "var subs: float = 0.0;");
|
||||
}
|
||||
|
||||
node_shader_add_constant(kong, "texpaint_size: float2", "_texpaint_size");
|
||||
node_shader_write_frag(kong, "var blur_step: float = 1.0 / constants.texpaint_size.x;");
|
||||
if (g_context->blur_type == BLUR_TYPE_SMUDGE) {
|
||||
// node_shader_write_frag(kong, "const blur_weight: float[7] = {1.0 / 28.0, 2.0 / 28.0, 3.0 / 28.0, 4.0 / 28.0, 5.0 / 28.0, 6.0 / 28.0, 7.0 / 28.0};");
|
||||
node_shader_add_function(kong, str_get_smudge_tool_weight);
|
||||
node_shader_add_constant(kong, "brush_direction: float3", "_brush_direction");
|
||||
node_shader_write_frag(kong, "var blur_direction: float2 = constants.brush_direction.yx;");
|
||||
node_shader_write_frag(kong, "var smudge_delta: float2 = constants.inp.xy - constants.inplast.xy;");
|
||||
node_shader_write_frag(kong, "for (var i: int = 0; i < 7; i += 1) {");
|
||||
// node_shader_write_frag(kong, "var tex_coord_inp2: float2 = gbuffer2[uint2((sp.x + blur_direction.x * blur_step * float(i)) *
|
||||
// constants.gbuffer_size.x, (sp.y + blur_direction.y * blur_step * float(i)) * constants.gbuffer_size.y)].ba;");
|
||||
node_shader_write_frag(kong, "var tex_coord_inp24: float4 = gbuffer2[uint2(uint((sp.x + blur_direction.x * blur_step * float(i)) * "
|
||||
"constants.gbuffer_size.x), uint((sp.y + blur_direction.y * blur_step * float(i)) * constants.gbuffer_size.y))];");
|
||||
node_shader_write_frag(kong, "var smudge_sp: float2 = sp.xy - smudge_delta * ((float(i) + 1.0) / 7.0);");
|
||||
node_shader_write_frag(kong, "smudge_sp = float2(clamp(smudge_sp.x, 0.0, 0.9999), clamp(smudge_sp.y, 0.0, 0.9999));");
|
||||
node_shader_write_frag(kong, "var tex_coord_inp24: float4 = gbuffer2[uint2(uint(smudge_sp.x * constants.gbuffer_size.x), uint(smudge_sp.y * "
|
||||
"constants.gbuffer_size.y))];");
|
||||
node_shader_write_frag(kong, "var tex_coord_inp2: float2 = tex_coord_inp24.ba;");
|
||||
node_shader_write_frag(kong, "var texpaint_sample: float4 = sample(texpaint_undo, sampler_linear, tex_coord_inp2);");
|
||||
node_shader_write_frag(kong, "var texpaint_sample: float4 = sample(texpaint_ref, sampler_linear, tex_coord_inp2);");
|
||||
node_shader_write_frag(kong, "var blur_weight_i: float = get_smudge_tool_weight(i);");
|
||||
node_shader_write_frag(kong, "opacity += texpaint_sample.a * blur_weight_i;");
|
||||
node_shader_write_frag(kong, "basecol += texpaint_sample.rgb * texpaint_sample.a * blur_weight_i;");
|
||||
node_shader_write_frag(kong, "var texpaint_pack_sample: float4 = sample(texpaint_pack_undo, sampler_linear, tex_coord_inp2) * blur_weight_i;");
|
||||
node_shader_write_frag(kong, "var texpaint_pack_sample: float4 = sample(texpaint_pack_ref, sampler_linear, tex_coord_inp2) * blur_weight_i;");
|
||||
node_shader_write_frag(kong, "roughness += texpaint_pack_sample.g;");
|
||||
node_shader_write_frag(kong, "metallic += texpaint_pack_sample.b;");
|
||||
node_shader_write_frag(kong, "occlusion += texpaint_pack_sample.r;");
|
||||
node_shader_write_frag(kong, "height += texpaint_pack_sample.a;");
|
||||
node_shader_write_frag(kong, "nortan += sample(texpaint_nor_undo, sampler_linear, tex_coord_inp2).rgb * blur_weight_i;");
|
||||
node_shader_write_frag(kong, "nortan += sample(texpaint_nor_ref, sampler_linear, tex_coord_inp2).rgb * blur_weight_i;");
|
||||
node_shader_write_frag(kong, "}");
|
||||
}
|
||||
else {
|
||||
// node_shader_write_frag(kong, "const blur_weight: float[15] = {0.034619 / 2.0, 0.044859 / 2.0, 0.055857 / 2.0, 0.066833 / 2.0, 0.076841 / 2.0,
|
||||
// 0.084894 / 2.0, 0.090126 / 2.0, 0.09194 / 2.0, 0.090126 / 2.0, 0.084894 / 2.0, 0.076841 / 2.0, 0.066833 / 2.0, 0.055857 / 2.0, 0.044859 / 2.0,
|
||||
// 0.034619 / 2.0};");
|
||||
node_shader_write_frag(kong,
|
||||
"var tex_coord_inp4: float4 = gbuffer2[uint2(uint(sp.x * constants.gbuffer_size.x), uint(sp.y * constants.gbuffer_size.y))];");
|
||||
node_shader_write_frag(kong, "var tex_coord_inp: float2 = tex_coord_inp4.ba;");
|
||||
node_shader_add_constant(kong, "texpaint_size: float2", "_texpaint_size");
|
||||
node_shader_write_frag(kong, "var blur_step: float = 1.0 / constants.texpaint_size.x;");
|
||||
node_shader_add_function(kong, str_get_blur_tool_weight);
|
||||
// X
|
||||
node_shader_write_frag(kong, "for (var i: int = 0; i <= 14; i += 1) {");
|
||||
node_shader_write_frag(kong,
|
||||
"var texpaint_sample: float4 = sample(texpaint_undo, sampler_linear, tex_coord_inp + float2(blur_step * float(i - 7), 0.0));");
|
||||
"var texpaint_sample: float4 = sample(texpaint_ref, sampler_linear, tex_coord_inp + float2(blur_step * float(i - 7), 0.0));");
|
||||
node_shader_write_frag(kong, "var blur_weight_i: float = get_blur_tool_weight(i);");
|
||||
node_shader_write_frag(kong, "opacity += texpaint_sample.a * blur_weight_i;");
|
||||
node_shader_write_frag(kong, "basecol += texpaint_sample.rgb * texpaint_sample.a * blur_weight_i;");
|
||||
node_shader_write_frag(kong, "var texpaint_pack_sample: float4 = sample(texpaint_pack_undo, sampler_linear, tex_coord_inp + float2(blur_step * float(i "
|
||||
node_shader_write_frag(kong, "var texpaint_pack_sample: float4 = sample(texpaint_pack_ref, sampler_linear, tex_coord_inp + float2(blur_step * float(i "
|
||||
"- 7), 0.0)) * blur_weight_i;");
|
||||
node_shader_write_frag(kong, "roughness += texpaint_pack_sample.g;");
|
||||
node_shader_write_frag(kong, "metallic += texpaint_pack_sample.b;");
|
||||
node_shader_write_frag(kong, "occlusion += texpaint_pack_sample.r;");
|
||||
node_shader_write_frag(kong, "height += texpaint_pack_sample.a;");
|
||||
node_shader_write_frag(
|
||||
kong, "nortan += sample(texpaint_nor_undo, sampler_linear, tex_coord_inp + float2(blur_step * float(i - 7), 0.0)).rgb * blur_weight_i;");
|
||||
kong, "nortan += sample(texpaint_nor_ref, sampler_linear, tex_coord_inp + float2(blur_step * float(i - 7), 0.0)).rgb * blur_weight_i;");
|
||||
node_shader_write_frag(kong, "}");
|
||||
// Y
|
||||
node_shader_write_frag(kong, "for (var j: int = 0; j <= 14; j += 1) {");
|
||||
node_shader_write_frag(kong,
|
||||
"var texpaint_sample: float4 = sample(texpaint_undo, sampler_linear, tex_coord_inp + float2(0.0, blur_step * float(j - 7)));");
|
||||
"var texpaint_sample: float4 = sample(texpaint_ref, sampler_linear, tex_coord_inp + float2(0.0, blur_step * float(j - 7)));");
|
||||
node_shader_write_frag(kong, "var blur_weight_j: float = get_blur_tool_weight(j);");
|
||||
node_shader_write_frag(kong, "opacity += texpaint_sample.a * blur_weight_j;");
|
||||
node_shader_write_frag(kong, "basecol += texpaint_sample.rgb * texpaint_sample.a * blur_weight_j;");
|
||||
node_shader_write_frag(kong, "var texpaint_pack_sample: float4 = sample(texpaint_pack_undo, sampler_linear, tex_coord_inp + float2(0.0, blur_step * "
|
||||
node_shader_write_frag(kong, "var texpaint_pack_sample: float4 = sample(texpaint_pack_ref, sampler_linear, tex_coord_inp + float2(0.0, blur_step * "
|
||||
"float(j - 7))) * blur_weight_j;");
|
||||
node_shader_write_frag(kong, "roughness += texpaint_pack_sample.g;");
|
||||
node_shader_write_frag(kong, "metallic += texpaint_pack_sample.b;");
|
||||
node_shader_write_frag(kong, "occlusion += texpaint_pack_sample.r;");
|
||||
node_shader_write_frag(kong, "height += texpaint_pack_sample.a;");
|
||||
node_shader_write_frag(
|
||||
kong, "nortan += sample(texpaint_nor_undo, sampler_linear, tex_coord_inp + float2(0.0, blur_step * float(j - 7))).rgb * blur_weight_j;");
|
||||
kong, "nortan += sample(texpaint_nor_ref, sampler_linear, tex_coord_inp + float2(0.0, blur_step * float(j - 7))).rgb * blur_weight_j;");
|
||||
node_shader_write_frag(kong, "}");
|
||||
}
|
||||
node_shader_write_frag(kong, "var blur_src_alpha: float = opacity;");
|
||||
|
||||
@@ -195,6 +195,14 @@ node_shader_context_t *make_paint_run_context(material_t *data, material_context
|
||||
bool uv_island_fill = g_context->tool == TOOL_TYPE_FILL && g_context->fill_type == FILL_TYPE_UV_ISLAND;
|
||||
bool decal = context_is_decal();
|
||||
|
||||
bool accum = g_context->tool == TOOL_TYPE_BLUR;
|
||||
char *tex_src = accum ? "texpaint_ref" : "texpaint_undo";
|
||||
char *tex_nor_src = accum ? "texpaint_nor_ref" : "texpaint_nor_undo";
|
||||
char *tex_pack_src = accum ? "texpaint_pack_ref" : "texpaint_pack_undo";
|
||||
char *tex_src_link = accum ? "_texpaint_ref" : "_texpaint_undo";
|
||||
char *tex_nor_link = accum ? "_texpaint_nor_ref" : "_texpaint_nor_undo";
|
||||
char *tex_pack_link = accum ? "_texpaint_pack_ref" : "_texpaint_pack_undo";
|
||||
|
||||
char *tuv = g_context->layer->uv_map == 1 ? "input.tex1" : "input.tex";
|
||||
if (is_atlas) {
|
||||
node_shader_add_constant(kong, "atlas_transform: float3", "_atlas_transform");
|
||||
@@ -316,9 +324,9 @@ node_shader_context_t *make_paint_run_context(material_t *data, material_context
|
||||
if (g_context->tool == TOOL_TYPE_CLONE || g_context->tool == TOOL_TYPE_BLUR) {
|
||||
node_shader_add_texture(kong, "gbuffer2", NULL);
|
||||
node_shader_add_constant(kong, "gbuffer_size: float2", "_gbuffer_size");
|
||||
node_shader_add_texture(kong, "texpaint_undo", "_texpaint_undo");
|
||||
node_shader_add_texture(kong, "texpaint_nor_undo", "_texpaint_nor_undo");
|
||||
node_shader_add_texture(kong, "texpaint_pack_undo", "_texpaint_pack_undo");
|
||||
node_shader_add_texture(kong, tex_src, tex_src_link);
|
||||
node_shader_add_texture(kong, tex_nor_src, tex_nor_link);
|
||||
node_shader_add_texture(kong, tex_pack_src, tex_pack_link);
|
||||
|
||||
if (g_context->tool == TOOL_TYPE_CLONE) {
|
||||
make_clone_run(kong);
|
||||
@@ -495,11 +503,16 @@ node_shader_context_t *make_paint_run_context(material_t *data, material_context
|
||||
node_shader_write_frag(kong, "sample_tc.y = 1.0 - sample_tc.y;");
|
||||
node_shader_add_texture(kong, "paintmask", NULL);
|
||||
node_shader_write_frag(kong, "var sample_mask: float = sample_lod(paintmask, sampler_linear, sample_tc, 0.0).r;");
|
||||
node_shader_write_frag(kong, "var base_str: float = max(str, sample_mask);");
|
||||
node_shader_write_frag(kong, "str = base_str + str * (1.0 - base_str) * 0.1;");
|
||||
if (accum) {
|
||||
node_shader_write_frag(kong, "str *= 0.5;");
|
||||
}
|
||||
else {
|
||||
node_shader_write_frag(kong, "var base_str: float = max(str, sample_mask);");
|
||||
node_shader_write_frag(kong, "str = base_str + str * (1.0 - base_str) * 0.1;");
|
||||
}
|
||||
|
||||
node_shader_add_texture(kong, "texpaint_undo", "_texpaint_undo");
|
||||
node_shader_write_frag(kong, "var sample_undo: float4 = sample_lod(texpaint_undo, sampler_linear, sample_tc, 0.0);");
|
||||
node_shader_add_texture(kong, tex_src, tex_src_link);
|
||||
node_shader_write_frag(kong, string_tmp("var sample_undo: float4 = sample_lod(%s, sampler_linear, sample_tc, 0.0);", tex_src));
|
||||
|
||||
f32 matid = g_context->material->id / 255.0;
|
||||
if (g_context->picker_paint_mask) {
|
||||
@@ -532,10 +545,10 @@ node_shader_context_t *make_paint_run_context(material_t *data, material_context
|
||||
}
|
||||
|
||||
// Output
|
||||
node_shader_add_texture(kong, "texpaint_nor_undo", "_texpaint_nor_undo");
|
||||
node_shader_add_texture(kong, "texpaint_pack_undo", "_texpaint_pack_undo");
|
||||
node_shader_write_frag(kong, "var sample_nor_undo: float4 = sample_lod(texpaint_nor_undo, sampler_linear, sample_tc, 0.0);");
|
||||
node_shader_write_frag(kong, "var sample_pack_undo: float4 = sample_lod(texpaint_pack_undo, sampler_linear, sample_tc, 0.0);");
|
||||
node_shader_add_texture(kong, tex_nor_src, tex_nor_link);
|
||||
node_shader_add_texture(kong, tex_pack_src, tex_pack_link);
|
||||
node_shader_write_frag(kong, string_tmp("var sample_nor_undo: float4 = sample_lod(%s, sampler_linear, sample_tc, 0.0);", tex_nor_src));
|
||||
node_shader_write_frag(kong, string_tmp("var sample_pack_undo: float4 = sample_lod(%s, sampler_linear, sample_tc, 0.0);", tex_pack_src));
|
||||
|
||||
bool is_mask = slot_layer_is_mask(g_context->layer);
|
||||
if (g_context->tool == TOOL_TYPE_ERASER && !is_mask) {
|
||||
|
||||
@@ -169,6 +169,49 @@ void render_path_paint_commands_particle(i32 tid, char *texpaint, bool is_mask)
|
||||
}
|
||||
}
|
||||
|
||||
static void render_path_paint_ref_target(char *name, char *format) {
|
||||
render_target_t *rt = any_map_get(render_path_render_targets, name);
|
||||
if (rt != NULL && (rt->width != config_get_texture_res_x() || rt->height != config_get_texture_res_y() || !string_equals(rt->format, format))) {
|
||||
gpu_delete_texture(rt->_image);
|
||||
map_delete(render_path_render_targets, name);
|
||||
rt = NULL;
|
||||
}
|
||||
if (rt == NULL) {
|
||||
render_target_t *t = render_target_create();
|
||||
t->name = name;
|
||||
t->width = config_get_texture_res_x();
|
||||
t->height = config_get_texture_res_y();
|
||||
t->format = format;
|
||||
render_path_create_render_target(t);
|
||||
}
|
||||
}
|
||||
|
||||
static void render_path_paint_ref_snapshot(i32 tid, bool is_mask) {
|
||||
if (is_mask) {
|
||||
render_path_paint_ref_target("texpaint_ref", "RGBA32");
|
||||
render_path_set_target("texpaint_ref", NULL, NULL, GPU_CLEAR_NONE, 0, 0.0);
|
||||
render_path_bind_target(string_tmp("texpaint%d", tid), "tex");
|
||||
render_path_draw_shader("Scene/copy_pass/copy_pass");
|
||||
return;
|
||||
}
|
||||
char *format = base_bits_handle->i == TEXTURE_BITS_BITS8 ? "RGBA32" : base_bits_handle->i == TEXTURE_BITS_BITS16 ? "RGBA64" : "RGBA128";
|
||||
render_path_paint_ref_target("texpaint_ref", format);
|
||||
render_path_paint_ref_target("texpaint_nor_ref", format);
|
||||
render_path_paint_ref_target("texpaint_pack_ref", format);
|
||||
string_array_t *additional = any_array_create_from_raw_tmp(
|
||||
(void *[]){
|
||||
"texpaint_nor_ref",
|
||||
"texpaint_pack_ref",
|
||||
},
|
||||
2);
|
||||
render_path_set_target("texpaint_ref", additional, NULL, GPU_CLEAR_NONE, 0, 0.0);
|
||||
render_path_bind_target(string_tmp("texpaint%d", tid), "tex0");
|
||||
render_path_bind_target(string_tmp("texpaint_nor%d", tid), "tex1");
|
||||
render_path_bind_target(string_tmp("texpaint_pack%d", tid), "tex2");
|
||||
char *pipe = string_equals(format, "RGBA32") ? "copy_mrt3_pass" : string_equals(format, "RGBA64") ? "copy_mrt3RGBA64_pass" : "copy_mrt3RGBA128_pass";
|
||||
render_path_draw_shader(string_tmp("Scene/copy_mrt3_pass/%s", pipe));
|
||||
}
|
||||
|
||||
void render_path_paint_commands_paint(bool dilation) {
|
||||
i32 tid = g_context->layer->id;
|
||||
|
||||
@@ -418,6 +461,10 @@ void render_path_paint_commands_paint(bool dilation) {
|
||||
bool read_tc = (g_context->tool == TOOL_TYPE_FILL && g_context->fill_type == FILL_TYPE_FACE) || g_context->tool == TOOL_TYPE_CLONE ||
|
||||
g_context->tool == TOOL_TYPE_BLUR;
|
||||
|
||||
if (g_context->tool == TOOL_TYPE_BLUR) {
|
||||
render_path_paint_ref_snapshot(tid, is_mask);
|
||||
}
|
||||
|
||||
if (g_context->tool == TOOL_TYPE_PARTICLE) {
|
||||
render_path_paint_commands_particle(tid, texpaint, is_mask);
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ void uniforms_ext_cache_uv_map(void *_) {
|
||||
util_uv_cache_uv_map();
|
||||
}
|
||||
|
||||
static gpu_texture_t *_uniforms_ext_undo_target(char *name) {
|
||||
static gpu_texture_t *_uniforms_ext_get_target(char *name) {
|
||||
render_target_t *rt = any_map_get(render_path_render_targets, name);
|
||||
if (rt == NULL) {
|
||||
rt = any_map_get(render_path_render_targets, "empty_black");
|
||||
@@ -376,18 +376,27 @@ static gpu_texture_t *_uniforms_ext_undo_target(char *name) {
|
||||
gpu_texture_t *uniforms_ext_tex_link(object_t *object, material_data_t *mat, char *link) {
|
||||
if (string_equals(link, "_texpaint_undo")) {
|
||||
i32 i = history_undo_i - 1 < 0 ? g_config->undo_steps - 1 : history_undo_i - 1;
|
||||
return _uniforms_ext_undo_target(string_tmp("texpaint_undo%d", i));
|
||||
return _uniforms_ext_get_target(string_tmp("texpaint_undo%d", i));
|
||||
}
|
||||
else if (string_equals(link, "_texpaint_nor_undo")) {
|
||||
i32 i = history_undo_i - 1 < 0 ? g_config->undo_steps - 1 : history_undo_i - 1;
|
||||
return _uniforms_ext_undo_target(string_tmp("texpaint_nor_undo%d", i));
|
||||
return _uniforms_ext_get_target(string_tmp("texpaint_nor_undo%d", i));
|
||||
}
|
||||
else if (string_equals(link, "_texpaint_pack_undo")) {
|
||||
i32 i = history_undo_i - 1 < 0 ? g_config->undo_steps - 1 : history_undo_i - 1;
|
||||
return _uniforms_ext_undo_target(string_tmp("texpaint_pack_undo%d", i));
|
||||
return _uniforms_ext_get_target(string_tmp("texpaint_pack_undo%d", i));
|
||||
}
|
||||
else if (string_equals(link, "_texpaint_ref")) {
|
||||
return _uniforms_ext_get_target("texpaint_ref");
|
||||
}
|
||||
else if (string_equals(link, "_texpaint_nor_ref")) {
|
||||
return _uniforms_ext_get_target("texpaint_nor_ref");
|
||||
}
|
||||
else if (string_equals(link, "_texpaint_pack_ref")) {
|
||||
return _uniforms_ext_get_target("texpaint_pack_ref");
|
||||
}
|
||||
else if (string_equals(link, "_texpaint_sculpt_undo")) {
|
||||
return _uniforms_ext_undo_target("texpaint_sculpt_ref"); // Per-frame accumulation reference
|
||||
return _uniforms_ext_get_target("texpaint_sculpt_ref"); // Per-frame accumulation reference
|
||||
}
|
||||
else if (string_equals(link, "_texcolorid")) {
|
||||
if (g_project->_->assets->length == 0) {
|
||||
|
||||
Reference in New Issue
Block a user