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;
|
||||
render_mode unshaded;
|
||||
|
||||
uniform float angle;
|
||||
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;
|
||||
}
|
||||
#include "res://src/Shaders/Effects/Rotation/CommonRotation.gdshaderinc"
|
||||
|
||||
|
||||
void fragment() {
|
||||
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 pixelated_uv = floor(UV * tex_size) / (tex_size - 1.0); // Pixelate UV to fit resolution
|
||||
vec2 pivot = pivot_pixel / tex_size; // Normalize pivot position
|
||||
float ratio = tex_size.x / tex_size.y; // Resolution ratio
|
||||
|
||||
// Make a border to prevent stretching pixels on the edge
|
||||
vec2 border_uv = rotate(pixelated_uv, pivot, ratio);
|
||||
|
||||
// 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
|
||||
vec2 rotated_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);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ shader_type canvas_item;
|
|||
// SOFTWARE.
|
||||
//
|
||||
|
||||
#include "res://src/Shaders/Effects/Rotation/CommonRotation.gdshaderinc"
|
||||
|
||||
uniform int ScaleMultiplier : hint_range(0, 100) = 4;
|
||||
|
||||
// vertex compatibility #defines
|
||||
|
@ -40,9 +42,6 @@ uniform int ScaleMultiplier : hint_range(0, 100) = 4;
|
|||
// #define outsize vec4(OutputSize, 1.0 / OutputSize)
|
||||
|
||||
// Pixelorama-specific uniforms
|
||||
uniform float angle;
|
||||
uniform sampler2D selection_tex;
|
||||
uniform vec2 pivot_pixel;
|
||||
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()
|
||||
{
|
||||
vec4 original = texture(TEXTURE, UV);
|
||||
float selection = texture(selection_tex, UV).a;
|
||||
vec2 size = 1.0 / TEXTURE_PIXEL_SIZE;
|
||||
vec2 pivot = pivot_pixel / size; // Normalize pivot position
|
||||
float ratio = size.x / size.y; // Resolution ratio
|
||||
|
@ -321,29 +302,8 @@ void fragment()
|
|||
else {
|
||||
rotated_uv = rotate(UV, pivot, ratio);
|
||||
}
|
||||
vec4 c;
|
||||
c = scale(TEXTURE, rotated_uv, TEXTURE_PIXEL_SIZE);
|
||||
vec4 c = scale(TEXTURE, rotated_uv, TEXTURE_PIXEL_SIZE);
|
||||
|
||||
// Taken from NearestNeighbour shader
|
||||
c.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 - 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;
|
||||
// Pixelorama edit
|
||||
COLOR = mix_rotated_and_original(c, original, UV, rotated_uv, TEXTURE_PIXEL_SIZE);
|
||||
}
|
|
@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
|
||||
shader_type canvas_item;
|
||||
|
||||
#include "res://src/Shaders/Effects/Rotation/CommonRotation.gdshaderinc"
|
||||
//enables 2:1 slopes. otherwise only uses 45 degree slopes
|
||||
#define SLOPE
|
||||
//cleans up small detail slope transitions (if SLOPE is enabled)
|
||||
|
@ -45,9 +45,6 @@ uniform float similarThreshold = 0.0;
|
|||
uniform float lineWidth = 1.0;
|
||||
|
||||
// Edited for Pixelorama
|
||||
uniform float angle;
|
||||
uniform sampler2D selection_tex;
|
||||
uniform vec2 pivot_pixel;
|
||||
uniform bool preview = false;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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() {
|
||||
vec2 size = 1.0/TEXTURE_PIXEL_SIZE+0.0001; //fix for some sort of rounding error
|
||||
// Pixelorama edit
|
||||
vec4 original = texture(TEXTURE, UV);
|
||||
float selection = texture(selection_tex, UV).a;
|
||||
vec2 pivot = pivot_pixel / size; // Normalize pivot position
|
||||
float ratio = size.x / size.y; // Resolution ratio
|
||||
vec2 pixelated_uv = floor(UV * size) / (size - 1.0); // Pixelate UV to fit resolutio
|
||||
|
@ -360,24 +339,6 @@ void fragment() {
|
|||
col = u_col;
|
||||
}
|
||||
|
||||
// Pixelorama edit, taken from NearestNeighbour shader
|
||||
col.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 - 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
|
||||
// Pixelorama edit
|
||||
COLOR = mix_rotated_and_original(col, original, UV, rotated_uv, TEXTURE_PIXEL_SIZE);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue