3
\$\begingroup\$

I would like to create a glow effect in GLSL, there is a tutorial that explains how we multiply RGB * a :

enter image description here

enter image description here

I have some questions :

is it an operation that is in a fragment shader, where RGBa is calculated each frame, and then we apply the blur at the end of the shader? The whole process in the same shader, called each frame? Or can we multiply RGBa in a separate process at the beginning of the game and send this texture to the fragment that will blur the result?

I have tried to translate the informations I found, but I am a beginner with the shaders, could someone put me on the right track here? Should we use a "buffer"? Here is my starting code :

GLuint CreateBufferForMixAB() {

    unsigned char * data;
    GLuint bindingPoint = 1, mixTex, buffer;

    glGenTextures( 1, &mixTex );
    glBindTexture( GL_TEXTURE_2D, mixTex );
    data = (unsigned char *)malloc( width * height );
    ...imageTex.rgb * alphaTex.rgb...

    glGenBuffers(1, &buffer);
    glBindBuffer(GL_UNIFORM_BUFFER, buffer);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(mixTex), mixTex, GL_DYNAMIC_DRAW);
    glBindBufferBase(GL_UNIFORM_BUFFER, bindingPoint, buffer);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, 
    GL_UNSIGNED_BYTE, data);

}

Thanks

\$\endgroup\$
  • \$\begingroup\$ So you want a bloom effect? \$\endgroup\$ – ratchet freak Mar 17 '15 at 13:34
  • \$\begingroup\$ @ratchetfreak yes this is the kind of effect I am looking for. Like in the examples from the tutorial, for lights, or neon objects. \$\endgroup\$ – Paul Mar 17 '15 at 13:36
2
\$\begingroup\$

In order to do a glow or bloom, you generally need to start with an image, threshold it and possibly colorize it, then blur it and add the blurred version to the original. I would do this by creating a few textures and FBOs for multiple passes. Something like this pseudocode:

Create an FBO
Attach a texture to it to draw into
Draw a textured quad with your input image as the texture and a shader applied 
    that makes every pixel with a luminance below some threshold transparent black
    (that is the RGBA = 0,0,0,0). All other pixels are either left untouched
    or their color is pulled out of a gradient texture based on their luminance
Detach the texture, and attach a new output texture to the FBO
Apply a horizontal blur to the thresholded image (Do this by drawing a textured quad 
    with the threshold image and applying a shader that blurs horizontally)
Detach the blurred texture and attach a new output texture to the FBO
Apply a vertical blur to the horizontally blurred image (using a shader as above)
Detach the vertically blurred texture and attach the final output texture
Add the original unmodified input texture to the vertically blurred texture either 
    using a shader or using blending

A shader for doing a threshold might look something like this:

in vec2 texCoord;
out vec4 color;
uniform float threshold;
uniform sampler2D inputImage;
const vec4 lumConst = { 0.2126, 0.7152, 0.0722, 0.0 };
void main ()
{
    vec4 inputSample = sample (texCoord, inputImage);
    vec4 result;
    if (dot (inputSample, lumConst) < threshold)
    {
        result = vec4(0.0);
    }
    else
    {
        result = inputSample;
    }
    color = result;
}

A horizontal or vertical blur would sample some number of pixels to the left and right or above and below the current pixel and multiply them by kernel weights and sum them.

To get more bloom, you can scale the final blurred image by a value greater than 1 before adding it to the original image.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.