I'm just getting more involved with shaders and SFML and really fell in love with this effect on shadertoy.com which is perfect for my explosions.
https://www.shadertoy.com/view/llj3Dz#Now shader code is new to me but I took a stab at converting it. The effect runs alright, but the source texture is upside down, mirrored and only shows half the screen.
Really starting to see the power of shaders now and thought this would be a good intro to learning more. Any pointers on what I've done wrong would be great.
Here's the test image:
and the result from my testing code:
Here's the .cpp
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window (sf::VideoMode(1920, 1080), "SFML window");
window.setVerticalSyncEnabled (true);
window.setKeyRepeatEnabled (false);
sf::Texture bgt;
bgt.loadFromFile("testcard.jpg");
sf::Sprite bgs(bgt);
sf::Shader shader;
shader.loadFromFile("shockwave.frag", sf::Shader::Type::Fragment);
sf::RenderStates states;
states.shader = &shader;
sf::Clock clock;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
window.close();
}
shader.setParameter("source", sf::Shader::CurrentTexture);
shader.setParameter("sourceSize", sf::Vector2f(1920.f, 1080.f));
shader.setParameter("time", clock.getElapsedTime().asSeconds());
window .clear ();
window .draw (bgs, states);
window .display();
}
return EXIT_SUCCESS;
}
...and my attempt to change the fragment shader from shadertoy format.
uniform sampler2D source;
uniform vec2 sourceSize;
uniform float time;
void main( void )
{
//Sawtooth function to pulse from centre.
float offset = (time- floor(time)) / time;
float CurrentTime = (time)*(offset);
vec3 WaveParams = vec3(10.0, 0.8, 0.1 );
float ratio = sourceSize.y / sourceSize.x;
vec2 WaveCentre = vec2(0.5, 0.5);
WaveCentre.y *= ratio;
vec2 texCoord = gl_FragCoord.xy / sourceSize.xy;
texCoord.y *= ratio;
float Dist = distance(texCoord, WaveCentre);
vec4 Color = texture2D(source, texCoord);
//Only distort the pixels within the parameter distance from the centre
if ( (Dist <= ((CurrentTime) + (WaveParams.z))) &&
(Dist >= ((CurrentTime) - (WaveParams.z))))
{
//The pixel offset distance based on the input parameters
float Diff = (Dist - CurrentTime);
float ScaleDiff = (1.0 - pow(abs(Diff * WaveParams.x), WaveParams.y));
float DiffTime = (Diff * ScaleDiff);
//The direction of the distortion
vec2 DiffTexCoord = normalize(texCoord - WaveCentre);
//Perform the distortion and reduce the effect over time
texCoord += ((DiffTexCoord * DiffTime) / (CurrentTime * Dist * 40.0));
Color = texture2D(source, texCoord);
//Blow out the color and reduce the effect over time
Color += (Color * ScaleDiff) / (CurrentTime * Dist * 40.0);
}
gl_FragColor = Color;
}