There are two purple tiles generating heat. The heat shader is working fine but the entire screen now has unwanted artifacts. I've taken the entire windows RenderTexture and applied the shader on a small sub section of the bitmap per tile.
Does anyone recognize these symptoms? Shader and code below:
#version 130
uniform sampler2D currentTexture; // Our render texture
uniform sampler2D distortionMapTexture; // Our heat distortion map texture
uniform float time; // Time used to scroll the distortion map
uniform float distortionFactor; // Factor used to control severity of the effect
uniform float riseFactor; // Factor used to control how fast air rises
uniform float x;
uniform float y;
uniform float w;
uniform float h;
void main()
{
vec4 alpha = vec4(0.0f,0.0f,0.0f,0.0f);
vec2 distortionMapCoordinate = gl_TexCoord[0].st;
//distortionMapCoordinate.y = 1.0f - distortionMapCoordinate.y;
vec2 size = textureSize(currentTexture,0);
vec2 screenCoord = vec2(gl_TexCoord[0].s, (1.0f-gl_TexCoord[0].t)) * size;
if(!(screenCoord.x >= x && screenCoord.x <= x + w && screenCoord.y >= y && screenCoord.y <= y + h)) {
gl_FragColor = gl_Color * texture2D(currentTexture, gl_TexCoord[0].st);
return;
} else {
// We use the time value to scroll our distortion texture upwards
// Since we enabled texture repeating, OpenGL takes care of
// coordinates that lie outside of [0, 1] by discarding
// the integer part and keeping the fractional part
// Basically performing a "floating point modulo 1"
// 1.1 = 0.1, 2.4 = 0.4, 10.3 = 0.3 etc.
distortionMapCoordinate.t -= time * riseFactor;
vec4 distortionMapValue = texture2D(distortionMapTexture, distortionMapCoordinate);
// The values are normalized by OpenGL to lie in the range [0, 1]
// We want negative offsets too, so we subtract 0.5 and multiply by 2
// We end up with values in the range [-1, 1]
vec2 distortionPositionOffset = distortionMapValue.xy;
distortionPositionOffset -= vec2(0.5f, 0.5f);
distortionPositionOffset *= 2.f;
// The factor scales the offset and thus controls the severity
distortionPositionOffset *= distortionFactor;
// The latter 2 channels of the texture are unused... be creative
vec2 distortionUnused = distortionMapValue.zw;
// Since we all know that hot air rises and cools,
// the effect loses its severity the higher up we get
// We use the t (a.k.a. y) texture coordinate of the original texture
// to tell us how "high up" we are and damp accordingly
// Remember, OpenGL 0 is at the bottom
distortionPositionOffset *= ((y+h)-screenCoord.y )/ (y+h);
vec2 distortedTextureCoordinate = gl_TexCoord[0].st + distortionPositionOffset;
gl_FragColor = gl_Color * texture2D(currentTexture, distortedTextureCoordinate);
}
}
engine:
/*
Post processing shaders
*/
sf::RenderTexture &postprocessing = *ENGINE.GetPostProcessingBuffer();
sf::Sprite distortionPost;
distortionPost.setTexture(postprocessing.getTexture());
heatShader.setUniform("time", totalTime);
heatShader.setUniform("distortionFactor", 0.1f);
heatShader.setUniform("riseFactor", 0.2f);
heatShader.setUniform("w", tile->GetWidth()-8.f);
heatShader.setUniform("h", tile->GetHeight()-8.f);
while (field->GetNextTile(tile)) {
if (tile->GetState() == TileState::PURPLE) {
heatShader.setUniform("x", tile->getPosition().x+4.f);
heatShader.setUniform("y", tile->getPosition().y);
LayeredDrawable* bake = new LayeredDrawable(sf::Sprite(distortionPost));
bake->SetShader(&heatShader);
ENGINE.Draw(bake);
delete bake;
}
}
Where post processing buffer is just an sf::RenderTexture I've been baking the scene into. Add the end of the call the window Displays() this texture.