Added a few more transition effects.

This commit is contained in:
Kai Blaschke
2023-11-02 23:14:31 +01:00
parent c9b0ce0c2c
commit e99ae49c49
7 changed files with 203 additions and 13 deletions

View File

@ -1,6 +1,10 @@
set(TRANSITION_SHADER_FILES
TransitionShaders/TransitionShaderBuiltInCircleGlsl330.frag
TransitionShaders/TransitionShaderBuiltInPlasmaGlsl330.frag
TransitionShaders/TransitionShaderBuiltInSimpleBlendGlsl330.frag
TransitionShaders/TransitionShaderBuiltInSweepGlsl330.frag
TransitionShaders/TransitionShaderBuiltInWarpGlsl330.frag
TransitionShaders/TransitionShaderBuiltInZoomBlurGlsl330.frag
TransitionShaders/TransitionVertexShaderGlsl330.vert
TransitionShaders/TransitionShaderHeaderGlsl330.frag
TransitionShaders/TransitionShaderMainGlsl330.frag

View File

@ -2,11 +2,17 @@
#include "BuiltInTransitionsResources.hpp"
#include <iostream>
TransitionShaderManager::TransitionShaderManager()
: m_mersenneTwister(m_randomDevice())
: m_transitionShaders({CompileTransitionShader(kTransitionShaderBuiltInCircleGlsl330),
CompileTransitionShader(kTransitionShaderBuiltInPlasmaGlsl330),
CompileTransitionShader(kTransitionShaderBuiltInSimpleBlendGlsl330),
CompileTransitionShader(kTransitionShaderBuiltInSweepGlsl330),
CompileTransitionShader(kTransitionShaderBuiltInWarpGlsl330),
CompileTransitionShader(kTransitionShaderBuiltInZoomBlurGlsl330)})
, m_mersenneTwister(m_randomDevice())
{
m_transitionShaders.push_back(CompileTransitionShader(kTransitionShaderBuiltInSimpleBlendGlsl330));
m_transitionShaders.push_back(CompileTransitionShader(kTransitionShaderBuiltInSweepGlsl330));
}
auto TransitionShaderManager::RandomTransition() -> std::shared_ptr<Shader>
@ -22,12 +28,12 @@ auto TransitionShaderManager::RandomTransition() -> std::shared_ptr<Shader>
auto TransitionShaderManager::CompileTransitionShader(const std::string& shaderBodyCode) -> std::shared_ptr<Shader>
{
#if USE_GLES
std::string versionHeader{"#version 300 es\n\n"};
constexpr char versionHeader[] = "#version 300 es\n\n";
#else
std::string versionHeader{"#version 330\n\n"};
constexpr char versionHeader[] = "#version 330\n\n";
#endif
std::string fragmentShaderSource(versionHeader);
std::string fragmentShaderSource(static_cast<const char*>(versionHeader));
fragmentShaderSource.append(kTransitionShaderHeaderGlsl330);
fragmentShaderSource.append("\n");
fragmentShaderSource.append(shaderBodyCode);
@ -37,7 +43,7 @@ auto TransitionShaderManager::CompileTransitionShader(const std::string& shaderB
try
{
auto transitionShader = std::make_shared<Shader>();
transitionShader->CompileProgram(versionHeader + kTransitionVertexShaderGlsl330, fragmentShaderSource);
transitionShader->CompileProgram(static_cast<const char*>(versionHeader) + kTransitionVertexShaderGlsl330, fragmentShaderSource);
return transitionShader;
}
catch (const ShaderException& ex)

View File

@ -0,0 +1,52 @@
// Circular blend with soft edge, inside-out or outside-in
// Source: https://www.shadertoy.com/view/NdGfzG
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord / iResolution.xy;
float aspect = iResolution.y / iResolution.x;
// Randomize direction and edge width
float inOrOut = mod(float(iRandStatic.x) * .01, 2.);
float progress;
vec3 imgInner, imgOuter;
if (inOrOut < 1.)
{
imgInner = texture(iChannel0, uv).xyz;
imgOuter = texture(iChannel1, uv).xyz;
progress = iProgressCosine;
}
else
{
imgOuter = texture(iChannel0, uv).xyz;
imgInner = texture(iChannel1, uv).xyz;
progress = 1. - iProgressCosine;
}
float blendWidth = mod(float(iRandStatic.y) * .001, .1) + .05;
progress = progress * (1. + blendWidth) - blendWidth;
// Blending
vec2 center = vec2(.5);
float rad = sqrt(center.x / aspect * center.x / aspect + center.y * center.y) * progress;
float rad2 = rad + blendWidth;
float r1 = sqrt((uv.x - center.x) / aspect * (uv.x - center.x) / aspect + (uv.y - center.y) * (uv.y - center.y));
vec3 col;
if (r1 > rad2)
{
col = imgInner;
}
else if (r1 > rad)
{
float v1=(r1-rad)/(rad2-rad);
float v2 = 1.0 - v1;
col = v1 * imgInner + v2 * imgOuter;
}
else
{
col = imgOuter;
}
// Output to screen
fragColor = vec4(col, 1.0);
}

View File

@ -0,0 +1,55 @@
// Fractal, plasma-like transition effect with random scales and noise seeds.
// Source: https://www.shadertoy.com/view/MstBzf
float sinNoise(vec2 uv)
{
return fract(abs(sin(uv.x * 180.0 + uv.y * 3077.0) * (float(iRandStatic.x) * .001)));
}
float valueNoise(vec2 uv, float scale)
{
vec2 luv = fract(uv * scale);
vec2 luvs = smoothstep(0.0, 1.0, fract(uv * scale));
vec2 id = floor(uv * scale);
float tl = sinNoise(id + vec2(0.0, 1.0));
float tr = sinNoise(id + vec2(1.0, 1.0));
float t = mix(tl, tr, luvs.x);
float bl = sinNoise(id + vec2(0.0, 0.0));
float br = sinNoise(id + vec2(1.0, 0.0));
float b = mix(bl, br, luvs.x);
return mix(b, t, luvs.y) * 2.0 - 1.0;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
vec3 imgOld = texture(iChannel0, uv).xyz;
vec3 imgNew = texture(iChannel1, uv).xyz;
uv.y /= iResolution.x/iResolution.y;
float sinN = sinNoise(uv);
float scale = mod(float(iRandStatic.y) * .01, 7.) * 4. + 4.;
float fractValue = 0.;
float amp = 1.;
for(int i = 0; i < 16; i++)
{
fractValue += valueNoise(uv, float(i + 1) * scale) * amp;
amp *= .5;
}
fractValue *= .25;
fractValue += .5;
float cutoff = smoothstep(iProgressCosine + .1, iProgressCosine - .1, fractValue);
vec3 col = mix(imgOld, imgNew, cutoff);
// Output to screen
fragColor = vec4(col, 1.);
}

View File

@ -2,12 +2,9 @@
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord / iResolution.xy;
vec3 imgOld = texture(iChannel0, uv).xyz;
vec3 imgNew = texture(iChannel1, uv).xyz;
// Blending
vec3 col = vec3((1.0 - iProgressCosine) * imgOld + iProgressCosine * imgNew);
// Output to screen
fragColor = vec4(col, 1.0);
fragColor = vec4(mix(texture(iChannel0, uv).xyz,
texture(iChannel1, uv).xyz,
iProgressCosine), 1.0);
}

View File

@ -0,0 +1,20 @@
// Horizontal/vertical warp effect
// Source: https://www.shadertoy.com/view/ssj3Dh
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord / iResolution.xy;
vec3 imgOld = texture(iChannel0, uv).xyz;
vec3 imgNew = texture(iChannel1, uv).xyz;
// Randomize direction
float direction = mod(float(iRandStatic.x) * .01, 4.);
float coord;
if (direction < 1.) coord = uv.x;
else if (direction < 2.) coord = 1. - uv.x;
else if (direction < 3.) coord = uv.y;
else coord = 1. - uv.y;
// Blending
float x = smoothstep(.0,1.0,(iProgressCosine * 2.0 + coord - 1.0));
fragColor = mix(texture(iChannel0, (uv - .5) * (1. - x) + .5), texture(iChannel1, (uv - .5) * x + .5), x);
}

View File

@ -0,0 +1,56 @@
const float strength = 0.3;
const float PI = 3.141592653589793;
float Linear_ease(in float begin, in float change, in float duration, in float time) {
return change * time / duration + begin;
}
float Exponential_easeInOut(in float begin, in float change, in float duration, in float time) {
if (time == 0.0)
return begin;
else if (time == duration)
return begin + change;
time = time / (duration / 2.0);
if (time < 1.0)
return change / 2.0 * pow(2.0, 10.0 * (time - 1.0)) + begin;
return change / 2.0 * (-pow(2.0, -10.0 * (time - 1.0)) + 2.0) + begin;
}
float Sinusoidal_easeInOut(in float begin, in float change, in float duration, in float time) {
return -change / 2.0 * (cos(PI * time / duration) - 1.0) + begin;
}
float random(in vec3 scale, in float seed) {
return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
}
vec3 crossFade(in vec2 uv, in float dissolve) {
return mix(texture(iChannel0, uv).rgb, texture(iChannel1, uv).rgb, dissolve);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
vec2 texCoord = fragCoord.xy / iResolution.xy;
float progress = iProgressCosine;
// Linear interpolate center across center half of the image
vec2 center = vec2(Linear_ease(0.5, 0.0, 1.0, progress),0.5);
float dissolve = Exponential_easeInOut(0.0, 1.0, 1.0, progress);
// Mirrored sinusoidal loop. 0->strength then strength->0
float strength = Sinusoidal_easeInOut(0.0, strength, 0.5, progress);
vec3 color = vec3(0.0);
float total = 0.0;
vec2 toCenter = center - texCoord;
/* randomize the lookup values to hide the fixed number of samples */
float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0)*0.5;
for (float t = 0.0; t <= 20.0; t++) {
float percent = (t + offset) / 20.0;
float weight = 1.0 * (percent - percent * percent);
color += crossFade(texCoord + toCenter * percent * strength, dissolve) * weight;
total += weight;
}
fragColor = vec4(color / total, 1.0);
}