Applying a blur shader to sf::RectangleShape

北慕城南 提交于 2019-12-23 04:35:09

问题


I have an object that is a 2d array of sf::RectangleShapes (for a tile-based game). It's supposed to look like a cloud, so I want to add some blur to it. Here is what it looks like now:

And I want it to look like this:

Instinctively, it seems to achieve this blur effect on the low level, I would have to draw the cloud object to a buffer, and then apply the blur object to the buffer. But I'm not sure if SFML is doing this already.

In my main loop, I have this:

    for( CloudIterator it = clouds.begin(); it != clouds.end(); it++ ) {
        window.draw(**it);
    }

Which I hope to replace with:

    for( CloudIterator it = clouds.begin(); it != clouds.end(); it++ ) {
        window.draw(**it, &blurShader);
    }

Where blurShader is loaded from the following GLSL file:

    uniform sampler2D texture;
    uniform float blur_radius;

    void main()
    {
        vec2 offx = vec2(blur_radius, 0.0);
        vec2 offy = vec2(0.0, blur_radius);

        vec4 pixel = texture2D(texture, gl_TexCoord[0].xy)               * 4.0 +
                     texture2D(texture, gl_TexCoord[0].xy - offx)        * 2.0 +
                     texture2D(texture, gl_TexCoord[0].xy + offx)        * 2.0 +
                     texture2D(texture, gl_TexCoord[0].xy - offy)        * 2.0 +
                     texture2D(texture, gl_TexCoord[0].xy + offy)        * 2.0 +
                     texture2D(texture, gl_TexCoord[0].xy - offx - offy) * 1.0 +
                     texture2D(texture, gl_TexCoord[0].xy - offx + offy) * 1.0 +
                     texture2D(texture, gl_TexCoord[0].xy + offx - offy) * 1.0 +
                     texture2D(texture, gl_TexCoord[0].xy + offx + offy) * 1.0;

        gl_FragColor =  gl_Color * (pixel / 16.0);
    }

However, the result is clouds that are completely black. Is the texture referred to in the GLSL file something I have to load?

My draw code for these cloud objects looks like this, overloaded from sf::Drawable :

void Cloud::draw(sf::RenderTarget& target, sf::RenderStates states) const {
    states.transform *= getTransform();

    ...loop to draw various sf::RectangleShape's in the Cloud...

}

So, I may be a little naive that window.draw(**it, &blurShader) would just work. Should I be fetching and applying the shader in the Cloud::draw function?


回答1:


However, the result is clouds that are completely black. Is the texture referred to in the GLSL file something I have to load?

I'm pretty sure you'll have to set the texture yourself. If you look at the shader example, when each shader is loaded the author binds the current texture as the texture parameter. You'll probably have to do the same thing.

m_shader.setParameter("texture", sf::Shader::CurrentTexture);

If sf::Shader::CurrentTexture refers to a different texture, then you'll have to explicitly obtain the correct texture. If your sf::RectangleShapes don't have a texture, then of course you can't blur something that isn't there.

In the case where your shapes do not have a texture of their own, you may be able to achieve the desired effect by rendering the shapes to an sf::RenderTexture, and then rendering an sf::Sprite using the sf::RenderTexture and applying the shader to that draw call.



来源:https://stackoverflow.com/questions/19392525/applying-a-blur-shader-to-sfrectangleshape

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!