【问题标题】:SFML shader not workingSFML 着色器不工作
【发布时间】:2017-06-01 07:15:09
【问题描述】:

我正在尝试在单击按钮时为我的按钮创建轮廓效果,但 atm 我只是在使用着色器测试东西......每当我用我的着色器绘制一些东西时,它都会使形状完全变黑

#include <SFML\Graphics.hpp>

int main(){
    sf::RenderWindow window(sf::VideoMode(500, 500), "hello world", sf::Style::Close);

    sf::RectangleShape rect;
    rect.setSize(sf::Vector2f(100, 100));
    rect.setFillColor(sf::Color::Red);

    sf::Shader blur;
    if (!blur.loadFromFile("blur.frag", sf::Shader::Fragment)){
        return 1;
    }
    if (!blur.isAvailable()){
        return 1;
    }
    blur.setUniform("texture", sf::Shader::CurrentTexture);
    blur.setUniform("blur_radius", 0.002f);

    while (window.isOpen()){

        sf::Event evnt;

        while (window.pollEvent(evnt)){
            if (evnt.type == sf::Event::Closed)
                window.close();
        }

        window.clear(sf::Color(0, 100, 100));

        sf::RenderStates state;
        state.shader = &blur;
        window.draw(rect, state);

        window.display();
    }
    return 0;
}

还有我的着色器代码。

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);
}

我希望左上角会出现一个模糊的红色矩形,但会出现一个黑色实心矩形。

【问题讨论】:

  • 请在minimal reproducible example中编辑。
  • @BartekBanachewicz 现在更新了
  • 着色器代码看起来不错。尽管会出现模糊的红色矩形,但您的代码中没有任何内容。您有一个将着色器应用到的蓝色矩形,但是您期望什么?你不能只模糊一种颜色。为了看到模糊效果,你必须有别的东西,你可以用它来模糊颜色。做以下实验:将模糊着色器应用到整个场景,你会看到它会按预期工作:)
  • 创建一个红色纹理,在上面制作一个精灵,然后绘制这个精灵。 RectangleShape 没有纹理,所以我猜它不受着色器的影响。
  • @user3881815 在我的原始代码中有这个三角形是红色的。但是使用这个最小的完整且可验证的示例,正​​如 bartek 建议的那样,我出于某种原因将矩形设为蓝色......我现在正在改变,感谢您指出它

标签: c++ sfml


【解决方案1】:

因为rect 没有附加纹理,所以在 blur.frag 中使用的所有像素都是无效的,我猜在这种情况下它使用黑色像素,因此是黑色矩形。

你应该create a texture(使用sf::RenderTexture),在上面画任何你想要的东西,然后在上面创建一个sf::Sprite并画出这个精灵。或者,您可以加载纹理 from an image

#include <SFML/Graphics.hpp>

int main(){
    sf::RenderWindow window(sf::VideoMode(200, 200), "hello world", sf::Style::Close);
    window.setFramerateLimit(60);

    sf::RectangleShape rectBlue;
    rectBlue.setSize(sf::Vector2f(100, 50));
    rectBlue.setFillColor(sf::Color::Blue);
    sf::RectangleShape rectYellow;
    rectYellow.setSize(sf::Vector2f(100, 50));
    rectYellow.setFillColor(sf::Color::Yellow);
    rectYellow.setPosition(0, 50);

    sf::RenderTexture renderTexture;
    if (!renderTexture.create(100, 100)){ //create a render texture
        return 1;
    }
    renderTexture.clear();
    renderTexture.draw(rectBlue); //draw blue rect on the render texture
    renderTexture.draw(rectYellow); //draw yellow rect
    renderTexture.display();
    sf::Sprite sprite(renderTexture.getTexture()); //create a sprite from the created texture

    sf::Shader blur;
    if (!blur.loadFromFile("blur.frag", sf::Shader::Fragment)){
        return 1;
    }
    if (!blur.isAvailable()){
        return 1;
    }
    blur.setUniform("texture", sf::Shader::CurrentTexture);
    blur.setUniform("blur_radius", 0.05f);

    while (window.isOpen()){

        sf::Event evnt;

        while (window.pollEvent(evnt)){
            if (evnt.type == sf::Event::Closed)
                window.close();
        }

        window.clear(sf::Color(0, 100, 100));
        window.draw(sprite, &blur); //draw the sprite with blur shader
        window.display();
    }
    return 0;
}

结果:

【讨论】:

  • 非常感谢您的良好解释和明确答案。这对我来说是个烦人的问题。但这实际上不是我想要的......这个模糊着色器没有按照我想要的方式工作。你知道如何创建一个模糊精灵轮廓的着色器吗?
  • 快速而肮脏的方式:您可以在分配 gl_FragColor 之前简单地检查像素 alpha pixel.a。如果pixel.a &lt; 16.0 则模糊它:@​​987654331@,否则不要:gl_FragColor = gl_Color * texture2D(texture, gl_TexCoord[0].xy)。如果你想要一个透明的渲染纹理,那么不要调用renderTexture.clear()
  • 我大部分时间都在使用,但我最终自己弄明白了,在过程中我编写了我的第一个着色器程序......非常感谢你的帮助 tntxtnt 你给了我做我的第一个着色器的动力程序
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-17
  • 1970-01-01
  • 2013-01-12
  • 2014-04-30
  • 1970-01-01
  • 2023-04-09
相关资源
最近更新 更多