mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-30 23:19:49 +00:00
Make clipping masks work with Move tool and offset image dialog (#1057)
* made clipping masks work with offset image dialog * move tool now works with clipping masks
This commit is contained in:
parent
f27d152cb3
commit
1d82bd95e5
|
@ -172,10 +172,18 @@ void fragment() {
|
||||||
if (!origin_y_positive) {
|
if (!origin_y_positive) {
|
||||||
current_origin.y = -current_origin.y;
|
current_origin.y = -current_origin.y;
|
||||||
}
|
}
|
||||||
|
// get origin of previous layer (used for clipping masks to work correctly)
|
||||||
|
vec2 prev_origin = texture(metadata, vec2(float(i - 1), 2.0 / metadata_size_float.y)).rg;
|
||||||
|
if (!origin_x_positive) {
|
||||||
|
prev_origin.x = -prev_origin.x;
|
||||||
|
}
|
||||||
|
if (!origin_y_positive) {
|
||||||
|
prev_origin.y = -prev_origin.y;
|
||||||
|
}
|
||||||
float current_opacity = texture(metadata, vec2(layer_index, 1.0 / metadata_size_float.y)).r;
|
float current_opacity = texture(metadata, vec2(layer_index, 1.0 / metadata_size_float.y)).r;
|
||||||
vec2 uv = UV - current_origin;
|
vec2 uv = UV - current_origin;
|
||||||
vec4 layer_color = texture(layers, vec3(uv, float(i)));
|
vec4 layer_color = texture(layers, vec3(uv, float(i)));
|
||||||
vec4 prev_layer_color = texture(layers, vec3(uv, float(i - 1)));
|
vec4 prev_layer_color = texture(layers, vec3(UV - prev_origin, float(i - 1)));
|
||||||
float clipping_mask = texture(metadata, vec2(layer_index, 3.0 / metadata_size_float.y)).r;
|
float clipping_mask = texture(metadata, vec2(layer_index, 3.0 / metadata_size_float.y)).r;
|
||||||
layer_color.a *= prev_layer_color.a * step(0.5, clipping_mask) + 1.0 * step(clipping_mask, 0.5);
|
layer_color.a *= prev_layer_color.a * step(0.5, clipping_mask) + 1.0 * step(clipping_mask, 0.5);
|
||||||
layer_color.a = border_trim(layer_color, uv);
|
layer_color.a = border_trim(layer_color, uv);
|
||||||
|
|
|
@ -10,9 +10,6 @@ var wrap_around := false
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
super._ready()
|
super._ready()
|
||||||
var sm := ShaderMaterial.new()
|
|
||||||
sm.shader = shader
|
|
||||||
preview.set_material(sm)
|
|
||||||
# Set in the order of the Animate enum
|
# Set in the order of the Animate enum
|
||||||
animate_panel.add_float_property(
|
animate_panel.add_float_property(
|
||||||
"Offset X", $VBoxContainer/OffsetOptions/OffsetSliders.get_sliders()[0]
|
"Offset X", $VBoxContainer/OffsetOptions/OffsetSliders.get_sliders()[0]
|
||||||
|
@ -39,17 +36,85 @@ func commit_action(cel: Image, project := Global.current_project) -> void:
|
||||||
|
|
||||||
var params := {"offset": offset, "wrap_around": wrap_around, "selection": selection_tex}
|
var params := {"offset": offset, "wrap_around": wrap_around, "selection": selection_tex}
|
||||||
if !has_been_confirmed:
|
if !has_been_confirmed:
|
||||||
for param in params:
|
recalculate_preview(params)
|
||||||
preview.material.set_shader_parameter(param, params[param])
|
|
||||||
else:
|
else:
|
||||||
var gen := ShaderImageEffect.new()
|
var gen := ShaderImageEffect.new()
|
||||||
gen.generate_image(cel, shader, params, project.size)
|
gen.generate_image(cel, shader, params, project.size)
|
||||||
|
|
||||||
|
|
||||||
func _on_OffsetSliders_value_changed(_value: Vector2) -> void:
|
func _on_OffsetSliders_value_changed(_value: Vector2) -> void:
|
||||||
update_preview()
|
update_preview() # (from here, commit_action will be called, and then recalculate_preview)
|
||||||
|
|
||||||
|
|
||||||
func _on_WrapCheckBox_toggled(button_pressed: bool) -> void:
|
func _on_WrapCheckBox_toggled(button_pressed: bool) -> void:
|
||||||
wrap_around = button_pressed
|
wrap_around = button_pressed
|
||||||
update_preview()
|
update_preview() # (from here, commit_action will be called, and then recalculate_preview)
|
||||||
|
|
||||||
|
|
||||||
|
func recalculate_preview(params: Dictionary) -> void:
|
||||||
|
var frame := Global.current_project.frames[_preview_idx]
|
||||||
|
commit_idx = _preview_idx
|
||||||
|
match affect:
|
||||||
|
SELECTED_CELS:
|
||||||
|
selected_cels.fill(Color(0, 0, 0, 0))
|
||||||
|
blend_layers(selected_cels, frame, params, true)
|
||||||
|
preview_image.copy_from(selected_cels)
|
||||||
|
_:
|
||||||
|
current_frame.fill(Color(0, 0, 0, 0))
|
||||||
|
blend_layers(current_frame, frame, params)
|
||||||
|
preview_image.copy_from(current_frame)
|
||||||
|
|
||||||
|
|
||||||
|
## Altered version of blend_layers() located in DrawingAlgos.gd
|
||||||
|
## This function is REQUIRED in order for offset effect to work correctly with cliping masks
|
||||||
|
func blend_layers(
|
||||||
|
image: Image,
|
||||||
|
frame: Frame,
|
||||||
|
effect_params := {},
|
||||||
|
only_selected_cels := false,
|
||||||
|
only_selected_layers := false,
|
||||||
|
) -> void:
|
||||||
|
var project := Global.current_project
|
||||||
|
var frame_index := project.frames.find(frame)
|
||||||
|
var previous_ordered_layers: Array[int] = project.ordered_layers
|
||||||
|
project.order_layers(frame_index)
|
||||||
|
var textures: Array[Image] = []
|
||||||
|
var gen := ShaderImageEffect.new()
|
||||||
|
# Nx4 texture, where N is the number of layers and the first row are the blend modes,
|
||||||
|
# the second are the opacities, the third are the origins and the fourth are the
|
||||||
|
# clipping mask booleans.
|
||||||
|
var metadata_image := Image.create(project.layers.size(), 4, false, Image.FORMAT_R8)
|
||||||
|
for i in project.layers.size():
|
||||||
|
var ordered_index := project.ordered_layers[i]
|
||||||
|
var layer := project.layers[ordered_index]
|
||||||
|
var include := true if layer.is_visible_in_hierarchy() else false
|
||||||
|
if only_selected_cels and include:
|
||||||
|
var test_array := [frame_index, i]
|
||||||
|
if not test_array in project.selected_cels:
|
||||||
|
include = false
|
||||||
|
if only_selected_layers and include:
|
||||||
|
var layer_is_selected := false
|
||||||
|
for selected_cel in project.selected_cels:
|
||||||
|
if i == selected_cel[1]:
|
||||||
|
layer_is_selected = true
|
||||||
|
break
|
||||||
|
if not layer_is_selected:
|
||||||
|
include = false
|
||||||
|
var cel := frame.cels[ordered_index]
|
||||||
|
var cel_image := layer.display_effects(cel)
|
||||||
|
if include: ## apply offset effect to it
|
||||||
|
gen.generate_image(cel_image, shader, effect_params, project.size)
|
||||||
|
textures.append(cel_image)
|
||||||
|
DrawingAlgos.set_layer_metadata_image(layer, cel, metadata_image, ordered_index, include)
|
||||||
|
var texture_array := Texture2DArray.new()
|
||||||
|
texture_array.create_from_images(textures)
|
||||||
|
var params := {
|
||||||
|
"layers": texture_array,
|
||||||
|
"metadata": ImageTexture.create_from_image(metadata_image),
|
||||||
|
}
|
||||||
|
var blended := Image.create(project.size.x, project.size.y, false, image.get_format())
|
||||||
|
var blend_layers_shader = DrawingAlgos.blend_layers_shader
|
||||||
|
gen.generate_image(blended, blend_layers_shader, params, project.size)
|
||||||
|
image.blend_rect(blended, Rect2i(Vector2i.ZERO, project.size), Vector2i.ZERO)
|
||||||
|
# Re-order the layers again to ensure correct canvas drawing
|
||||||
|
project.ordered_layers = previous_ordered_layers
|
||||||
|
|
Loading…
Reference in a new issue