Graphicslab Project's Glow (Glare,glow) effect

Source: Internet
Author: User

I_dovelemon

Date: 2016/07/02

Source: CSDN

Topics: Render to Texture, Post process, glare, Glow, multi-pass rendering



Introduction

Since the inception of Graphicslab project projects, has been busy building shader experimental environment, now the basic experimental environment has been built, so try to use it to write some effects. This article will tell you how to use GLSL to write a glow effect in OpenGL.

Glow (Glare,glow)

Glow effect, also known as Glare,glow effect. Its main role is to simulate some scenes of the light-emitting objects around the hazy blurred glow effect, a bit similar to PS in the outer glow. First look at the actual picture of this effect, give everyone a perceptual understanding.

Figure 1

Figure 2

Figure 3
The picture above shows you the visual experience that the glow effect can bring. Adds a glow effect to a glowing object in the scene, enabling a dim feel of the light. Of course, for the overall picture of harmony can not be confused with this effect, otherwise it gives a very tacky feeling.

Principle

Here are some of the ways to achieve this effect. In fact, the principle of its implementation is very simple, we just want to add a glow effect of the object to do a fuzzy operation, and then the blurred image and the original image of the Alpha Blend, you can get the effect shown above. The operation is shown (here for simplicity, only glare objects are drawn in the scene, and only a little light is added, no other effects are added):

Figure 4 The original scene without blurring

Figure 5 Image after blurring the original scene

Figure 6 The final effect after the blurred scene is Alpha blend with the original scene
The above three pictures show the overall steps to draw a simple glow effect. The principle is not very simple??? You can in Photoshop and other image processing software, direct simulation to see if this effect can be obtained.

OpenGL implementation

Before we tell the specific implementation, we need to understand some basic points of knowledge first. We are able to achieve this effect on the basis of understanding these points of knowledge.
Render to texture (render to Texture, RTT)
In graphics processing, we often need to do some processing of the rendered scene. That is, we need a way to save our graphics API (OpenGL, DirectX)-drawn scenes to our designated memory (video) so that we can deal with him later. And in OpenGL, it's easy to do that. This technique is also mentioned in my blog. You can learn about this in terms of the description and code in your blog.
Post-processing (post-processing)
Post-processing is often used in graphical studies. The scenes that we draw in the game are often not able to be achieved simply by relying on the light model calculations. A lot of special effects are obtained through the post-processing of the image space in the rendered scene. For example, the glow effect implemented in this article uses this technique. There are many other special effects that are processed in the image space, and interested students can read the chapters in real-time rendering on this technique.
Image Blur (Blur)
When we talk about the overall drawing process of the glow effect, we need to blur the original scene image. So how can we achieve the blurred operation of the image?
In the image processing, we often use the fuzzy is based on Gaussian distribution function Gaussian blur. This article describes in detail some of the technical details of blurred images, so you can learn how to do Gaussian blur.
Gaussian blur in the image processing, is the use of 2-D Gaussian distribution function to a pixel of the upper and lower left and right surrounded by the pixels to be achieved. We assume that the radius of the blur is 20 pixels, and that each pixel needs to be computed (2 * 20) ^ 2 samples according to the original calculation of the Gaussian blur. This is acceptable for image processing, but for real-time games, the computational capacity is a bit larger.
For this reason, people have come up with an optimized method to achieve Gaussian blur. For a pixel, its fuzzy radius of 20, then we can be divided into two times fuzzy, one is the horizontal fuzzy calculation, one is the longitudinal fuzzy calculation. That is, the blur operation is reduced from O (n^2) to 2 * O (N). Shows how to do this:

Figure 7
, we can see that we first have a horizontal fuzzy calculation of the original scene map, this calculation we only need to use one-dimensional Gaussian distribution to calculate. Then the transverse blurred image is blurred vertically, and the same as the transverse blur, using one-dimensional Gaussian distribution function. In this way, a Gaussian blur image can be obtained, and its blur effect is no worse than the Ivigos blur effect.
OpenGL drawing Process
Here's a drawing process in my code to show you how to draw a glow effect in OpenGL:
void Glb_display () {    glb_draw_normal_scene ();    Glb_draw_render_target_gauss_blur_h ();    Glb_draw_render_target_gauss_blur_v ();    Glb_draw_blend ();    Glutswapbuffers ();}

The code above gives the flow I've drawn:
(1). Draw a normal scene--the scene drawn here is saved to a texture A, and copies a texture to the B texture
(2) Draw a rectangle that is the same size as the screen, apply texture A as a map of the rectangle, apply a transverse fuzzy shader calculation, and save the final result to another map C
(3) Draw a rectangle of the same size as the screen, the texture C as the map of the rectangle, apply a longitudinal fuzzy shader calculation, the final result is saved to texture a (A has been copied to B, so it can be overwritten)
(4) After the first three steps, a texture saved the image after the blur, B texture saved the original image, and then draw a rectangle, the two posters are passed into, the alpha mixed calculation.
Shader calculation
For the (1) step, use the following two shader:
Light_pixel.vs
--------------------------------------------------------------------//Declaration:copyright (c), by I_dovelemon , 2016. All right reserved.//author:i_dovelemon[[email protected]]//date:2016/06/29//brief:phong lights ' s vertex shader/ /--------------------------------------------------------------------#version 330in vec3 vertex;in vec3 Normal; Uniform mat4 proj;uniform mat4 view;uniform mat4 world;uniform mat4 trans_inv_world;out vec3 vs_vertex;out vec3 vs_normal;  void Main () {gl_position = proj * view * World * VEC4 (Vertex, 1.0); Vs_vertex = (World * VEC4 (Vertex, 1.0)). Xyz;vs_normal = (Trans_inv_world * VEC4 (Normal, 0.0)). XYZ;}

Light_pixel.ps
--------------------------------------------------------------------//Declaration:copyright (c), by I_dovelemon , 2016. All right reserved.//author:i_dovelemon[[email protected]]//date:2016/06/29//brief:phong lights ' s pixel sha der//-------------------------------------------------------------------#version 330in vec3 vs_vertex;in vec3 vs_ Normal;out vec4 color;uniform vec3 parallel_light_dir;uniform vec3 parallel_light_ambient;uniform vec3 parallel_light_ Diffuse;uniform vec3 parallel_light_specular;uniform vec3 material_ambient;uniform vec3 material_diffuse;uniform vec3 Material_specular;uniform float material_specular_pow;uniform vec3 eye_pos;vec3 calc_diffuse (vec3 Light_vec, VEC3 Normal, vec3 diffuse, vec3 light_color) {float ratio = dot (Light_vec, normal); ratio = max (ratio, 0.0); return diffuse * Lig Ht_color * ratio;} VEC3 calc_specular (vec3 Light_vec, vec3 Normal, vec3 View_vec, vec3 specular, vec3 Light_color, float pow_value) {VEC3 ref _light_vec = Reflect (Light_vec, normal); float ratio = dot (Ref_light_vec, view_vec); ratio = max (ratio, 0.0); ratio = POW (ratio, pow_value); return specular * Light_color * ratio;} void Main () {vec3 Light_vec =-parallel_light_dir;vec3 normal = normalize (vs_normal); VEC3 View_vec = Normalize (eye_pos-v S_vertex); vec3 ambient = material_ambient * PARALLEL_LIGHT_AMBIENT;VEC3 diffuse = calc_diffuse (Light_vec, Normal, Material_diffuse, parallel_light_diffuse); VEC3 specular = Calc_specular (Light_vec, Normal, View_vec, Material_ Specular, Parallel_light_specular, material_specular_pow); color = VEC4 (ambient + diffuse + specular, 1.0);}

These two shader just to achieve the Phong-type lighting calculation, give the scene a little light, for the paint glow effect is not necessary, but you must have something to draw the glow effect!
For steps (2) and step (3), use the following three shader:
Gauss_blur.vs
--------------------------------------------------------------------//Declaration:copyright (c), by I_dovelemon , 2016. All right reserved.//author:i_dovelemon[[email protected]]//date:2016/06/29//Brief:gauss Blur pass through Verte X shader//--------------------------------------------------------------------#version 330in vec3 vertex;in vec2 Texcoord;out vec2 vs_texcoord;void Main () {    gl_position = VEC4 (vertex, 1.0);    Vs_texcoord = Texcoord;}

gauss_ Blurh.ps 
--------------------------------------------------------------------//Declaration:copyright (c), by I_dovelemon , 2016. All right reserved.//author:i_dovelemon[[email protected]]//date:2016/06/29//brief:gauss Blur Horizontal Pass SH ader//--------------------------------------------------------------------#version 330in vec2 vs_texcoord;out vec4 Color;uniform sampler2d tex;uniform float tex_width;uniform float gauss_num[21];void main () {color = Texture2d (Tex, vs    _texcoord) * Gauss_num[0];    float step = 1.0/tex_width; for (int i = 1; i < i++) {if (Vs_texcoord.x-i * Step >= 0.0) {color + = Texture2d (Tex, VEC2 (Vs_texcoord.x-i * step, VS_TEXCOORD.Y))        * Gauss_num[i]; if (vs_texcoord.x + i * Step <= 1.0) {color + texture2d (Tex, VEC2 (vs_texcoord.x + i * step, Vs_te        XCOORD.Y)) * Gauss_num[i]; }    }}

gauss_ Blurv.ps 
--------------------------------------------------------------------//Declaration:copyright (c), by I_dovelemon , 2016. All right reserved.//author:i_dovelemon[[email protected]]//date:2016/06/29//brief:gauss Blur Vertical Pass Shad er//--------------------------------------------------------------------#version 330in vec2 vs_texcoord;out vec4 Color;uniform sampler2d tex;uniform float tex_height;uniform float gauss_num[21];void main () {color = Texture2d (Tex, V    S_texcoord) * Gauss_num[0];    float step = 1.0/tex_height; for (int i = 0; I <21; i++) {if (Vs_texcoord.y-i * Step >= 0.0) {color + = Texture2d (Tex, VEC2 (        Vs_texcoord.x, Vs_texcoord.y-i * step)) * Gauss_num[i]; } if (Vs_texcoord.y + i * Step <= 1.0) {color + texture2d (Tex, VEC2 (vs_texcoord.x, Vs_texcoord.y +        I * Step)) * Gauss_num[i]; }    }}

The above three shader combinations complete the Gaussian blur calculation. Here are a few things to keep in mind.
(1) When the fuzzy calculation, the logic is a pixel unit for the step value, but because the texture coordinates are from [0,1], so we need to calculate the step value of a pixel as the corresponding texture coordinate stepping. This operation can be completed in the application phase, and then passed to the shader, where Bo master lazy, directly in the shader calculation.
(2) gauss_num[21 in shader] each value of the Gaussian distribution with a fuzzy radius of 20 is preserved. The calculation of this value is done in the application phase and then submitted to the shader, as follows is the function to calculate the Gauss_num, using a one-dimensional Gaussian distribution function to complete:
float glb_gauss_num (int x) {    float pi = 3.1415927f;    float e = 2.71828f;    float theta = 0.1f;    float theta2 = theta * THETA;    float Temp1 = 1.0f/(theta * sqrt (2 * pi));    float Temp2 = POW (E,-(x * x)/2 * theta2);    return TEMP1 * TEMP2;} void Glb_calc_gauss_nums () {    g_gaussnum[0] = 1.0f;    for (int32_t i = 1; i < sizeof (g_gaussnum)/sizeof (g_gaussnum[0]); i++) {        G_gaussnum[i] = Glb_gauss_num (i);    }    Float total = 0.0f;    for (int32_t i = 0; i < sizeof (g_gaussnum)/sizeof (g_gaussnum[0]), i++) {total        + = G_gaussnum[i];    }    for (int32_t i = 0; i < sizeof (g_gaussnum)/sizeof (g_gaussnum[0]); i++) {        g_gaussnum[i] = g_gaussnum[i]/total;< c17/>}}

For step (4), the following two shader are used:
Blend.vs
--------------------------------------------------------------------//Declaration:copyright (c), by I_dovelemon , 2016. All right reserved.//author:i_dovelemon[[email protected]]//date:2016/06/29//brief:blend pass through Vertex sha der//--------------------------------------------------------------------#version 330in vec3 vertex;in vec2 Texcoord;out vec2 vs_texcoord;void Main () {    gl_position = VEC4 (vertex, 1.0);    Vs_texcoord = Texcoord;}

Blend.ps
--------------------------------------------------------------------//Declaration:copyright (c), by I_dovelemon , 2016. All right reserved.//author:i_dovelemon[[email protected]]//date:2016/06/29//brief:alpha blend shader//--------- -----------------------------------------------------------#version 330in vec2 vs_texcoord;out vec4 color;uniform SAMPLER2D blur_tex;uniform sampler2d scene_tex;void Main () {Vec4 Blur_color = texture2d (Blur_tex, Vs_texcoord); vec4 Scene_color = Texture2d (Scene_tex, vs_texcoord); color = Blur_color * 0.5 + scene_color * 0.5;}

For the final blending calculation, I chose half of the blur map and half of the scene map to do the blending. The final effect is as follows:

Figure 8

Summarize

In order to simplify operations, the above article has done a lot of operations that are not possible in the actual project. For example, the texture stepping value is computed in shader. In the actual case, the implementation of the glow is far more complex than shown here, such as the scene has a non-luminous objects, and glowing objects, it is necessary to use an alpha map to identify which of the scene map needs to be blurred, and which is not required. Also for example, the light object in a non-luminous object behind, then the fuzzy calculation, it will inevitably let the light-emitting objects into the non-luminous objects, will produce a more coarse feeling.
Therefore, this article is only to tell you about the basic principles of the glow algorithm, as to how to integrate into your own projects, you need to think of yourselves! Hope this article can help you!

Reference documents

http://http.developer.nvidia.com/GPUGems/gpugems_ch21.html GPU gems-chapter 21.real-time Glow
Http://www.nutty.ca/?page_id=352&link=glow Nutty-software-glow (aka Bloom)
http://blog.csdn.net/a3070173/article/details/3220940 GLSL for Glow effect
Http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html Gaussian Blur algorithm-Nanyi's blog
Http://baike.baidu.com/link?url=bWuVG4Lbr7DM-UReJNKUDOqrNcA788yhwpgl7Ln1IE-TRqiBkEYJrRP1tJEZ2sHOa0MAat21_ Ivrss2ds6r4_a Normal distribution-Gaussian distributions-Baidu Encyclopedia

Graphicslab Project's Glow (Glare,glow) effect

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.