Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: GLSL Fragment Shader artifacts  (Read 2604 times)

0 Members and 1 Guest are viewing this topic.

AveryBibeau

  • Newbie
  • *
  • Posts: 7
    • View Profile
GLSL Fragment Shader artifacts
« on: July 30, 2013, 02:33:19 am »
I'm having trouble with eliminating artifacts from this fragment shader. I'm trying to simulate a radial blur/crepuscular rays effect and it works, except for the artifacts. I've found that when the RenderWindow's antialiasing is 0, they are most prominent, and they are still prominent until antialiasing is set to 8. In sf::Style::Fullscreen mode they are more prominent. Also, when the number of samples is higher than 65 (64 loop iterations), the shader goes haywire and displays nonsensical graphics. Finally, the artifacts have a slight blue tint to them even though the entire scene is just white with a black circle.

Here's the code for my fragment shader:
uniform float exposure;

uniform float decay;

uniform float density;

uniform float weight;

uniform vec2 lightPositionOnScreen;

uniform sampler2D firstPass;

const int NUM_SAMPLES = 65;

out vec4 color;

void main()
{      
        vec2 pixel = gl_FragCoord.xy;
       
        pixel.x /= 1920.0;
        pixel.y /= 1080.0;
       
        vec2 lpos = lightPositionOnScreen;
        lpos.x /= 1920.0;
        lpos.y /= 1080.0;

        vec2 deltaTextCoord = vec2( lpos.xy - pixel.xy );

        deltaTextCoord *= density / float(NUM_SAMPLES);

        float illuminationDecay = 1.0;

        for(int i=0; i < NUM_SAMPLES ; i++)
        {
                pixel += deltaTextCoord;

                vec4 sample = texture2D(firstPass, pixel);
                       
                sample *= illuminationDecay * weight;

                color += sample;
                       
                illuminationDecay *= decay;
        }
        color *= exposure;
}

And here is the code for the project:
#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
        sf::ContextSettings cs;
        cs.antialiasingLevel = 0;
        int scrHeight = sf::VideoMode::getDesktopMode().height;
        int scrWidth = sf::VideoMode::getDesktopMode().width;
        sf::RenderWindow Window(sf::VideoMode( scrWidth, scrHeight ), "SFML", sf::Style::Default, cs );
        Window.setVerticalSyncEnabled(true);

        sf::Clock clock;

        srand( time(NULL) );

        sf::Shader rayShader;

        rayShader.loadFromFile("data\\shaders\\radial.FRAG", sf::Shader::Fragment);
        rayShader.setParameter("exposure", 0.5f);
        rayShader.setParameter("decay", 0.97f);
        rayShader.setParameter("density", 0.97f);
        rayShader.setParameter("weight", 0.5f);

        sf::RenderTexture buffer1;
        sf::Sprite buffer1Sprite;
        buffer1.create( 1920, 1080 );
        buffer1.setSmooth( true );
        buffer1Sprite = sf::Sprite( buffer1.getTexture() );

        sf::RenderTexture buffer2;
        sf::Sprite buffer2Sprite;
        buffer2.create( 1920, 1080 );
        buffer2.setSmooth( true );
        buffer2Sprite = sf::Sprite( buffer2.getTexture() );

        sf::CircleShape test;
        test.setRadius( 40 );
        test.setOrigin( 40, 40 );
        test.setFillColor( sf::Color::Black );
        test.setPosition( 400, 400 );

        sf::RenderStates states;

        while( Window.isOpen() )
        {
                if( sf::Keyboard::isKeyPressed( sf::Keyboard::LControl ) && sf::Keyboard::isKeyPressed( sf::Keyboard::Q ) )
                        Window.close();
                sf::Time dt = clock.restart();

                sf::Event Event;
                while( Window.pollEvent( Event ) )
                {
                        if( Event.type == sf::Event::Closed )
                                Window.close();

                        if( Event.type == sf::Event::Resized )
                        {
                                sf::FloatRect visibleArea( 0, 0, Event.size.width, Event.size.height );
                                Window.setView( sf::View( visibleArea ) );
                        }
                }

                float x = sf::Mouse::getPosition(Window).x;
                float y = sf::Mouse::getPosition(Window).y;

                rayShader.setParameter("lightPositionOnScreen", sf::Vector2f(960.0, 540.0 ));
                rayShader.setParameter("firstPass", sf::Shader::CurrentTexture );
                rayShader.setParameter("exposure", 0.25f);
                rayShader.setParameter("decay", 0.97f);
                rayShader.setParameter("density", 0.97f);
                rayShader.setParameter("weight", 0.5f);
               
                states.shader = &rayShader;
                test.setPosition( x, y );
                bg.setColor( sf::Color::Black );
                buffer1.clear( sf::Color::Transparent );
                buffer1.draw( test );
                buffer1.display();

                buffer2.clear( sf::Color::Transparent );
                buffer2.draw( buffer1Sprite );
                buffer2.draw( buffer1Sprite, states );
                buffer2.display();
                Window.clear( sf::Color::White );

                Window.draw( buffer2Sprite );

                Window.display();
        }
}

Here are the artifacts in question:

AveryBibeau

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: GLSL Fragment Shader artifacts
« Reply #1 on: August 01, 2013, 06:29:55 am »
After updating my drivers (Intel HD4000), a few issues seem to be fixed. The radial shadow is no longer blue and the noise is less noticeable (but still prominent in dark areas). I haven't had access to an nVidia/AMD setup yet to test if it's just a problem with Intel drivers, but I can't see anything in my setup that is weird enough to cause this much trouble between specs.

 

anything