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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - degski

Pages: 1 [2]
16
It's fine if you have already planned out what the maximum should be and it's for your own specific use.

Why do you not just use a larger number to begin with?  ;D

I've increased it to 256 in the top post. One could just as well put 4k, and be able to blur a full screen (in 4k  HD), but I doubt that is going to be practical as there are already serious running time demands at much smaller values (like 8 or 16), see below.

The pixelation issue, we discussed earlier, was due to not calculating the decimal size of a pixel correctly, and as a consequence only every second pixel got processed. This is also corrected in the top post.

What a would like to ask you with your deep understanding of the matter at hand, whether you see any means of optimising the constructor for speed from where it stands at the moment. At the moment doing this dynamically seems to be out of the question as the constructor takes quite a number of frames (at 1/ 60) to run.

17
Graphics / Re: Shaded Text [was Blur Shader]
« on: March 03, 2016, 05:35:27 am »
If you attempt to use a radius of 129, this shader won't be too happy.

Correct! One could simply put a bigger number.

This issue was actually already pointed out in the source of the shader http://www.cocos2d-x.org/wiki/User_Tutorial-RenderTexture_Plus_Blur.

There a plenty of those kind of hard-coded numbers in the STL and f.e. Boost as well. I don't see the issue.

18
Graphics / Re: Shaded Text [was Blur Shader]
« on: March 02, 2016, 08:37:25 am »
The number of weights is the number of samples. This is hard-coded (as 128) in the shader.

Well, yes and no, it is set at 128 (that's a radius in pixels) just to placate the GLSL-compiler, as it apparently does not accept float[], while the code should be usable with different radii. Normal values would be more like 4, 8 or maybe 12... As the c-array decays into a pointer, again apparently, and the blur_radius controls both the size of the weights and the loop in the shader this should not be a problem ASAICS, as the values that are accessed (through the pointer) well and truely exist.

19
General discussions / Re: SFML 3D logo
« on: March 01, 2016, 01:25:50 pm »
I worked on a very basic 3D logo (using Blender) for a project and I came up this:

Forgive me for asking, but why a 3D-Logo for a 2D-Library? I think it's odd.

20
Graphics / Re: Shaded Text [was Blur Shader]
« on: March 01, 2016, 07:48:35 am »
I can't try your code as I don't have access to setUniform() (and therefore passing arrays etc.) yet.

It's in the latest developments.

I think that the pixelation is due to the resolution of your sample. If you want to reduce the pixelation, you'll need more weights.

Somehow the forum seems to enlarge the attached image with a factor higher than 100% (i.e. what you see is bigger than what I see on my laptop locally), when you click on it. On my laptop with Full HD screen, the text size is considerably smaller, the pixelation is less. I used M$ Paint and print-screen to capture the image, this might be a contributing factor.

What happens when you choose a radius greater than the number of weights?

The constructor takes care of setting up the correct weights vector for the radius chosen.

21
Graphics / Re: Blur Shader
« on: February 29, 2016, 01:09:06 pm »
Have been looking at this a bit lot more, and I've got something working. I would like to ask for your comments, suggestions and/or improvements.

The fragment shader is now as follows:

uniform sampler2D texture;

uniform vec2 pixel_size;
uniform int blur_radius;
uniform float[128] weights;
uniform vec2 direction;

void main ( ) {

        const vec2 texture_coordinates = gl_TexCoord [ 0 ].xy;

    gl_FragColor = texture2D ( texture, texture_coordinates ) * weights [ 0 ];

    for ( int i = 1; i < blur_radius; ++i ) {

        const vec2 offset = vec2 ( float ( i ) * pixel_size.x * direction.x, float ( i ) * pixel_size.y * direction.y );

        gl_FragColor += texture2D ( texture, texture_coordinates + offset ) * weights [ i ];
        gl_FragColor += texture2D ( texture, texture_coordinates - offset ) * weights [ i ];
    }
}
 


And the ShadedText class (and a main) is like this:

class ShadedText {

        sf::Text m_text;
        sf::RenderTexture m_text_render_texture;
        sf::Sprite m_text_sprite;

        const std::vector<float> m_gaussian_weights;

        sf::RenderStates m_render_state;
        sf::Shader m_shader;

        sf::RenderTexture m_horz_render_texture;
        sf::RenderTexture m_vert_render_texture;

        sf::Sprite m_horz_sprite;
        sf::Sprite m_final_sprite;

        std::vector<float> gaussianWeights ( const std::size_t size_ ) const {

                // http://www.cocos2d-x.org/wiki/User_Tutorial-RenderTexture_Plus_Blur

                std::vector<float> gaussian_weights ( size_ );

                double nill = 1.0;

                for ( std::size_t i = 1; i < size_; ++i ) {

                        const double x =  ( double ) i / ( double ) ( size_ - 1 ), gwi = 1.196826841204297942 / ( double ) size_ * std::exp ( -x * x * 4.5 );

                        gaussian_weights [ i ] = gwi;
                        nill -= 2.0 * gwi;
                }

                gaussian_weights [ 0 ] = nill;

                return gaussian_weights;
        }

public:

        ShadedText ( const std::wstring &text_, const sf::Font &font_, const std::size_t points_, const std::size_t radius_, const sf::Vector2f &position_ = sf::Vector2f ( 0.0f, 0.0f ) ) :

                m_text ( text_, font_, points_ ),
                m_gaussian_weights ( gaussianWeights ( radius_ ) ) {

                const float dispx = 12.0f, dispy = 13.0f;

                // Finish setting text object...

                m_text.setFillColor ( sf::Color::Black );
                m_text.setOrigin ( m_text.getLocalBounds ( ).left - radius_, m_text.getLocalBounds ( ).top - radius_ ); // Otherwise text is not properly positioned in the rendertexture

                // Init render texture...

                m_text_render_texture.create ( m_text.getLocalBounds ( ).width + 2.0f * radius_ + dispx, m_text.getLocalBounds ( ).height + 2.0f * radius_ + dispx );
                m_text_render_texture.clear ( sf::Color::White );
                m_text_render_texture.setSmooth ( true );

                m_text.setPosition ( dispx, dispy );

                m_text_render_texture.draw ( m_text );
                m_text_render_texture.display ( );

                // 1. Create text sprite...

                m_text_sprite.setTexture ( m_text_render_texture.getTexture ( ) );

                // Load shader...

                if ( not ( m_shader.loadFromFile ( "c:/tmp/resources/blur.frag", sf::Shader::Fragment ) ) ) {

                        exit ( EXIT_FAILURE );
                }

                // Set shader parameters...

                m_shader.setUniform ( "pixel_size", sf::Vector2f ( 2.0f / m_text_sprite.getLocalBounds ( ).width, 2.0f / m_text_sprite.getLocalBounds ( ).height ) );
                m_shader.setUniform ( "blur_radius", ( int ) radius_ );
                m_shader.setUniformArray ( "weights", m_gaussian_weights.data ( ), radius_ );

                m_render_state.shader = &m_shader;

                // 2. Draw it to a RenderTexture with horizontal blur shader...

                m_shader.setUniform ( "direction", sf::Vector2f ( 1.0f, 0.0f ) );

                m_horz_render_texture.create ( m_text_sprite.getLocalBounds ( ).width + 2.0f * radius_, m_text_sprite.getLocalBounds ( ).height + 2.0f * radius_ );
                m_horz_render_texture.clear ( sf::Color::White );
                m_horz_render_texture.setSmooth ( true );
                m_horz_render_texture.draw ( m_text_sprite, m_render_state );
                m_horz_render_texture.display ( );

                // 3. Create a sprite from resulting texture...

                m_horz_sprite.setTexture ( m_horz_render_texture.getTexture ( ) );

                // 4. Draw this sprite to a Render texture with vertical shader...

                m_shader.setUniform ( "direction", sf::Vector2f ( 0.0f, 1.0f ) );

                m_vert_render_texture.create ( m_horz_sprite.getLocalBounds ( ).width, m_horz_sprite.getLocalBounds ( ).height );
                m_vert_render_texture.clear ( sf::Color::White );
                m_vert_render_texture.setSmooth ( true );
                m_vert_render_texture.draw ( m_horz_sprite, m_render_state );

                m_text.setFillColor ( sf::Color::Green );
                m_text.setOutlineColor ( sf::Color::Black );
                m_text.setOutlineThickness ( 1.0f );
                m_text.setPosition ( 0.0f, 0.0f );

                m_vert_render_texture.draw ( m_text );

                m_vert_render_texture.display ( );

                m_final_sprite.setTexture ( m_vert_render_texture.getTexture ( ) );
                m_final_sprite.setPosition ( 50.0f, 50.0f );
        }

        void draw ( sf::RenderWindow &window_ ) {

                window_.draw ( m_final_sprite );
        }
};


int main ( ) {

        sf::ContextSettings settings;
        settings.antialiasingLevel = 8;

        sf::RenderWindow window ( sf::VideoMode ( 500, 300 ), "SFML Shaded Text", sf::Style::Titlebar | sf::Style::Close, settings );

        window.setVerticalSyncEnabled ( true );
        window.setFramerateLimit ( 60 );

        sf::Font font;

        if ( not ( font.loadFromFile ( "c:/windows/fonts/impact.ttf" ) ) ) {

                return EXIT_FAILURE;
        }

        ShadedText text ( L"Text", font, 224u, 8u, sf::Vector2f ( window.getSize ( ).x * 0.5f, window.getSize ( ).y * 0.5f ) );

        while ( window.isOpen ( ) ) {

                sf::Event event;

                while ( window.pollEvent ( event ) ) {

                        if ( event.type == sf::Event::Closed ) {

                                window.close ( );
                        }
                }

                window.clear ( sf::Color::White );

                text.draw ( window );

                window.display ( );
        }

        return 0;
}
 

The image of the resulting text is attached below. The result is reasonably good I would say (but could be improved IMO)...

The constructor runs in about 90ms 80ms on my laptop. It seems long to me... In a real-time situation it might be better, but improvements (or ideas) are welcomed.

[EDIT1] I wonder whether writing the m_text_sprite to an sf::Image, apply the blur on cpu and writing it back to the sf:Image wouln't be much faster (as opposed to creating all those sf::RenderTargets adn other boilerplate). Writing the m_text to sf::Image takes about 1-2ms, so there's time left!

[EDIT2] Eliminated 1 RenderTexture by re-use... The constructor now runs in about 80ms.

[EDIT3] About a quarter of the time is spent in this call:

m_text.setOrigin ( m_text.getLocalBounds ( ).left - radius_, m_text.getLocalBounds ( ).top - radius_ );

That's expensive!

[EDIT4] updated the latest result... looks good now.

22
Graphics / Re: Blur Shader
« on: February 28, 2016, 08:24:19 am »
It looks like you're using a blur radius value that is too high. Try a much smaller one e.g. 0.02 (it's not perfect)

Thanks for that! Indeed the radius needs to be much smaller. I've added a lighter outline as well, which gives the reult below... (it's better, but not perfet, as you said).

23
Graphics / Add Shadow to SFML-Objects (including Text) [was Shaded Text]
« on: February 27, 2016, 11:13:34 am »
I'm trying to create a shade to a text. A sharp shade is obviously no problem, just draw the text twice slightly displaced in the opposite direction of the "light" direction. I would like to blur this shadow around the edges. The answer seems to be "use shaders".

I've looked at the (SFML) shader examples and isolated the blur effect out of the wave+blur effect. This does not give a good result. That's why I'm working on a shader solution...

Other simpeler approaches (to the problem of adding feathered shade to text) are equally appreciated.

[EDIT] I've come to something I'm happy with (for now). It's still slow, but for my purposes I can work around it. I'll post the code in the top post (this one), and attach the result of running the code below it. The attached png is for some reason displayed larger (about 125%) than it is in reality (when clicked) and will therefore look better in an application.

#include <ciso646>
#include <vector>
#include <string>

#include <SFML/Graphics.hpp>


const std::string gaussian_blur_shader { "\
\
        uniform sampler2D texture;\
\
        uniform vec2 pixel_size;\
        uniform int blur_radius;\
        uniform float [ 256 ] weights;\
        uniform bool horizontal;\
\
\
        void main ( ) {\
\
        const vec2 texture_coordinates = gl_TexCoord [ 0 ].xy;\
\
        gl_FragColor = texture2D ( texture, texture_coordinates ) * weights [ 0 ];\
\
        if ( horizontal ) {\
\
                for ( int i = 1; i < blur_radius; ++i ) {\
\
                        const vec2 offset = vec2 ( float ( i ) * pixel_size.x, 0.0f );\
\
                        gl_FragColor += texture2D ( texture, texture_coordinates + offset ) * weights [ i ];\
                        gl_FragColor += texture2D ( texture, texture_coordinates - offset ) * weights [ i ];\
                }\
        }\
\
        else {\
\
                for ( int i = 1; i < blur_radius; ++i ) {\
\
                        const vec2 offset = vec2 ( 0.0f, float ( i ) * pixel_size.y );\
\
                        gl_FragColor += texture2D ( texture, texture_coordinates + offset ) * weights [ i ];\
                        gl_FragColor += texture2D ( texture, texture_coordinates - offset ) * weights [ i ];\
                }\
        }\
}\
\
"
};


template<typename T>
class Shadowed : public sf::Drawable {

        sf::Sprite m_object_sprite;

        const std::vector<float> m_gaussian_weights;
        sf::Shader m_shader;

        sf::RenderTexture m_horz_render_texture;
        sf::Sprite m_horz_sprite;

        sf::RenderTexture m_render_texture;
        sf::Sprite m_sprite;

        std::vector<float> gaussianWeights ( const std::size_t size_ ) const {

                // http://www.cocos2d-x.org/wiki/User_Tutorial-RenderTexture_Plus_Blur

                std::vector<float> gaussian_weights ( size_ );

                double nill = 1.0;

                for ( std::size_t i = 1; i < size_; ++i ) {

                        const double x = ( double ) i / ( double ) ( size_ - 1 ), gwi = 1.196826841204297942 / ( double ) size_ * std::exp ( -x * x * 4.5 );

                        gaussian_weights [ i ] = gwi;
                        nill -= 2.0 * gwi;
                }

                gaussian_weights [ 0 ] = nill;

                return gaussian_weights;
        }

public:

        Shadowed (

                T &object_,

                const std::size_t radius_,
                const sf::Vector2f &displacement_,
                const sf::Color &shadow_color = sf::Color::Black,
                const sf::Color &background_color = sf::Color::Transparent // To be set for better gradient...

                ) :

                m_gaussian_weights ( gaussianWeights ( radius_ ) ) {

                // Finish setting text object...

                const sf::Color original_fill_color ( object_.getFillColor ( ) );
                const sf::Color original_outline_color ( object_.getOutlineColor ( ) );

                const sf::Vector2f original_position ( object_.getPosition ( ) );
                const sf::Vector2f original_origin ( object_.getOrigin ( ) );

                object_.setFillColor ( shadow_color );
                object_.setOutlineColor ( shadow_color );
                object_.setOrigin ( object_.getLocalBounds ( ).left - std::max ( ( float ) radius_, displacement_.x ), object_.getLocalBounds ( ).top - std::max ( ( float ) radius_, displacement_.y ) );
                object_.setPosition ( sf::Vector2f ( 0.0f, 0.0f ) );

                // Init render texture...
                m_render_texture.create ( object_.getLocalBounds ( ).width + ( radius_ > std::abs ( displacement_.x ) ? 2 * radius_ : radius_ + std::abs ( displacement_.x ) ), object_.getLocalBounds ( ).height + ( radius_ > std::abs ( displacement_.y ) ? 2 * radius_ : radius_ + std::abs ( displacement_.y ) ) );
                m_render_texture.clear ( background_color );
                m_render_texture.setSmooth ( true );
                m_render_texture.draw ( object_ );
                m_render_texture.display ( );

                // 1. Create object sprite...

                m_object_sprite.setTexture ( m_render_texture.getTexture ( ) );

                // Load shader...

                m_shader.loadFromMemory ( gaussian_blur_shader, sf::Shader::Fragment );

                // Set shader parameters...

                m_shader.setUniform ( "pixel_size", sf::Vector2f ( 1.0f / m_object_sprite.getLocalBounds ( ).width, 1.0f / m_object_sprite.getLocalBounds ( ).height ) );
                m_shader.setUniform ( "blur_radius", ( int ) m_gaussian_weights.size ( ) );
                m_shader.setUniformArray ( "weights", m_gaussian_weights.data ( ), m_gaussian_weights.size ( ) );

                // 2. Draw it to a RenderTexture with horizontal blur shader...

                m_shader.setUniform ( "horizontal", true );

                m_horz_render_texture.create ( m_object_sprite.getLocalBounds ( ).width, m_object_sprite.getLocalBounds ( ).height );
                m_horz_render_texture.clear ( background_color );
                m_horz_render_texture.setSmooth ( true );
                m_horz_render_texture.draw ( m_object_sprite, &m_shader );

                m_horz_render_texture.display ( );

                // 3. Create a sprite from resulting texture...

                m_horz_sprite.setTexture ( m_horz_render_texture.getTexture ( ) );

                // 4. Draw this sprite to a Render texture with vertical shader...

                m_shader.setUniform ( "horizontal", false );

                m_render_texture.clear ( background_color );

                // Draw the objects's shadow...

                m_render_texture.draw ( m_horz_sprite, &m_shader );

                // Setup the actual object...

                object_.setFillColor ( original_fill_color );
                object_.setOutlineColor ( original_outline_color );
                object_.setPosition ( -displacement_.x, -displacement_.y );

                // Draw object...

                m_render_texture.draw ( object_ );
                m_render_texture.display ( );

                // Create sprite with the object at it's original position, dis-regarding the shadow... (needs more work)

                m_sprite.setTexture ( m_render_texture.getTexture ( ) );
                m_sprite.setPosition ( original_position + displacement_ - sf::Vector2f ( ( float ) radius_, ( float ) radius_ ) );

                object_.setPosition ( original_position );
                object_.setOrigin ( original_origin );
        }

        virtual void draw ( sf::RenderTarget &target_, sf::RenderStates states_ ) const {

                target_.draw ( m_sprite, states_ );
        }
};


int main ( ) {

        sf::ContextSettings settings;
        settings.antialiasingLevel = 8;

        sf::RenderWindow window ( sf::VideoMode ( 600, 800 ), "SFML add Shadow to Objects...", sf::Style::Titlebar | sf::Style::Close, settings );

        window.setVerticalSyncEnabled ( true );
        window.setFramerateLimit ( 60 );

        sf::Font font;

        if ( not ( font.loadFromFile ( "c:/windows/fonts/impact.ttf" ) ) ) {

                return EXIT_FAILURE;
        }

        sf::Text text ( L"SFML", font, 210u );

        text.setFillColor ( sf::Color::Green );
        text.setOutlineColor ( sf::Color::Black );
        text.setOutlineThickness ( 4.0f );
        text.setPosition ( sf::Vector2f ( 100.0f, 100.0f ) );

        Shadowed<sf::Text> shadowed_text (

                text,
                16u,
                sf::Vector2f ( 8.0f, 8.0f ),
                sf::Color::Black
        );

        sf::RectangleShape rect ( sf::Vector2f ( 300.0f, 300.0f ) );

        rect.setFillColor ( sf::Color::Yellow );
        rect.setOutlineColor ( sf::Color::Black );
        rect.setOutlineThickness ( 1.0f );
        rect.setPosition ( sf::Vector2f ( 150.0f, 400.0f ) );

        Shadowed<sf::RectangleShape> shadowed_rect (

                rect,
                16u,
                sf::Vector2f ( -16.0f, 24.0f ),
                sf::Color::Black
        );

        while ( window.isOpen ( ) ) {

                sf::Event event;

                while ( window.pollEvent ( event ) ) {

                        if ( event.type == sf::Event::Closed ) {

                                window.close ( );
                        }
                }

                window.clear ( sf::Color::White );

                window.draw ( shadowed_text );
                window.draw ( shadowed_rect );

                window.display ( );
        }

        return 0;
}
 

The code is self contained, on non-Windhoze platforms you'll have to stick in another font.

PS: What I thought would also be cool is to not just put in the displacement of the shadow, but a direction, elevation, and distance to the "base surface", so as to be able to calculate the displacement required from those three parameters. (need to brush-up my trig, or find something, help accepted :D) The objective would be to make the shadow coincide with the real shadows at the players location at the time of play.

Pages: 1 [2]
anything