diff --git a/paint/sources/export_texture.c b/paint/sources/export_texture.c index 05961345..185d5eac 100644 --- a/paint/sources/export_texture.c +++ b/paint/sources/export_texture.c @@ -219,19 +219,14 @@ void export_texture_run_layers(char *path, slot_layer_t_array_t *layers, char *o gpu_texture_t *mask = empty; slot_layer_t_array_t *l1masks = slot_layer_get_masks(l1, true); if (l1masks != NULL && !bake_material) { - if (l1masks->length > 1) { - layers_make_temp_mask_img(); - draw_begin(pipes_temp_mask_image, true, 0x00000000); - draw_end(); - slot_layer_t *l1 = GC_ALLOC_INIT(slot_layer_t, {.texpaint = pipes_temp_mask_image}); - for (i32 i = 0; i < l1masks->length; ++i) { - layers_merge_layer(l1, l1masks->buffer[i], false); - } - mask = pipes_temp_mask_image; - } - else { - mask = l1masks->buffer[0]->texpaint; + layers_make_temp_mask_img(); + draw_begin(pipes_temp_mask_image, true, 0xffffffff); + draw_end(); + slot_layer_t *l1 = GC_ALLOC_INIT(slot_layer_t, {.texpaint = pipes_temp_mask_image}); + for (i32 i = 0; i < l1masks->length; ++i) { + layers_merge_layer(l1, l1masks->buffer[i], false); } + mask = pipes_temp_mask_image; } if (l1->paint_base) { diff --git a/paint/sources/functions.h b/paint/sources/functions.h index a4423212..e0eeaa5e 100644 --- a/paint/sources/functions.h +++ b/paint/sources/functions.h @@ -480,7 +480,6 @@ void make_material_restore_paint_material(); parse_node_preview_result_t *make_material_parse_node_preview_material(ui_node_t *node, ui_node_canvas_t *group, ui_node_t_array_t *parents); void make_material_parse_brush(); char *make_material_blend_mode(node_shader_t *kong, i32 blending, char *cola, char *colb, char *opac); -char *make_material_blend_mode_mask(node_shader_t *kong, i32 blending, char *cola, char *colb, char *opac); f32 make_material_get_displace_strength(); void ui_viewnodes_init(); void ui_viewnodes_on_node_remove(ui_node_t *n); diff --git a/paint/sources/make_material.c b/paint/sources/make_material.c index ebdaba00..dacea428 100644 --- a/paint/sources/make_material.c +++ b/paint/sources/make_material.c @@ -1,10 +1,10 @@ #include "global.h" -shader_context_t *make_material_default_scon = NULL; -material_context_t *make_material_default_mcon = NULL; -static shader_context_t *make_material_saved_scon = NULL; -static material_context_t *make_material_saved_mcon = NULL; +shader_context_t *make_material_default_scon = NULL; +material_context_t *make_material_default_mcon = NULL; +static shader_context_t *make_material_saved_scon = NULL; +static material_context_t *make_material_saved_mcon = NULL; bool make_material_get_mout() { for (i32 i = 0; i < g_context->material->canvas->nodes->length; ++i) { @@ -512,61 +512,6 @@ char *make_material_blend_mode(node_shader_t *kong, i32 blending, char *cola, ch } } -char *make_material_blend_mode_mask(node_shader_t *kong, i32 blending, char *cola, char *colb, char *opac) { - if (blending == BLEND_TYPE_MIX) { - return string("lerp(%s, %s, %s)", cola, colb, opac); - } - else if (blending == BLEND_TYPE_DARKEN) { - return string("lerp(%s, min(%s, %s), %s)", cola, cola, colb, opac); - } - else if (blending == BLEND_TYPE_MULTIPLY) { - return string("lerp(%s, %s * %s, %s)", cola, cola, colb, opac); - } - else if (blending == BLEND_TYPE_BURN) { - return string("lerp(%s, 1.0 - (1.0 - %s) / %s, %s)", cola, cola, colb, opac); - } - else if (blending == BLEND_TYPE_LIGHTEN) { - return string("max(%s, %s * %s)", cola, colb, opac); - } - else if (blending == BLEND_TYPE_SCREEN) { - return string("(1.0 - ((1.0 - %s) + %s * (1.0 - %s)) * (1.0 - %s))", opac, opac, colb, cola); - } - else if (blending == BLEND_TYPE_DODGE) { - return string("lerp(%s, %s / (1.0 - %s), %s)", cola, cola, colb, opac); - } - else if (blending == BLEND_TYPE_ADD) { - return string("lerp(%s, %s + %s, %s)", cola, cola, colb, opac); - } - else if (blending == BLEND_TYPE_OVERLAY) { - // return "lerp(" + cola + ", " + cola + " < 0.5 ? 2.0 * " + cola + " * " + colb + " : 1.0 - 2.0 * (1.0 - " + cola + ") * (1.0 - " + colb + "), " + opac - // + ")"; - char *res = string("%s_res", string_replace_all(cola, ".", "_")); - node_shader_write_frag(kong, string("var %s: float;", res)); - node_shader_write_frag(kong, string("if (%s < 0.5) { %s = 2.0 * %s * %s; } else { %s = 1.0 - 2.0 * (1.0 - %s) * (1.0 - %s); }", cola, res, cola, colb, - res, cola, colb)); - return string("lerp(%s, %s, %s)", cola, res, opac); - } - else if (blending == BLEND_TYPE_SOFT_LIGHT) { - return string("((1.0 - %s) * %s + %s * ((1.0 - %s) * %s * %s + %s * (1.0 - (1.0 - %s) * (1.0 - %s))))", opac, cola, opac, cola, colb, cola, cola, colb, - cola); - } - else if (blending == BLEND_TYPE_LINEAR_LIGHT) { - return string("(%s + %s * (2.0 * (%s - 0.5)))", cola, opac, colb); - } - else if (blending == BLEND_TYPE_DIFFERENCE) { - return string("lerp(%s, abs(%s - %s), %s)", cola, cola, colb, opac); - } - else if (blending == BLEND_TYPE_SUBTRACT) { - return string("lerp(%s, %s - %s, %s)", cola, cola, colb, opac); - } - else if (blending == BLEND_TYPE_DIVIDE) { - return string("(1.0 - %s) * %s + %s * %s / %s", opac, cola, opac, cola, colb); - } - else { // BlendHue, BlendSaturation, BlendColor, BlendValue - return string("lerp(%s, %s, %s)", cola, colb, opac); - } -} - f32 make_material_get_displace_strength() { vec4_t sc = context_main_object()->base->transform->scale; return g_config->displace_strength * 0.1 * sc.x; diff --git a/paint/sources/make_mesh.c b/paint/sources/make_mesh.c index 32003d60..f590de4e 100644 --- a/paint/sources/make_mesh.c +++ b/paint/sources/make_mesh.c @@ -341,7 +341,7 @@ node_shader_context_t *make_mesh_run(material_t *data, i32 layer_pass) { } if (has_visible) { char *texpaint_mask = string("texpaint_mask%s", i32_to_string(l->id)); - node_shader_write_frag(kong, string("var %s: float = 0.0;", texpaint_mask)); + node_shader_write_frag(kong, string("var %s: float = 1.0;", texpaint_mask)); for (i32 i = 0; i < masks->length; ++i) { slot_layer_t *m = masks->buffer[i]; if (!slot_layer_is_visible(m)) { @@ -352,10 +352,9 @@ node_shader_context_t *make_mesh_run(material_t *data, i32 layer_pass) { node_shader_write_frag(kong, string("var texpaint_mask_sample%s: float = sample_lod(texpaint%s, sampler_linear, %s, 0.0).r;", i32_to_string(m->id), i32_to_string(m->id), tex_coord)); - f32 opac = slot_layer_get_opacity(m); - char *mask = make_material_blend_mode_mask(kong, m->blending, texpaint_mask, string("texpaint_mask_sample%s", i32_to_string(m->id)), - string("float(%s)", f32_to_string(opac))); - node_shader_write_frag(kong, string("%s = %s;", texpaint_mask, mask)); + f32 opac = slot_layer_get_opacity(m); + node_shader_write_frag(kong, string("%s *= lerp(1.0, %s, float(%s));", texpaint_mask, + string("texpaint_mask_sample%s", i32_to_string(m->id)), f32_to_string(opac))); node_shader_write_frag(kong, "}"); } node_shader_write_frag(kong, string("texpaint_opac *= clamp(%s, 0.0, 1.0);", texpaint_mask)); @@ -632,7 +631,7 @@ node_shader_context_t *make_mesh_run(material_t *data, i32 layer_pass) { node_shader_write_frag(kong, string("var mask_view: float = sample_lod(texpaint%s, sampler_linear, tex_coord, 0.0).r;", i32_to_string(id))); } else { - node_shader_write_frag(kong, "var mask_view: float = 0.0;"); + node_shader_write_frag(kong, "var mask_view: float = 1.0;"); for (i32 i = 0; i < slot_layer_get_masks(g_context->layer, true)->length; ++i) { slot_layer_t *m = slot_layer_get_masks(g_context->layer, true)->buffer[i]; if (!slot_layer_is_visible(m)) { @@ -640,10 +639,8 @@ node_shader_context_t *make_mesh_run(material_t *data, i32 layer_pass) { } node_shader_write_frag(kong, string("var mask_sample%s: float = sample_lod(texpaint_view_mask%s, sampler_linear, tex_coord, 0.0).r;", i32_to_string(m->id), i32_to_string(m->id))); - f32 opac = slot_layer_get_opacity(m); - char *mask = make_material_blend_mode_mask(kong, m->blending, "mask_view", string("mask_sample%s", i32_to_string(m->id)), - string("float(%s)", f32_to_string(opac))); - node_shader_write_frag(kong, string("mask_view = %s;", mask)); + f32 opac = slot_layer_get_opacity(m); + node_shader_write_frag(kong, string("mask_view *= lerp(1.0, mask_sample%s, float(%s));", i32_to_string(m->id), f32_to_string(opac))); } } node_shader_write_frag(kong, "output[1] = float4(mask_view, mask_view, mask_view, 1.0);"); diff --git a/paint/sources/slot_layer.c b/paint/sources/slot_layer.c index 431e9b41..7290607b 100644 --- a/paint/sources/slot_layer.c +++ b/paint/sources/slot_layer.c @@ -99,7 +99,7 @@ slot_layer_t *slot_layer_create(char *ext, layer_slot_type_t type, slot_layer_t i32 id = (raw->id + 1); raw->name = string("Mask %d", id); char *format = "RGBA32"; // Full bits for undo support, R8 is used - raw->blending = BLEND_TYPE_ADD; + raw->blending = BLEND_TYPE_MIX; { render_target_t *t = render_target_create(); @@ -1696,7 +1696,18 @@ void layers_merge_layer(slot_layer_t *l0, slot_layer_t *l1, bool use_mask) { // for (let i: i32 = 1; i < l1masks.length - 1; ++i) { // merge_layer(l1masks[i + 1], l1masks[i]); // } - mask = l1masks->buffer[0]->texpaint; + layers_make_temp_mask_img(); + _gpu_begin(pipes_temp_mask_image, NULL, NULL, GPU_CLEAR_NONE, 0, 0.0); + gpu_set_pipeline(pipes_merge_mask); + gpu_set_texture(pipes_tex0_merge_mask, l1masks->buffer[0]->texpaint); + gpu_set_texture(pipes_texa_merge_mask, empty); + gpu_set_float(pipes_opac_merge_mask, l1masks->buffer[0]->mask_opacity); + gpu_set_int(pipes_blending_merge_mask, BLEND_TYPE_MIX); + gpu_set_vertex_buffer(const_data_screen_aligned_vb); + gpu_set_index_buffer(const_data_screen_aligned_ib); + gpu_draw(); + gpu_end(); + mask = pipes_temp_mask_image; } if (slot_layer_is_mask(l1)) { @@ -1705,7 +1716,7 @@ void layers_merge_layer(slot_layer_t *l0, slot_layer_t *l1, bool use_mask) { gpu_set_texture(pipes_tex0_merge_mask, l1->texpaint); gpu_set_texture(pipes_texa_merge_mask, layers_temp_image); gpu_set_float(pipes_opac_merge_mask, slot_layer_get_opacity(l1)); - gpu_set_int(pipes_blending_merge_mask, l1->blending); + gpu_set_int(pipes_blending_merge_mask, BLEND_TYPE_MIX); gpu_set_vertex_buffer(const_data_screen_aligned_vb); gpu_set_index_buffer(const_data_screen_aligned_ib); gpu_draw(); @@ -1814,19 +1825,14 @@ slot_layer_t *layers_flatten(bool height_to_normal, slot_layer_t_array_t *layers gpu_texture_t *mask = empty; slot_layer_t_array_t *l1masks = slot_layer_get_masks(l1, true); if (l1masks != NULL) { - if (l1masks->length > 1) { - layers_make_temp_mask_img(); - draw_begin(pipes_temp_mask_image, GPU_CLEAR_COLOR, 0x00000000); - draw_end(); - slot_layer_t *l1 = GC_ALLOC_INIT(slot_layer_t, {.texpaint = pipes_temp_mask_image}); - for (i32 i = 0; i < l1masks->length; ++i) { - layers_merge_layer(l1, l1masks->buffer[i], false); - } - mask = pipes_temp_mask_image; - } - else { - mask = l1masks->buffer[0]->texpaint; + layers_make_temp_mask_img(); + draw_begin(pipes_temp_mask_image, GPU_CLEAR_COLOR, 0xffffffff); + draw_end(); + slot_layer_t *l1 = GC_ALLOC_INIT(slot_layer_t, {.texpaint = pipes_temp_mask_image}); + for (i32 i = 0; i < l1masks->length; ++i) { + layers_merge_layer(l1, l1masks->buffer[i], false); } + mask = pipes_temp_mask_image; } if (l1->paint_base) { diff --git a/paint/sources/tab_layers.c b/paint/sources/tab_layers.c index 2004a274..71ae58bd 100644 --- a/paint/sources/tab_layers.c +++ b/paint/sources/tab_layers.c @@ -447,13 +447,10 @@ void tab_layers_draw_layer_slot_full(slot_layer_t *l, i32 i) { } // Blending combo - if (!slot_layer_is_group(l)) { + if (!slot_layer_is_group(l) && !slot_layer_is_mask(l)) { ui->_x = uix + uiw * 0.60; ui->_y = uiy; ui->_w = uiw * 0.30; - if (slot_layer_is_mask(l)) { - ui->_y += center; - } tab_layers_combo_blending(l, false); } @@ -641,7 +638,7 @@ void tab_layers_draw_layer_context_menu_draw() { ui_menu_keep_open = true; } - if (!slot_layer_is_group(l)) { + if (!slot_layer_is_group(l) && !slot_layer_is_mask(l)) { if (tab_layers_combo_blending(l, true)->changed) { ui_menu_keep_open = true; }