I. INTRODUCTION
Today to learn bloom effect, bloom effect sometimes called glow effect, Chinese is generally called "full-screen omni-ray", which is a full-screen post-processing effect can be simulated hdr, but the implementation of the principle and HDR is far, the effect is worse than hdr, but more than the performance of HDR to save a Lot.
Two. introduction of the principle
We have to mention the legendary hdr, starting with the contact engine, a group of Daniel often talk about the word, but as a novice, has been the legendary technology with "awe" attitude, but now gradually familiar with some of the rendering related things, cheap, and not so afraid of the technology. Today to learn about hdr, but HDR is not the protagonist of this article, so just a brief introduction.
1.HDR
HDR (high Dynamic range). The so-called high, refers to the range of brightness is higher. We know that the normal screen of a pixel is composed of RGB three primary colors, each channel with eight-bit binary representation, that is, 0-255, converted to 16 binary, is white 0xFFFFFF, black for 0x000000. The Real-world brightness is far greater than the screen can display brightness, such as the brightness of the sun will be tens of thousands of times times the brightness of our screen, and although we do not recognize such a wide range of brightness, but the screen brightness range is far from expressing the real world brightness distribution. Assuming that our real-world brightness is 0-10000, then this is what we call high, which is higher than the brightness range on our Screen. If you do not use hdr, the scene will appear in large chunks of light or dark, resulting in the scene contrast is not obvious, affecting the effect of the Picture.
How to simulate a higher range of luminance distributions with limited luminance distributions is what HDR is Doing. The technology that implements such a function is called tonemapping, which is not officially translated, and is called tone mapping technology. This technology will make the contrast of the picture softer, the high brightness range is more smoothly scaled to 0-255 of this low light range, the main application of the principle is local Adaptability. Our eyes, in the relatively dark place, the original can also see clear things, but if suddenly to a relatively bright place, we will see nothing, need correction for a while to adapt to the current brightness level, before playing a small array of CryEngine3, the default is to open this effect, feel or Dick Dick. About the principle of tonemapping technology, you can refer to this article and this article, as well as this piece of chicken bombing day paper, here is not too much Introduction.
2.Bloom
The subject of this article is not hdr, but bloom. Bloom can simulate the effect of hdr, but the principle and HDR are far apart. HDR is actually through the mapping technology, to achieve the overall adjustment of global brightness properties, This adjustment is the color, intensity, etc. can be adjusted, and bloom only can be the light range to high saturation, that is, to brighten the place brighter. however, The bloom effect is simple and the performance consumption is small, but it can achieve good results. You can refer to this article for the difference between HDR and BLOOM.
Here to introduce the implementation of the principle of bloom, in fact, it is relatively simple, first we need to set a luminance threshold we want to shine, first time processing, We need to filter the original scene, all pixels smaller than this threshold is filtered out, all pixels greater than the value left, so, We get a map that contains only the part that needs to be flooded, the rest is black, and the floodlight is produced by the diffraction effect, and the most light-flooded effect we see in the real world is actually going to spread to the dark, which means that in the bright place the boundary is not obvious, so we need to be part of the floodlight, That is the result of our previous operation of the image to blur operation, to achieve the effect of light overflow, and finally, we will process the image and the original image overlay, we get the final Result. There is an article written by the foreigner is better, here I borrowed this picture to Use:
The direct implementation of bloom on the DX can refer to this article
Three. Code Implementation
C # section:
Using unityengine;using system.collections; [executeineditmode]public class Bloomeffect:posteffectbase{//resolution public int downsample = 1; Sample rate public int samplerscale = 1; Highlight partial extraction threshold public Color Colorthreshold = color.gray; Bloom floodlight Color Public color Bloomcolor = color.white; Bloom weight Value [Range (0.0f, 1.0f)] public float bloomfactor = 0.5f; void Onrenderimage (rendertexture source, rendertexture destination) {if (_material) {//apply two blocks R T, and the resolution is reduced by downsameple rendertexture Temp1 = rendertexture.gettemporary (source.width >> downsample, SOURC E.height >> downsample, 0, source.format); Rendertexture temp2 = rendertexture.gettemporary (source.width >> downsample, source.height >> downsample, 0 , source.format); Copy the scene map directly to the low resolution RT to achieve the reduced resolution effect Graphics.blit (source, temp1); Extracts the highlighted part from the threshold, using PASS0 to highlight the _material.setvector ("_colorthreshold", colorThreshold); Graphics.blit (temp1, temp2, _material, 0); Gaussian blur, two times blur, transverse longitudinal, gaussian blur _material.setvector using Pass1 ("_offsets", new Vector4 (0, samplerscale, 0, 0)); Graphics.blit (temp2, temp1, _material, 1); _material.setvector ("_offsets", New Vector4 (samplerscale, 0, 0, 0)); Graphics.blit (temp1, temp2, _material, 1); Bloom, The blurred figure is used as the blur parameter _material.settexture ("_blurtex", temp2) Material. _material.setvector ("_bloomcolor", bloomcolor); _material.setfloat ("_bloomfactor", bloomfactor); Use Pass2 for depth of field effect calculation, clear scene map directly from source input to shader _maintex graphics.blit (source, destination, _material, 2); Release the application of RT Rendertexture.releasetemporary (temp1); Rendertexture.releasetemporary (temp2); } }}
Shader section:
Shader "custom/bloomeffect" {properties{_maintex ("Base (RGB)", 2D) = "white" {}_blurtex ("Blur", 2D) = "white" {}} Cginclude#include "unitycg.cginc"//for threshold extraction highlight part of struct V2F_THRESHOLD{FLOAT4 pos:sv_position;float2 uv:texcoord0;};/ /for blurstruct v2f_blur{float4 pos:sv_position;float2 uv:texcoord0;float4 uv01:texcoord1;float4 Uv23:texcoord2;flo AT4 uv45:texcoord3;};/ /for bloomstruct v2f_bloom{float4 pos:sv_position;float2 uv:texcoord0;float2 uv1:texcoord1;}; sampler2d _maintex;float4 _maintex_texelsize;sampler2d _blurtex;float4 _blurtex_texelsize;float4 _offsets;float4 _ COLORTHRESHOLD;FLOAT4 _bloomcolor;float _bloomfactor;//highlight Partial extract shaderv2f_threshold vert_threshold (appdata_img v) {v2f _threshold O;o.pos = mul (unity_matrix_mvp, v.vertex); o.uv = v.texcoord.xy;//dx The texture from the upper-left corner is the initial coordinate, need to reverse # if UNITY_UV_STARTS_AT _topif (_maintex_texelsize.y < 0) o.uv.y = 1-o.uv.y; #endifreturn o;} Fixed4 frag_threshold (v2f_threshold i): sv_target{fixed4 color = tex2d (_maintex, i.uv);//output r only if color is greater than the set threshold valueEturn Saturate (color-_colorthreshold);} Gaussian Blur vert Shader (previous article with detailed comments) V2f_blur vert_blur (appdata_img v) {v2f_blur o;_offsets *= _maintex_texelsize.xyxy;o.pos = Mul (unity_matrix_mvp, v.vertex); o.uv = V.TEXCOORD.XY;O.UV01 = V.texcoord.xyxy + _offsets.xyxy * float4 (1, 1,-1,-1); o.uv2 3 = v.texcoord.xyxy + _offsets.xyxy * float4 (1, 1,-1,-1) * 2.0;o.uv45 = v.texcoord.xyxy + _offsets.xyxy * FLOAT4 (1, 1,- 1,-1) * 3.0;return o;} Gaussian Blur pixel shader (the Previous article has detailed comments) fixed4 frag_blur (v2f_blur i): sv_target{fixed4 color = fixed4 (0,0,0,0); Color + = 0.40 * Tex (_maintex, i.uv); Color + = 0.15 * tex2d (_maintex, i.uv01.xy); Color + = 0.15 * tex2d (_maintex, i.uv01.zw); Color + = 0.10 * t ex2d (_maintex, i.uv23.xy); Color + 0.10 * tex2d (_maintex, i.uv23.zw); Color + = 0.05 * tex2d (_maintex, i.uv45.xy); color + = 0 . * tex2d (_maintex, i.uv45.zw); return color;} Bloom effect vertex shaderv2f_bloom vert_bloom (appdata_img v) {v2f_bloom o;//mvp Matrix Transform o.pos = Mul (unity_matrix_mvp, V.vertex );//UV coordinate transfer o.uv.xy = V.texcoord.xy;o.uv1.xy = o.uv.xy; #if unity_uv_starts_at_topif (_maintex_texelsize.y < 0) o.uv.y = 1-o.uv.y; #endifreturn o;} Fixed4 frag_bloom (v2f_bloom i): sv_target{//take The original clear picture for UV sampling fixed4 ori = tex2d (_maintex, i.uv1);//take The fuzzy wafer for UV sampling fixed4 blur = tex2d (_blurtex, i.uv);//output = original image, overlay Bloom weight *bloom color * floodlight color FIXED4 final = ori + _bloomfactor * Blur * _bloomcolor;return final ;} Endcgsubshader{//pass 0: Extract Highlight part pass{ztest offcull offzwrite offfog{Mode Off}cgprogram#pragma vertex vert_threshold# pragma fragment frag_thresholdendcg}//pass 1: gaussian blur pass{ztest offcull offzwrite offfog{Mode Off}cgprogram#pragma Vertex v Ert_blur#pragma fragment Frag_blurendcg}//pass 2:bloom effect pass{ztest offcull offzwrite Offfog{Mode Off}CGPROGRAM#pragma Vertex Vert_bloom#pragma Fragment frag_bloomendcg}}}
Note: the Posteffectbase class is the base class for post-processing classes, which are described in more detail in the previous article and are no longer posted Here.
Four. Effect Display
Original picture Effect:
The bloom effect is turned on, the filter threshold is set to gray (128,128,128), the floodlight color is white (256,256,256), and the floodlight weight is 1:
The bloom effect is turned on, the filter threshold is set to gray (0,0,0), the floodlight color is white (256,256,256), and the floodlight weight is 1, an overexposed effect:
Turn on Bloom effect, filter threshold is set to gray (0,0,0), flood color is green (0,256,0), floodlight weight is 1, night vision Effect:
This article is mainly about the implementation of Full-screen floodlight, that is, the floodlight is only a full-screen color threshold to be set, more than the threshold of the color of the Pan-ray operation, otherwise it will not be flooded. This is more efficient, but there is no way to control the individual objects from being Flooded. There is also this bloom operation for individual objects, which can achieve a more detailed bloom effect, which can be referenced in this Article.
Unity shader-post-processing: Bloom Full-screen floodlight