I have a shader that I am trying to use to create a dissolve effect. When I use the shader to draw a sprite which is 64x64 from a texture that is 64x64, it works seemingly perfectly. However, when I use the shader to draw a sprite which is 64x64 from a larger sprite sheet texture, it bugs out and the dissolve effect becomes stretched.
Here is what it looks like. 64x64 texture is on the left, 512x64 texture with 64x64 texture rect is on the right.
Here is my example code:
#include <SFML/Graphics.hpp>
int main()
{
sf::Clock mClock;
mClock.restart();
bool increase = true;
sf::Time dissolveTime = sf::Time::Zero;
sf::RenderWindow window(sf::VideoMode(800, 600), "My window");
sf::Shader dissolveShader;
dissolveShader.loadFromFile("Dissolve.frag", sf::Shader::Type::Fragment);
sf::Texture dissolveNoiseTexture;
dissolveNoiseTexture.loadFromFile("DissolveNoise.png");
dissolveShader.setUniform("noiseTexture", dissolveNoiseTexture);
sf::Texture normalTexture;
normalTexture.loadFromFile("Normal.png");
sf::Sprite normalSprite(normalTexture);
normalSprite.setOrigin(32.f, 32.f);
normalSprite.move(-20.f, 0.f);
sf::Texture spriteSheetTexture;
spriteSheetTexture.loadFromFile("SpriteSheet.png");
sf::Sprite spriteSheetSprite(spriteSheetTexture);
spriteSheetSprite.setTextureRect(sf::IntRect(0, 0, 64, 64));
spriteSheetSprite.setOrigin(32.f, 32.f);
spriteSheetSprite.move(20.f, 0.f);
sf::View view = window.getDefaultView();
view.zoom(0.1f);
view.setCenter(0.f, 0.f);
window.setView(view);
while (window.isOpen())
{
float dissolveAmount;
if (increase)
{
dissolveTime += mClock.getElapsedTime();
dissolveAmount = dissolveTime.asSeconds() / 3.f; //3 Seconds to dissolve up
if (dissolveAmount >= 1.f)
{
increase = false;
}
}
else
{
dissolveTime -= mClock.getElapsedTime();
dissolveAmount = dissolveTime.asSeconds() / 3.f; //3 Seconds to dissolve down
if (dissolveAmount <= 0.f)
{
increase = true;
}
}
dissolveShader.setUniform("dissolveAmount", dissolveAmount);
mClock.restart();
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear(sf::Color(128, 128, 128));
window.draw(normalSprite, &dissolveShader);
window.draw(spriteSheetSprite, &dissolveShader);
window.display();
}
return 0;
}
Here is the shader called Dissolve.frag that I am using:
uniform sampler2D source;
uniform sampler2D noiseTexture;
uniform float dissolveAmount;
void main()
{
vec2 textureCoordinates = gl_TexCoord[0].xy;
float edgeThickness = 0.1;
vec4 edgeColor = vec4(255, 0, 0, 100);
float noiseTiling = 0.8;
vec4 originalTexture = vec4(0.0);
originalTexture += texture2D(source, textureCoordinates);
vec4 dissolveNoise = vec4(0.0);
dissolveNoise += texture2D(noiseTexture, textureCoordinates * noiseTiling);
float remappedDissolve = dissolveAmount * (1.01 + edgeThickness) - edgeThickness;
vec4 step1 = step(remappedDissolve, dissolveNoise);
vec4 step2 = step(remappedDissolve + edgeThickness, dissolveNoise);
vec4 edge = step1 - step2;
edge.a = originalTexture.a;
vec4 edgeColorArea = edge * edgeColor;
originalTexture.a *= step1.r;
vec4 combinedColor = mix(originalTexture, edgeColorArea, edge.r);
gl_FragColor = combinedColor;
}
Here is links to the 64x64 image, 512x64 image, and the noise texture respectively:
https://i.imgur.com/H2fPEQd.pnghttps://i.imgur.com/ygFTifT.pnghttps://i.imgur.com/hn9kRoK.pngHow can I make it so that the shader works consistently on sprites regardless of their texture sizes? Shouldn't the size of the texture be irrelevant since it's not being rendered at all due to having a texture rect? I am new to GLSL so I don't understand how this works. I'm trying to get this shader to work by reverse engineering it from a Godot Tutorial.