1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-02-20 12:33:14 +00:00

Fix dithered gradients having wrong colors

Pass a nx1 image instead of the GradientTexture, that contains all of the gradient's selected colors, where n is the number of colors.
This commit is contained in:
Emmanouil Papadeas 2023-01-29 01:02:40 +02:00
parent f26484f854
commit 53dea9c8d0
3 changed files with 20 additions and 7 deletions

View file

@ -14,7 +14,7 @@ uniform int repeat = 0; // 0 = none, 1 = repeat, 2 = mirrored, 3 = truncate
float modify_uv(vec2 uv) {
float modified_uv;
if (shape == 0) {
if (shape == 0) { // Linear
vec2 uv_offsetted = uv - 0.5;
float angle_cos = cos(radians(angle));
float angle_sin = sin(radians(angle));
@ -24,7 +24,7 @@ float modify_uv(vec2 uv) {
float pivot = position / size;
modified_uv -= pivot - 0.5;
}
else {
else { // Radial
vec2 uv_offsetted = uv * 2.0 - 1.0;
uv_offsetted -= (center * 2.0) - vec2(1.0);
uv_offsetted *= radius;
@ -33,6 +33,7 @@ float modify_uv(vec2 uv) {
return modified_uv;
}
float mirror_fract(float uv) {
int sign_uv = (int(sign(uv)) - 1) / 2;
if (int((uv)) % 2 == sign_uv)

View file

@ -19,7 +19,7 @@ uniform int n_of_colors = 2;
float modify_uv(vec2 uv) {
float modified_uv;
if (shape == 0) {
if (shape == 0) { // Linear
vec2 uv_offsetted = uv - 0.5;
float angle_cos = cos(radians(angle));
float angle_sin = sin(radians(angle));
@ -29,7 +29,7 @@ float modify_uv(vec2 uv) {
float pivot = position / size;
modified_uv -= pivot - 0.5;
}
else {
else { // Radial
vec2 uv_offsetted = uv * 2.0 - 1.0;
uv_offsetted -= (center * 2.0) - vec2(1.0);
uv_offsetted *= radius;
@ -52,7 +52,7 @@ float mirror_fract(float uv) {
// Logic taken from https://godotshaders.com/shader/dither-gradient-shader/
float dither(vec2 uv, float modified_uv) {
float uv_lower = floor(modified_uv);
float uv_upper = (floor(modified_uv) + 1.0);
float uv_upper = floor(modified_uv) + 1.0;
float threshold = texture(dither_texture, uv * (image_size / float(pixel_size))).r;
float ramp_val = modified_uv < threshold ? 0.0 : 1.0;
// sample at the lower bound colour if ramp_val is 0.0, upper bound color if 1.0

View file

@ -70,22 +70,34 @@ func commit_action(cel: Image, project: Project = Global.current_project) -> voi
var dither_texture: Texture = selected_dither_matrix.texture
var pixel_size := dither_texture.get_width()
var gradient: Gradient = gradient_edit.texture.gradient
var gradient: Gradient = gradient_edit.gradient
var n_of_colors := gradient.offsets.size()
# Pass the gradient offsets as an array to the shader
# ...but since Godot 3.x doesn't support uniform arrays, instead we construct
# a nx1 grayscale texture with each offset stored in each pixel, and pass it to the shader
var offsets_image := Image.new()
offsets_image.create(n_of_colors, 1, false, Image.FORMAT_L8)
# Construct an image that contains the selected colors of the gradient without interpolation
var gradient_image := Image.new()
gradient_image.create(n_of_colors, 1, false, Image.FORMAT_RGBA8)
offsets_image.lock()
gradient_image.lock()
for i in n_of_colors:
var c := gradient.offsets[i]
offsets_image.set_pixel(i, 0, Color(c, c, c, c))
gradient_image.set_pixel(i, 0, gradient.colors[i])
offsets_image.unlock()
gradient_image.unlock()
var offsets_tex := ImageTexture.new()
offsets_tex.create_from_image(offsets_image, 0)
var gradient_tex: Texture
if shader == shader_linear:
gradient_tex = gradient_edit.texture
else:
gradient_tex = ImageTexture.new()
gradient_tex.create_from_image(gradient_image, 0)
var params := {
"gradient_texture": gradient_edit.texture,
"gradient_texture": gradient_tex,
"offset_texture": offsets_tex,
"selection": selection_tex,
"repeat": repeat_option_button.selected,