2024-08-05 19:35:55 +00:00
|
|
|
shader_type canvas_item;
|
|
|
|
|
|
|
|
uniform float flip_param : hint_range(0.0, 1.0); // Parameter to control the flipping effect
|
|
|
|
uniform float dim_color_scale : hint_range(0.0, 1.0) = 0.4; // Control the dim of the back of the flipped texture
|
|
|
|
|
|
|
|
uniform float x_buffer = 2.0;//Increase these if you need your flip to stretch further
|
|
|
|
uniform float y_buffer = 2.0;
|
|
|
|
|
|
|
|
const vec2 scale = vec2(1, 1); // Scale of the texture
|
|
|
|
const vec2 start_flip_pos = vec2(1.0, 0.0); // Starting position of the flip
|
|
|
|
const vec2 end_flip_pos = vec2(0, 1); // Ending position of the flip
|
|
|
|
|
2025-02-10 18:04:27 +00:00
|
|
|
uniform vec2 atlas_offset = vec2(0.0); // Offset dans l'atlas
|
|
|
|
uniform vec2 atlas_size = vec2(1.0); // Taille de la région dans l'atlas
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-08-05 19:35:55 +00:00
|
|
|
// Function to calculate the vector from a line to a point
|
|
|
|
vec2 Line2point(vec2 linePoint, vec2 lineDire, vec2 point) {
|
|
|
|
lineDire = normalize(lineDire); // Normalize the direction of the line
|
|
|
|
return -linePoint - dot(-linePoint, lineDire) * lineDire - (-point - dot(-point, lineDire) * lineDire);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void vertex() {
|
|
|
|
//This increases the size of the uv so the sprite can be drawn 'out of bounds'
|
|
|
|
VERTEX.x *= x_buffer;
|
|
|
|
VERTEX.y *= y_buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Main fragment shader function
|
|
|
|
void fragment() {
|
|
|
|
|
|
|
|
// Resize the texture coordinates before the buffer
|
|
|
|
vec2 uv = vec2((UV.x - 0.5) * x_buffer + 0.5, (UV.y - 0.5) * y_buffer + 0.5);
|
2025-02-10 18:04:27 +00:00
|
|
|
uv = UV * atlas_size + atlas_offset;
|
2024-08-05 19:35:55 +00:00
|
|
|
|
|
|
|
// Interpolate flip position based on flip_param
|
|
|
|
vec2 flip_pos = mix(start_flip_pos, end_flip_pos, flip_param);
|
|
|
|
|
|
|
|
// Get the UV coordinates of the fragment
|
|
|
|
vec4 finalColor = vec4(0.0); // Initialize final color with transparent
|
|
|
|
float scale_min = scale.x / scale.y;
|
|
|
|
vec2 uv_max = vec2(scale_min, 1.0);
|
|
|
|
float trueScale;
|
|
|
|
|
|
|
|
// Adjust UV coordinates based on the scale
|
|
|
|
if (scale.y < scale.x) {
|
|
|
|
scale_min = scale.y / scale.x;
|
|
|
|
uv.y *= scale_min;
|
|
|
|
uv_max = vec2(1.0, scale_min);
|
|
|
|
trueScale = scale.x;
|
|
|
|
} else {
|
|
|
|
uv.x *= scale_min;
|
|
|
|
trueScale = scale.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sample the color from the texture at the given UV coordinates
|
|
|
|
COLOR = texture(TEXTURE, uv);
|
|
|
|
|
|
|
|
// Calculate the position in texture space
|
|
|
|
vec2 pPos = uv / trueScale;
|
|
|
|
|
|
|
|
// If the flip position is valid, can't be 0
|
|
|
|
if (flip_pos.x > -0.00001) {
|
|
|
|
vec2 left_bottom = vec2(0.0, uv_max.y / trueScale);
|
|
|
|
vec2 midpoint = (flip_pos - left_bottom) / 2.5 + left_bottom;
|
|
|
|
vec2 midDirect = normalize(vec2(-(flip_pos - left_bottom).y, (flip_pos - left_bottom).x));
|
|
|
|
|
|
|
|
// Calculate sharp point and direction vectors
|
|
|
|
vec2 sharpPoint = vec2(0.0, midpoint.y - midDirect.y / midDirect.x * midpoint.x);
|
|
|
|
vec2 flipEdgeDire = normalize(sharpPoint - flip_pos);
|
|
|
|
|
|
|
|
vec2 sharpPointB = vec2(midpoint.x - midDirect.x / midDirect.y * (midpoint - left_bottom).y, left_bottom.y);
|
|
|
|
vec2 flipEdgeDireB = normalize(sharpPointB - flip_pos);
|
|
|
|
|
|
|
|
float cyOriOff = min(length(flip_pos - left_bottom), 100.0);
|
|
|
|
float cyR = cyOriOff * 2.05 / PI;
|
|
|
|
|
|
|
|
vec2 midlineToP = Line2point(midpoint, midDirect, pPos);
|
|
|
|
|
|
|
|
vec2 cyOriToP = midlineToP - normalize(flip_pos - left_bottom) * cyOriOff;
|
|
|
|
vec2 cyEdgeToP = midlineToP - normalize(flip_pos - left_bottom) * (cyOriOff - cyR);
|
|
|
|
|
|
|
|
// Determine the location of the fragment relative to the flip
|
|
|
|
bool atBG = (cyOriToP.x <= -0.001);
|
|
|
|
bool atCy = (cyEdgeToP.x >= 0.0) && (cyOriToP.x <= 0.0);
|
|
|
|
bool atCyPage = false;
|
|
|
|
vec2 uvCy;
|
|
|
|
vec2 uvCyB;
|
|
|
|
|
|
|
|
// If the fragment is within the curvature area
|
|
|
|
if (atCy) {
|
|
|
|
vec2 cyOri = pPos - cyOriToP;
|
|
|
|
vec2 trueDis = cyR * asin(length(cyOriToP) / cyR) * normalize(cyOriToP);
|
|
|
|
vec2 truePos = cyOri + trueDis;
|
|
|
|
|
|
|
|
vec2 sideEdgeToTP = Line2point(flip_pos, flipEdgeDire, truePos);
|
|
|
|
vec2 BottomEdgeToTP = Line2point(flip_pos, flipEdgeDireB, truePos);
|
|
|
|
uvCyB = truePos * trueScale;
|
|
|
|
|
|
|
|
if ((BottomEdgeToTP.x < 0.0) && (sideEdgeToTP.y > 0.0)) {
|
|
|
|
atCyPage = true;
|
|
|
|
uvCy = vec2(length(sideEdgeToTP), left_bottom.y - length(BottomEdgeToTP)) * trueScale;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((uvCyB.x > uv_max.x) || (uvCyB.y > uv_max.y) || (uvCyB.x <= 0.0) || (uvCyB.y <= 0.0)) {
|
|
|
|
atCy = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the fragment is not within the background or curvature area, sample the color from the texture
|
|
|
|
if (!atBG && !atCy) {
|
|
|
|
finalColor = texture(TEXTURE, uv);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the fragment is within the curvature area, sample the color with curvature effect
|
|
|
|
if (atCy) {
|
|
|
|
finalColor = texture(TEXTURE, uvCyB);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the fragment is on the flipped page, adjust the color for the back of the page
|
|
|
|
if (atCyPage) {
|
|
|
|
vec4 cyPageColor = texture(TEXTURE, uvCy);
|
|
|
|
cyPageColor.rgb *= dim_color_scale; // Dim the color slightly
|
|
|
|
finalColor = mix(finalColor, cyPageColor, cyPageColor.a);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the final color
|
|
|
|
COLOR = finalColor;
|
|
|
|
}
|
|
|
|
}
|