SFML Blur Shader shows no effect - c++

I'm trying to implement a SFML Shader following their example and it doesn't show up.
GameObject is a class that inherits and implements sf::Drawable. Inside GameObject I have a sf::Texture and a sf::Sprite objects, responsible for the image of the game object. I'm trying to apply a blur effect on it. Here's the .cpp where I load the image and shader:
x = new GameObject("Images/apple.png", 100, 100, 1, 1);
mshade.loadFromFile("Shaders/blur.frag", sf::Shader::Fragment);
mshade.setParameter("texture", *(x)->objectTexture);
mshade.setParameter("blur_radius", 200);
And this is how I draw it:
gameWindow->draw(*x, &mshade);
And this is the GLSL code to create the blur shader:
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);
}
But for some reason the image is displayed just as normally, without any effect. I also don't get any error. Does anyone know why the blur effect doesn't show up?

I don't know anything about SFML, but i looks like your blur_radius is not well chosen.
Your image has the size 100x100 and you Blur-Shader samples the image with distance of 200px (blur_radius). So if your texture has gl_repeat enabled , you hit exactly the same pixel as the original one. -> no blur
Try using a lower blur_radius maybe something around 2-5

Well in my question at: SFML shader not working I got help on this issue aswell I recoomend you go check out tntxtnt's answer that will probably help you. but basicly it dosent blur the outline of the textures it only blurs the colors inside the sprite.

Related

OpenGL multipass shadow maps on Qt are not rendered

I'm trying to render dynamic shadows casted from the point light on some cubes. However, like there are no shadows at all on the cubes, particularly on the silver cube:
In my program I use Qt OpenGL API together with the native OpenGL one. I do two passes: 1. create a depth texture (glGenTextures()), create a framebuffer (glGenFramebuffers()) and attach the texture to that (glFramebufferTexture()). Then render all cubes to that framebuffer. 2. Render as usually all scene to the screen with using that texture in the shaders. I use QOpenGLShaderProgram class for creating shader programs.
How I calculate the shadows in the fragment shader:
float isFragInShadow(vec3 fragPos)
{
vec3 relFragPos = fragPos - lightPos;
float closestDepth = texture(depth_map, relFragPos).r;
closestDepth *= far_plane;
float currentDepth = length(relFragPos);
float bias = max(0.05 * (1.0 - dot(normalize(-relFragPos), Normal)), 0.005);
float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
return shadow;
}
...
float isShadow = isFragInShadow(FragPos);
vec3 resColor = ambient * obj_material.ambient + (1.0 - isShadow) * (diffuse * obj_material.diffuse + specular * obj_material.specular);
I also tried to render to the screen the depth texture and the result is following:
https://i.stack.imgur.com/qM9a1.png
How I render:
vec3 lightToFrag = FragPos - lightPos;
float closestDepth = texture(depth_map, lightToFrag).r;
Color = vec4(vec3(closestDepth), 1.0);
Why can I not see shadows in the scene?

Shader only rendering 1/4th of the screen

I'm currently trying to create a gaussian blur shader, and while I've successfully created the blur effect my shader only renders the lower right quarter of my screen like the image shows: And just to make it clear; it has NOT re-scaled the image, it just doesn't render the rest of it.
Here's my shader code with comments of my thoughts:
Vertex (horizontal, vertical almost identical. See below)
#version 400
in vec2 a_texCoord0; //My tex coords
out vec2 blurTextureCoords[11]; //Sample 11px (i.e, 5 right 5 left of center)
uniform float u_width; //Width of the screen. Used to calculate pixel size
void main(void){
gl_Position = vec4(a_texCoord0, 0.0, 1.0);
vec2 centerTexCoords = a_texCoord0 * 0.5 + 0.5; //Maybe this is somehow wrong?
float pixelSize = 1.0 / u_width; //This is kind of interesting, because my shader sometimes tells me that "no uniform value was found with name 'u_width', but it still seems to work as if I change the values manually (ex. set it to 1920) it still looks normal.
for(int i=-5; i<=5; i++) {
blurTextureCoords[i+5] = centerTexCoords + vec2(pixelSize * i, 0.0); //I also thought that it might be because I multiply a float with an integer, but if I do float(i) instead of just i it still looks the same.
}
}
Fragment
#version 400
#ifdef GL_ES
precision mediump float;
#endif
in vec2 blurTextureCoords[11];
out vec4 out_colour;
uniform sampler2D u_texture;
void main(void){
//The actual bluring
out_colour = vec4(0.0);
out_colour += texture(u_texture, blurTextureCoords[0]) * 0.0093;
out_colour += texture(u_texture, blurTextureCoords[1]) * 0.028002;
out_colour += texture(u_texture, blurTextureCoords[2]) * 0.065984;
out_colour += texture(u_texture, blurTextureCoords[3]) * 0.121703;
out_colour += texture(u_texture, blurTextureCoords[4]) * 0.175713;
out_colour += texture(u_texture, blurTextureCoords[5]) * 0.198596;
out_colour += texture(u_texture, blurTextureCoords[6]) * 0.175713;
out_colour += texture(u_texture, blurTextureCoords[7]) * 0.121703;
out_colour += texture(u_texture, blurTextureCoords[8]) * 0.065984;
out_colour += texture(u_texture, blurTextureCoords[9]) * 0.028002;
out_colour += texture(u_texture, blurTextureCoords[10]) * 0.0093;
}
Additional code
Creating a shader:
//I also have one for the vertical shader, it's almost exactly the same.
horizontalShader = new ShaderProgram(
Gdx.files.internal("graphics/shaders/post-processing/blur/horizontalBlur.vert"),
Gdx.files.internal("graphics/shaders/post-processing/blur/blur.frag"));
horizontalShader.pedantic = false;
horizontalShader.begin();
horizontalShader.setUniformf("u_width", Gdx.graphics.getWidth());
horizontalShader.end();
if (horizontalShader.getLog().length() != 0) {
System.out.println("Horizontal shader! \n" + horizontalShader.getLog());
}
Rendering to FBO then to screen:
// Horozontal blur
horizontalFBO.begin();
spriteBatch.begin();
spriteBatch.setShader(horizontalShader);
background_image.draw(spriteBatch);
spriteBatch.end();
horizontalFBO.end();
// Vertical blur
verticalFBO.begin();
spriteBatch.begin();
spriteBatch.setShader(verticalShader);
spriteBatch.draw(horizontalFBO.getColorBufferTexture(), 0, 0);
spriteBatch.end();
verticalFBO.end();
// Normal FBO (screen)
spriteBatch.begin();
spriteBatch.setShader(null);
spriteBatch.draw(verticalFBO.getColorBufferTexture(), 0, 0);
spriteBatch.end();
Additional info
I use two FBOs, but it seems that those are not the root of the problem, as the problem still persists if I just render directly to the screen using these shaders.
I have two vertex shaders, one for the horizontal and one for the vertical blur. The only difference is the uniform name u_width becomes u_height and the blurTextureCoords[i+5] = centerTexCoords + vec2(pixelSize * i, 0.0); becomes blurTextureCoords[i+5] = centerTexCoords + vec2(0.0, pixelSize * i);

SFML loading shader error

So i am working on my game project using SFML and I tried to implement a blur shader. I have no idea why , but this block of code makes the program show a white screen and then close.I didn't even use the shader to draw anything , just the fact that I am trying to load it gives the unexpected result :( .
void button::setText(std::string _text)
{
text.setString(_text);
text.setFont(font);
text.setCharacterSize(80);
text.move(0,-(text.getLocalBounds().top));
text.setColor(sf::Color(255,255,255,255));
width=text.getLocalBounds().width+text.getLocalBounds().left;
height=text.getLocalBounds().height+text.getLocalBounds().top;
rndtexture.create(width, height);
rndtexture.setSmooth(true);
rndtexture.clear(sf::Color::Transparent);
rndtexture.draw(text);
rndtexture.display();
rTexture=rndtexture.getTexture();
spriteR.setTexture(rTexture);
rndtexture.clear(sf::Color::Transparent);
text.setColor(sf::Color(0,0,0,100));
rndtexture.draw(text);
rndtexture.display();
pTexture=rndtexture.getTexture();
spriteP.setTexture(pTexture);
//commenting this out will make it work just fine
if (!shader.loadFromFile("shader.frag", sf::Shader::Type::Fragment))
{
std::cout<<"lol";
}
//
shader.setParameter("texture", sf::Shader::CurrentTexture);
shader.setParameter("blur_radius", 5.0);
}
This is my shader 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);
}
What is wrong with this.. ?
What's the return value when you call:
sf::Shader::isAvailable()
Make sure you can use a shader program before you call it. Also, a shader can't crash a program, so it's definitely not your shader. If something was wrong with your shader, it wouldn't compile. If your shader didn't compile, then SFML automatically switches to a built-in shader.

Applying a blur shader to sf::RectangleShape

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?
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.

GLSL Normalize Mouse Input

i'm new in this shader world and just want to try out something. I want to do the following:
In a specific radius around the mouse the texture in the background should rotate by 10°. The mouse coordinates are absolute values, so to work with them i have to normalize them, so i can adress the right space in the texture. But somehow this doesn't work right. The rotation works but i get the color information with a little offset.
I think the problem is the normalize(mouse)but i don't know how to do this right. Here is the shader:
uniform sampler2D tex0;
uniform vec2 mouse;
void main() {
vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y);
if (distance(pos, mouse) < 90.0) {
vec2 p = gl_TexCoord[0].st;
vec2 m = normalize(mouse);
p.x = m.x + (cos(radians(10.0)) * (p.x - m.x) - sin(radians(10.0)) * (p.y - m.y));
p.y = m.y + (sin(radians(10.0)) * (p.x - m.x) + cos(radians(10.0)) * (p.y - m.y));
gl_FragColor = vec4(0.0, m.y, 0.0, 0.0);
gl_FragColor = texture2D( tex0, p );
}
else {
gl_FragColor.rgb = texture2D( tex0, gl_TexCoord[0].st ).rgb;
gl_FragColor.a = 1.0;
}
}
I'm using cinder to do this.
mShader.uniform( "mouse", Vec2f( m.x, 682 - m.y ) );
Thank you.
In order transform absolute mouse coordinates into [0,1] range (required for a texture sample), you don't need normalize function. You need a simple scale:
vec2 mouse_norm = vec2( m.x/screen.width, 1.0 - m.y/screen.height )
I wrote it in GLSL, but for you it will be easier to do on CPU side before passing a uniform, because originally it's CPU side that is aware of the screen resolution.