mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-18 17:19:50 +00:00
Add a ShaderInclude file for common shader rotation code
This commit is contained in:
parent
aa77dcb61f
commit
73e40ed127
49
src/Shaders/Effects/Rotation/CommonRotation.gdshaderinc
Normal file
49
src/Shaders/Effects/Rotation/CommonRotation.gdshaderinc
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
uniform sampler2D selection_tex;
|
||||||
|
uniform vec2 pivot_pixel;
|
||||||
|
uniform float angle;
|
||||||
|
|
||||||
|
vec2 rotate(vec2 uv, vec2 pivot, float ratio) {
|
||||||
|
// Scale and center image
|
||||||
|
uv.x -= pivot.x;
|
||||||
|
uv.x *= ratio;
|
||||||
|
uv.x += pivot.x;
|
||||||
|
|
||||||
|
// Rotate image
|
||||||
|
uv -= pivot;
|
||||||
|
mat3 transformation = mat3(
|
||||||
|
vec3(cos(angle), -sin(angle), 0.0),
|
||||||
|
vec3(sin(angle), cos(angle), 0.0),
|
||||||
|
vec3(0.0, 0.0, 1.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
uv = (transformation * vec3(uv, 1.0)).xy;
|
||||||
|
uv.x /= ratio;
|
||||||
|
uv += pivot;
|
||||||
|
|
||||||
|
return uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 mix_rotated_and_original(vec4 color, vec4 original_color, vec2 uv, vec2 rotated_uv, vec2 tex_pixel_size) {
|
||||||
|
color.a *= texture(selection_tex, rotated_uv).a; // Combine with selection mask
|
||||||
|
// Make a border to prevent stretching pixels on the edge
|
||||||
|
vec2 border_uv = rotated_uv;
|
||||||
|
|
||||||
|
// Center the border
|
||||||
|
border_uv -= 0.5;
|
||||||
|
border_uv *= 2.0;
|
||||||
|
border_uv = abs(border_uv);
|
||||||
|
|
||||||
|
float border = max(border_uv.x, border_uv.y); // This is a rectangular gradient
|
||||||
|
border = floor(border - tex_pixel_size.x); // Turn the grad into a rectangle shape
|
||||||
|
border = 1.0 - clamp(border, 0.0, 1.0); // Invert the rectangle
|
||||||
|
|
||||||
|
float selection = texture(selection_tex, uv).a;
|
||||||
|
float mask = mix(selection, 1.0, 1.0 - ceil(original_color.a)); // Combine selection mask with area outside original
|
||||||
|
|
||||||
|
vec4 final_color;
|
||||||
|
// Combine original and rotated image only when intersecting, otherwise just pure rotated image.
|
||||||
|
final_color.rgb = mix(mix(original_color.rgb, color.rgb, color.a * border), color.rgb, mask);
|
||||||
|
final_color.a = mix(original_color.a, 0.0, selection); // Remove alpha on the selected area
|
||||||
|
final_color.a = mix(final_color.a, 1.0, color.a * border); // Combine alpha of original image and rotated
|
||||||
|
return final_color;
|
||||||
|
}
|
|
@ -1,56 +1,17 @@
|
||||||
shader_type canvas_item;
|
shader_type canvas_item;
|
||||||
render_mode unshaded;
|
render_mode unshaded;
|
||||||
|
|
||||||
uniform float angle;
|
#include "res://src/Shaders/Effects/Rotation/CommonRotation.gdshaderinc"
|
||||||
uniform sampler2D selection_tex;
|
|
||||||
uniform vec2 pivot_pixel;
|
|
||||||
|
|
||||||
|
|
||||||
vec2 rotate(vec2 uv, vec2 pivot, float ratio) {
|
|
||||||
// Scale and center image
|
|
||||||
uv.x -= pivot.x;
|
|
||||||
uv.x *= ratio;
|
|
||||||
uv.x += pivot.x;
|
|
||||||
|
|
||||||
// Rotate image
|
|
||||||
uv -= pivot;
|
|
||||||
uv = vec2(cos(angle) * uv.x + sin(angle) * uv.y,
|
|
||||||
-sin(angle) * uv.x + cos(angle) * uv.y);
|
|
||||||
uv.x /= ratio;
|
|
||||||
uv += pivot;
|
|
||||||
|
|
||||||
return uv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void fragment() {
|
void fragment() {
|
||||||
vec4 original = texture(TEXTURE, UV);
|
vec4 original = texture(TEXTURE, UV);
|
||||||
float selection = texture(selection_tex, UV).a;
|
|
||||||
|
|
||||||
vec2 tex_size = 1.0 / TEXTURE_PIXEL_SIZE; // Texture size in real pixel coordinates
|
vec2 tex_size = 1.0 / TEXTURE_PIXEL_SIZE; // Texture size in real pixel coordinates
|
||||||
vec2 pixelated_uv = floor(UV * tex_size) / (tex_size - 1.0); // Pixelate UV to fit resolution
|
vec2 pixelated_uv = floor(UV * tex_size) / (tex_size - 1.0); // Pixelate UV to fit resolution
|
||||||
vec2 pivot = pivot_pixel / tex_size; // Normalize pivot position
|
vec2 pivot = pivot_pixel / tex_size; // Normalize pivot position
|
||||||
float ratio = tex_size.x / tex_size.y; // Resolution ratio
|
float ratio = tex_size.x / tex_size.y; // Resolution ratio
|
||||||
|
|
||||||
// Make a border to prevent stretching pixels on the edge
|
vec2 rotated_uv = rotate(pixelated_uv, pivot, ratio);
|
||||||
vec2 border_uv = rotate(pixelated_uv, pivot, ratio);
|
vec4 rotated_color = texture(TEXTURE, rotated_uv); // Rotated image
|
||||||
|
COLOR = mix_rotated_and_original(rotated_color, original, UV, rotated_uv, TEXTURE_PIXEL_SIZE);
|
||||||
// Center the border
|
|
||||||
border_uv -= 0.5;
|
|
||||||
border_uv *= 2.0;
|
|
||||||
border_uv = abs(border_uv);
|
|
||||||
|
|
||||||
float border = max(border_uv.x, border_uv.y); // This is a rectangular gradient
|
|
||||||
border = floor(border - TEXTURE_PIXEL_SIZE.x); // Turn the grad into a rectangle shape
|
|
||||||
border = 1.0 - clamp(border, 0.0, 1.0); // Invert the rectangle
|
|
||||||
|
|
||||||
// Mixing
|
|
||||||
vec4 rotated = texture(TEXTURE, rotate(pixelated_uv, pivot, ratio)); // Rotated image
|
|
||||||
rotated.a *= texture(selection_tex, rotate(pixelated_uv, pivot, ratio)).a; // Combine with selection mask
|
|
||||||
float mask = mix(selection, 1.0, 1.0 - ceil(original.a)); // Combine selection mask with area outside original
|
|
||||||
|
|
||||||
// Combine original and rotated image only when intersecting, otherwise just pure rotated image.
|
|
||||||
COLOR.rgb = mix(mix(original.rgb, rotated.rgb, rotated.a * border), rotated.rgb, mask);
|
|
||||||
COLOR.a = mix(original.a, 0.0, selection); // Remove alpha on the selected area
|
|
||||||
COLOR.a = mix(COLOR.a, 1.0, rotated.a * border); // Combine alpha of original image and rotated
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,8 @@ shader_type canvas_item;
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "res://src/Shaders/Effects/Rotation/CommonRotation.gdshaderinc"
|
||||||
|
|
||||||
uniform int ScaleMultiplier : hint_range(0, 100) = 4;
|
uniform int ScaleMultiplier : hint_range(0, 100) = 4;
|
||||||
|
|
||||||
// vertex compatibility #defines
|
// vertex compatibility #defines
|
||||||
|
@ -40,9 +42,6 @@ uniform int ScaleMultiplier : hint_range(0, 100) = 4;
|
||||||
// #define outsize vec4(OutputSize, 1.0 / OutputSize)
|
// #define outsize vec4(OutputSize, 1.0 / OutputSize)
|
||||||
|
|
||||||
// Pixelorama-specific uniforms
|
// Pixelorama-specific uniforms
|
||||||
uniform float angle;
|
|
||||||
uniform sampler2D selection_tex;
|
|
||||||
uniform vec2 pivot_pixel;
|
|
||||||
uniform bool preview = false;
|
uniform bool preview = false;
|
||||||
|
|
||||||
|
|
||||||
|
@ -289,27 +288,9 @@ vec4 scale(sampler2D image, vec2 coord, vec2 pxSize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vec2 rotate(vec2 uv, vec2 pivot, float ratio) { // Taken from NearestNeighbour shader
|
|
||||||
// Scale and center image
|
|
||||||
uv.x -= pivot.x;
|
|
||||||
uv.x *= ratio;
|
|
||||||
uv.x += pivot.x;
|
|
||||||
|
|
||||||
// Rotate image
|
|
||||||
uv -= pivot;
|
|
||||||
uv = vec2(cos(angle) * uv.x + sin(angle) * uv.y,
|
|
||||||
-sin(angle) * uv.x + cos(angle) * uv.y);
|
|
||||||
uv.x /= ratio;
|
|
||||||
uv += pivot;
|
|
||||||
|
|
||||||
return uv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void fragment()
|
void fragment()
|
||||||
{
|
{
|
||||||
vec4 original = texture(TEXTURE, UV);
|
vec4 original = texture(TEXTURE, UV);
|
||||||
float selection = texture(selection_tex, UV).a;
|
|
||||||
vec2 size = 1.0 / TEXTURE_PIXEL_SIZE;
|
vec2 size = 1.0 / TEXTURE_PIXEL_SIZE;
|
||||||
vec2 pivot = pivot_pixel / size; // Normalize pivot position
|
vec2 pivot = pivot_pixel / size; // Normalize pivot position
|
||||||
float ratio = size.x / size.y; // Resolution ratio
|
float ratio = size.x / size.y; // Resolution ratio
|
||||||
|
@ -321,29 +302,8 @@ void fragment()
|
||||||
else {
|
else {
|
||||||
rotated_uv = rotate(UV, pivot, ratio);
|
rotated_uv = rotate(UV, pivot, ratio);
|
||||||
}
|
}
|
||||||
vec4 c;
|
vec4 c = scale(TEXTURE, rotated_uv, TEXTURE_PIXEL_SIZE);
|
||||||
c = scale(TEXTURE, rotated_uv, TEXTURE_PIXEL_SIZE);
|
|
||||||
|
|
||||||
// Taken from NearestNeighbour shader
|
// Pixelorama edit
|
||||||
c.a *= texture(selection_tex, rotated_uv).a; // Combine with selection mask
|
COLOR = mix_rotated_and_original(c, original, UV, rotated_uv, TEXTURE_PIXEL_SIZE);
|
||||||
// Make a border to prevent stretching pixels on the edge
|
|
||||||
vec2 border_uv = rotated_uv;
|
|
||||||
|
|
||||||
// Center the border
|
|
||||||
border_uv -= 0.5;
|
|
||||||
border_uv *= 2.0;
|
|
||||||
border_uv = abs(border_uv);
|
|
||||||
|
|
||||||
float border = max(border_uv.x, border_uv.y); // This is a rectangular gradient
|
|
||||||
border = floor(border - TEXTURE_PIXEL_SIZE.x); // Turn the grad into a rectangle shape
|
|
||||||
border = 1.0 - clamp(border, 0.0, 1.0); // Invert the rectangle
|
|
||||||
|
|
||||||
float mask = mix(selection, 1.0, 1.0 - ceil(original.a)); // Combine selection mask with area outside original
|
|
||||||
|
|
||||||
// Combine original and rotated image only when intersecting, otherwise just pure rotated image.
|
|
||||||
COLOR.rgb = mix(mix(original.rgb, c.rgb, c.a * border), c.rgb, mask);
|
|
||||||
COLOR.a = mix(original.a, 0.0, selection); // Remove alpha on the selected area
|
|
||||||
COLOR.a = mix(COLOR.a, 1.0, c.a * border); // Combine alpha of original image and rotated
|
|
||||||
//c.a = step(0.5,c.a);
|
|
||||||
//COLOR = c;
|
|
||||||
}
|
}
|
|
@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
shader_type canvas_item;
|
shader_type canvas_item;
|
||||||
|
#include "res://src/Shaders/Effects/Rotation/CommonRotation.gdshaderinc"
|
||||||
//enables 2:1 slopes. otherwise only uses 45 degree slopes
|
//enables 2:1 slopes. otherwise only uses 45 degree slopes
|
||||||
#define SLOPE
|
#define SLOPE
|
||||||
//cleans up small detail slope transitions (if SLOPE is enabled)
|
//cleans up small detail slope transitions (if SLOPE is enabled)
|
||||||
|
@ -45,9 +45,6 @@ uniform float similarThreshold = 0.0;
|
||||||
uniform float lineWidth = 1.0;
|
uniform float lineWidth = 1.0;
|
||||||
|
|
||||||
// Edited for Pixelorama
|
// Edited for Pixelorama
|
||||||
uniform float angle;
|
|
||||||
uniform sampler2D selection_tex;
|
|
||||||
uniform vec2 pivot_pixel;
|
|
||||||
uniform bool preview = false;
|
uniform bool preview = false;
|
||||||
|
|
||||||
bool similar(vec4 col1, vec4 col2){
|
bool similar(vec4 col1, vec4 col2){
|
||||||
|
@ -274,28 +271,10 @@ vec4 sliceDist(vec2 point, vec2 mainDir, vec2 pointDir, vec4 u, vec4 uf, vec4 uf
|
||||||
return vec4(-1.0);
|
return vec4(-1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pixelorama edit, taken from NearestNeighbour shader
|
|
||||||
vec2 rotate(vec2 uv, vec2 pivot, float ratio) {
|
|
||||||
// Scale and center image
|
|
||||||
uv.x -= pivot.x;
|
|
||||||
uv.x *= ratio;
|
|
||||||
uv.x += pivot.x;
|
|
||||||
|
|
||||||
// Rotate image
|
|
||||||
uv -= pivot;
|
|
||||||
uv = vec2(cos(angle) * uv.x + sin(angle) * uv.y,
|
|
||||||
-sin(angle) * uv.x + cos(angle) * uv.y);
|
|
||||||
uv.x /= ratio;
|
|
||||||
uv += pivot;
|
|
||||||
|
|
||||||
return uv;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
void fragment() {
|
||||||
vec2 size = 1.0/TEXTURE_PIXEL_SIZE+0.0001; //fix for some sort of rounding error
|
vec2 size = 1.0/TEXTURE_PIXEL_SIZE+0.0001; //fix for some sort of rounding error
|
||||||
// Pixelorama edit
|
// Pixelorama edit
|
||||||
vec4 original = texture(TEXTURE, UV);
|
vec4 original = texture(TEXTURE, UV);
|
||||||
float selection = texture(selection_tex, UV).a;
|
|
||||||
vec2 pivot = pivot_pixel / size; // Normalize pivot position
|
vec2 pivot = pivot_pixel / size; // Normalize pivot position
|
||||||
float ratio = size.x / size.y; // Resolution ratio
|
float ratio = size.x / size.y; // Resolution ratio
|
||||||
vec2 pixelated_uv = floor(UV * size) / (size - 1.0); // Pixelate UV to fit resolutio
|
vec2 pixelated_uv = floor(UV * size) / (size - 1.0); // Pixelate UV to fit resolutio
|
||||||
|
@ -360,24 +339,6 @@ void fragment() {
|
||||||
col = u_col;
|
col = u_col;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pixelorama edit, taken from NearestNeighbour shader
|
// Pixelorama edit
|
||||||
col.a *= texture(selection_tex, rotated_uv).a; // Combine with selection mask
|
COLOR = mix_rotated_and_original(col, original, UV, rotated_uv, TEXTURE_PIXEL_SIZE);
|
||||||
// Make a border to prevent stretching pixels on the edge
|
|
||||||
vec2 border_uv = rotated_uv;
|
|
||||||
|
|
||||||
// Center the border
|
|
||||||
border_uv -= 0.5;
|
|
||||||
border_uv *= 2.0;
|
|
||||||
border_uv = abs(border_uv);
|
|
||||||
|
|
||||||
float border = max(border_uv.x, border_uv.y); // This is a rectangular gradient
|
|
||||||
border = floor(border - TEXTURE_PIXEL_SIZE.x); // Turn the grad into a rectangle shape
|
|
||||||
border = 1.0 - clamp(border, 0.0, 1.0); // Invert the rectangle
|
|
||||||
|
|
||||||
float mask = mix(selection, 1.0, 1.0 - ceil(original.a)); // Combine selection mask with area outside original
|
|
||||||
|
|
||||||
// Combine original and rotated image only when intersecting, otherwise just pure rotated image.
|
|
||||||
COLOR.rgb = mix(mix(original.rgb, col.rgb, col.a * border), col.rgb, mask);
|
|
||||||
COLOR.a = mix(original.a, 0.0, selection); // Remove alpha on the selected area
|
|
||||||
COLOR.a = mix(COLOR.a, 1.0, col.a * border); // Combine alpha of original image and rotated
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue