Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize simple mean fuzzy in Unity Shader post-processing

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly shows you "how to achieve simple mean ambiguity in Unity Shader post-processing", the content is easy to understand, clear, hope to help you solve doubts, the following let the editor lead you to study and learn "how to achieve simple mean ambiguity in Unity Shader post-processing" this article.

one。 Brief introduction

A commonly used effect in post-processing is the screen blur effect. Blur effect is often used in image processing, and there are similar filters in Photoshop. We also often use it in the game. Because the screen blur effect is the basis of some advanced post-processing effects, such as depth of field, we first take a look at the screen blur effect, and then through the screen blur, further learn the realization of depth of field effect and motion blur effect.

The so-called blur, that is, is not clear, a clear picture, there will be an obvious transition between the pixels, and if the gap between the pixels is not very large, then the image will be blurred, in extreme cases, when the color of all the pixels in a picture is the same, then the picture is a solid color picture. Blur operation is to reduce the color gap between pixels, such as point An is red, the point around point An is green, blurring is like using a brush to mix the color of point A with the surrounding points to become the final color. And how to mix, according to different weights, can achieve different results. Such as mean ambiguity, and the famous Gaussian blur.

The important factor affecting the fuzzy degree is the fuzzy radius. The larger the fuzzy radius is, the greater the fuzzy degree is, and the smaller the fuzzy radius is, the smaller the fuzzy degree is. So, what is the blur radius? The so-called blur radius is a range that we sample, for example, our blur radius is very small, just mixing the pixel with a circle of fixed points around it, then the degree of blur is very small, and if we increase the blur radius, in the extreme, each vertex takes all the surrounding points, that is, the average pixel of the whole picture, then the color of this picture will be biased to one color.

two。 Mean ambiguity

At its simplest, let's take a look at the simple blur, which is directly averaged by the surrounding pixels, and the weight of the final image we mix at some point is only related to the blur radius. In other words, for example, if the blur radius is 1, then let's take a pixel and a circle of pixels around it, a total of nine points, and take the average directly, then the weight of each point is set to 1 pixel 9. This is also known as mean ambiguity. Let's look at an example of mean ambiguity.

Shader section:

Shader "Custom/SimpleBlurEffect" {Properties {_ MainTex ("Base (RGB)", 2D) = "white" {}} / / through CGINCLUDE we can predefine some of the following struct and functions used in Pass, / / so that you only need to set the rendering state and call functions in pass, and shader makes the CGINCLUDE / / cg file more concise and clear. Contains some cg functions built into unity # include "UnityCG.cginc" / / blur structure, which is passed from the vert function of blur to the parameter struct v2f_blur {float4 pos: SV_POSITION of the frag function / / Vertex position float2 uv: TEXCOORD0; / / texture coordinates float2 uv1: TEXCOORD1; / / surrounding texture 1 float2 uv2: TEXCOORD2; / / surrounding texture 2 float2 uv3: TEXCOORD3; / / surrounding texture 3 float2 uv4: TEXCOORD4; / / surrounding texture 4}; / / variable sampler2D _ texture used / / the pixel-dependent size of the XX_TexelSize,XX texture width,height corresponds to the resolution of the texture, x = 1/width, y = 1/height, z = width, w = height float4 _ MainTex_TexelSize; / / float _ BlurRadius; / / vertex shader v2f_blur vert_blur (appdata_img v) {v2f_blur o; o.pos = mul (UNITY_MATRIX_MVP, v.vertex) O.uv = v.texcoord.xyx; / / calculate the left and right points of the uv for the uv coordinates under the blur radius o.uv1 = v.texcoord.xy + _ BlurRadius * _ MainTex_TexelSize * float2 (1,1); o.uv2 = v.texcoord.xy + _ BlurRadius * _ MainTex_TexelSize * float2 (- 1,1) O.uv3 = v.texcoord.xy + _ BlurRadius * _ MainTex_TexelSize * float2 (- 1,-1); o.uv4 = v.texcoord.xy + _ BlurRadius * _ MainTex_TexelSize * float2 (1,-1); return o;} / / fragment shader fixed4 frag_blur (v2f_blur I): SV_Target {fixed4 color = fixed4 Color + = tex2D (_ MainTex, i.uv); color + = tex2D (_ MainTex, i.uv1); color + = tex2D (_ MainTex, i.uv2); color + = tex2D (_ MainTex, i.uv3); color + = tex2D (_ MainTex, i.uv4); / / Additive average, it is said that shader multiplication is faster return color * 0.2 } ENDCG / / child shader SubShader {/ / pass 0: blur effect Pass {ZTest Always Cull Off ZWrite Off Fog {Mode Off} / / directly call vert_blur and frag_blur CGPROGRAM # pragma vertex vert_blur # pragma fragment frag_blur ENDCG}

C # script part:

Using UnityEngine; using System.Collections; / / also runs [ExecuteInEditMode] / / inherits from PostEffectBase public class SimpleBlurEffect: PostEffectBase {/ / blur radius public float BlurRadius = 1.0f; void OnRenderImage (RenderTexture source, RenderTexture destination) {if (_ Material) {/ / blur _ Material.SetFloat ("_ BlurRadius", BlurRadius) Graphics.Blit (source, destination, _ Material);}

Note that PostEffectBase here is the base class for various post-processing effects, and there is a complete implementation of this class in the previous article: Unity Shader- post-processing: simple color adjustment (brightness, saturation, contrast), and no code is posted here.

The effect is shown in the following figure:

Original picture effect

BlurRadius = 1

BlurRadius = 5

From the blur effect above, we can see that the larger the blur radius, the more obvious the blur effect. But! This effect looks uncomfortable at all, there is a kind of nearsightedness, it is not a smooth blur effect at all, let alone a further full blur effect such as ground glass.

three。 Improvement of mean ambiguity

Since we feel that the effect of one blur is not very satisfactory, we can try to iterate the blur, that is, use the output of the previous blur as the input of the next blur, and the fuzzy effect after iteration is more obvious. Take a look at the code first. This time, our shader code remains the same as above, just modified the script and added two operations of resolution reduction and iteration.

Using UnityEngine; using System.Collections; / / also runs [ExecuteInEditMode] / / inherits from PostEffectBase public class SimpleBlurEffect: PostEffectBase {/ / blur radius public float BlurRadius = 1.0f; / / reduced resolution public int downSample = 2; / / iterations public int iteration = 3 Void OnRenderImage (RenderTexture source, RenderTexture destination) {if (_ Material) {/ / the resolution of applying RenderTexture,RT is reduced according to downSample RenderTexture rt1 = RenderTexture.GetTemporary (source.width > > downSample, source.height > > downSample, 0, source.format); RenderTexture rt2 = RenderTexture.GetTemporary (source.width > > downSample, source.height > > downSample, 0, source.format) / / directly copy the original image to the reduced resolution RT Graphics.Blit (source, rt1); / / iterate, perform two blurring operations in one iteration, and use two RT to cross process the for (int I = 0; I < iteration). Material.SetFloat ("_ BlurRadius", BlurRadius); Graphics.Blit (rt1, rt2, _ Material); Graphics.Blit (rt2, rt1, _ Material) } / / copy the result to the target RT Graphics.Blit (rt1, destination); / / release the application's two pieces of RenderBuffer content RenderTexture.ReleaseTemporary (rt1); RenderTexture.ReleaseTemporary (rt2);}

The results are as follows:

BlurRadius = 1, downSample = 2, iteration = 3

BlurRadius = 1, downSample = 2, iteration = 5

We can see that through iteration and reducing the resolution, our blur effect is more obvious, when the number of iterations is larger, there will be a kind of ground glass effect. Here, although the number of iterations increases, it will consume more performance, but accordingly, we also reduce the resolution and reduce the consumption of computing operations such as sampling.

IV. Introduction to RenderTexture

Here, we have completed the blur operation through multiple processing, including resolution reduction and iteration, and here we need to temporarily store the last processed intermediate output, so we need to use a concept commonly used in rendering, RenderTexture.

With regard to RenderTexture, let's briefly introduce that when we render a scene, we usually output it directly to the frame cache and then to the screen. However, sometimes we don't want to output the result directly, but we need to process the rendered result, so we output the rendered result to a texture, that is, RenderTexture, which is the basis of all post-processing. Unity RenderTexture is still very easy to use, we can not only use in post-processing, but also by setting the camera output to a certain RT, and then using this RT as some mirror-like object, we can achieve mirror effect or screen effect.

However, RenderTexture is still very resource-consuming. A large RenderTexture is a picture with a screen resolution, and it cannot be compressed at all, so when RenderTexture is used more in post-processing, it consumes a lot of memory. In mobile phones, especially large-screen phones, when the memory is relatively small, the superposition of post-processing is likely to collapse due to memory exhaustion. Therefore, we need to consider carefully when using RenderTexture. If the effect is acceptable, we can consider reducing the resolution of the RenderTexture, so that the output effect may be reduced, but the performance will be greatly improved. And our blur effect, reducing the resolution itself will lead to blurred picture, so here, we can rest assured to boldly reduce the resolution of RT, which can not only improve the effect, but also greatly reduce the cost.

There is another point here. Since the OnRenderImage function is called before rendering, I was worried about whether I would apply for RT here for every frame and release it. Would there be a very high GC? After looking up some information, it is found that Unity has been processed here, and RenderTexture is a previously applied memory area, which we can use directly without considering the problem of GC, just like the names of these two functions, RenderTexture.GetTemporary and RenderTexture.ReleaseTemporary. Moreover, I tested it myself and hung up the script using Profile, and found that there was no GC:

These are all the contents of the article "how to achieve simple mean ambiguity in Unity Shader post-processing". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report