Diamond-based Screen Transition
A transition shader drawn from this article by Timm[ie] Wong @DDRKirbyISQ. Permission was given by this individual for this post. The article explains more in depth and similar versions of this shader. Animating the shader parameter “progress” creates the transition effect. I have found that a tween using trans_cubic and ease_out looks pretty nice. Changing the final line from > to < will reverse the transition effect.
tween.interpolate_property(mymaterial, “shader_param/progress”, 1, 0, 1.5, Tween.TRANS_CUBIC, Tween.EASE_OUT)
Shader code
shader_type canvas_item;
// Ranges from 0 to 1 over the course of the transition.
// We use this to actually animate the shader.
uniform float progress : hint_range(0, 1);
// Size of each diamond, in pixels.
uniform float diamondPixelSize = 10f;
void fragment() {
float xFraction = fract(FRAGCOORD.x / diamondPixelSize);
float yFraction = fract(FRAGCOORD.y / diamondPixelSize);
float xDistance = abs(xFraction - 0.5);
float yDistance = abs(yFraction - 0.5);
if (xDistance + yDistance + UV.x + UV.y > progress * 4f) {
discard;
}
}



Does anyone know how to make it look pixelized?
you can just put it behind a low-res viewport
A slightly more optimized version (avoiding shader-unfriendly if statement):
See https://godotshaders.com/shader/optimize-your-shaders/
shader_type canvas_item; // Ranges from 0 to 1 over the course of the transition. // We use this to actually animate the shader. uniform float progress : hint_range(0, 1); // Size of each diamond, in pixels. uniform float diamondPixelSize = 10f; float when_lt(float x, float y) { return max(sign(y - x), 0.0); } void fragment() { float xFraction = fract(FRAGCOORD.x / diamondPixelSize); float yFraction = fract(FRAGCOORD.y / diamondPixelSize); float xDistance = abs(xFraction - 0.5); float yDistance = abs(yFraction - 0.5); COLOR.a *= when_lt(xDistance + yDistance + UV.x + UV.y, progress * 4f); }how to make it square not diamond?
Heck yeah! Fancy screen transition! super easy to use and animate, too!
For Godot 4
transition.gdshader
shader_type canvas_item; // Ranges from 0 to 1 over the course of the transition. // We use this to actually animate the shader. uniform float progress : hint_range(0, 1); // Size of each diamond, in pixels. uniform float diamondPixelSize = 10.0; float when_lt(float x, float y) { return max(sign(y - x), 0.0); } void fragment() { float xFraction = fract(FRAGCOORD.x / diamondPixelSize); float yFraction = fract(FRAGCOORD.y / diamondPixelSize); float xDistance = abs(xFraction - 0.5); float yDistance = abs(yFraction - 0.5); COLOR.a *= when_lt(xDistance + yDistance + UV.x + UV.y, progress * 4.0); }and de transition scene with a ColorRect
Hi! I added parameters to allow changing the angle & anchor point of the transition.
Uses the Godot 4.0 version that has the optimizations in it.
Note: probably not 100% accurate but it works.
Have fun!
shader_type canvas_item; // Ranges from 0 to 1 over the course of the transition. // We use this to actually animate the shader. uniform float progress : hint_range(0, 1); uniform float multiplier : hint_range(1, 10) = 3; uniform float angle : hint_range(0, 360) = 0.0; // anchor point of the transition (best anchor point result is 0.5, 0.5) uniform vec2 anchor = vec2(0.5, 0.5); // use this to increase the distance from the anchor point uniform float anchorOffset = 1.0; // Size of each diamond, in pixels. uniform float diamondPixelSize = 10.0; float when_lt(float x, float y) { return max(sign(y - x), 0.0); } void fragment() { float xFraction = fract(FRAGCOORD.x / diamondPixelSize); float yFraction = fract(FRAGCOORD.y / diamondPixelSize); float xDistance = abs(xFraction - 0.5); float yDistance = abs(yFraction - 0.5); COLOR.a *= when_lt(xDistance + yDistance + cos(radians(angle)) * (UV.x - anchor.x) + sin(radians(angle)) * (UV.y - anchor.y), (-anchorOffset + progress * multiplier)); }This is a version that will work in old android phones
shader_type canvas_item; uniform float uv1_progress : hint_range(0, 1); uniform float diamondPixelSize = 60.0f; uniform bool fadeOut = false; void fragment() { float xFraction = fract(FRAGCOORD.x / diamondPixelSize); float yFraction = fract(FRAGCOORD.y / diamondPixelSize); float xDistance = abs(xFraction - 0.5); float yDistance = abs(yFraction - 0.5); float alpha = 1.0; if (fadeOut) { if (xDistance + yDistance + UV.x + UV.y < uv1_progress * 4.0f) { alpha = 0.0; } } else { if (xDistance + yDistance + UV.x + UV.y > uv1_progress * 4.0f) { alpha = 0.0; } } COLOR = texture(TEXTURE, UV) * vec4(0.0, 0.0, 0.0, alpha); }why does
uniform float diamondPixelSize = 10f;
not work?