Recently, I was able to create a crepuscular ray shader with the help of a few individuals. However, when it comes to creating a mask for this effect, I'm experiencing difficulties getting the rays to bleed past the edges of the solid sprite overlay in front of the mask.
I would assume that it would be correct to draw the overlay sprite within the RenderTexture (renderTexture variable), but after scouring through the SFML 2.0 Documentation, I was unable to find a way to pass the shader specifically to a texture within the RenderTexture. If anyone here knows of a solution to this problem, please feel free to share it!
main.cpp:
#include <SFML\Graphics.hpp>
#include <SFML\System.hpp>
#include <SFML\Window.hpp>
#include <iostream>
void main()
{
sf::RenderWindow _window(sf::VideoMode(800, 480, 32), "Lighting Test");
sf::RenderTexture renderTexture;
sf::RenderStates renderState;
_window.setFramerateLimit(60);
renderTexture.create(_window.getSize().x, _window.getSize().y);
sf::Shader lightingShader;
sf::Texture texture;
texture.loadFromFile("image.png");
sf::Sprite sprite = sf::Sprite(texture);
sf::Sprite sprite2 = sf::Sprite(texture);
//sprite.setTexture(texture);
sf::Texture backgroundTexture;
backgroundTexture.loadFromFile("light.png");
sf::Sprite background = sf::Sprite(backgroundTexture);
//background.setTexture(backgroundTexture);
while (_window.isOpen())
{
int x = sf::Mouse::getPosition(_window).x;
int y = sf::Mouse::getPosition(_window).y;
sf::Event sfEvent;
while(_window.pollEvent(sfEvent))
{
switch(sfEvent.type)
{
case sf::Event::Closed: _window.close();
break;
case sf::Event::KeyPressed:
if(sfEvent.key.code==sf::Keyboard::Q) _window.close();
break;
default: break;
}
}
lightingShader.loadFromFile("lightingShader.frag", sf::Shader::Type::Fragment);
lightingShader.setParameter("exposure", 0.008f);
lightingShader.setParameter("decay", 0.97f);
lightingShader.setParameter("density", 0.97f);
lightingShader.setParameter("weight", 5.5f);
lightingShader.setParameter("lightPositionOnScreen", sf::Vector2f(0.5f, 0.5f));
//lightingShader.setParameter("texture", sf::Shader::CurrentTexture);
renderState.shader = &lightingShader;
sprite.setPosition(x - 504, y - 360);
//sprite2.setPosition((x - 504) * 0.5, (y - 360));
renderTexture.clear();
renderTexture.draw(background);
//renderTexture.draw(sprite2);
renderTexture.draw(sprite);
renderTexture.display();
_window.clear();
_window.draw(sf::Sprite(renderTexture.getTexture()), renderState); //<-- Shader Mask.
_window.draw(sprite); //<-- Solid Sprite Overlay
_window.display();
}
}
lightingShader.frag:
uniform float exposure;
uniform float decay;
uniform float density;
uniform float weight;
uniform vec2 lightPositionOnScreen;
uniform sampler2D texture;
const int NUM_SAMPLES = 100;
void main()
{
vec2 deltaTextCoord = vec2( gl_TexCoord[0].xy - lightPositionOnScreen.xy);
vec2 textCoord = gl_TexCoord[0].xy;
deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * density;
float illuminationDecay = 1.0;
for(int i=0; i < NUM_SAMPLES ; i++)
{
textCoord -= deltaTextCoord;
vec4 sample = texture2D(texture, textCoord);
sample *= illuminationDecay * weight;
gl_FragColor += sample;
illuminationDecay *= decay;
}
gl_FragColor *= exposure;
}
My OS is Windows 7, and I'm currently using the SFML 2.0 Release Candidate.