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 color adjustment in Unity Shader post-processing

2025-02-21 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 color adjustment in Unity Shader post-processing", the content is easy to understand, clear, hope to help you solve your doubts, the following let Xiaobian lead you to study and learn "how to achieve simple color adjustment in Unity Shader post-processing" this article.

one。 Concept introduction

When we are playing games, although we now have Unity and other engines, we do not have to deal with some tedious things by ourselves, but in any case, some pixel information of RGB is finally displayed on the screen. Understanding these basic concepts will certainly be more helpful for us to play games.

1. The concept of color model

Since it is to correct the color of the screen, it is necessary to understand the concept of these attributes that we want to correct. Here we have to mention our commonly used color definition, RGB color model and HSV color model.

1.1RGB color model

RGB color model is our most commonly used three primary colors, red, green and blue. The RGB color model belongs to additive color mixing. The higher the value of each color in RGB, the brighter the color. Black when RBG is (255255255) and white when RGB is (255255255). When dealing with color information, computers generally use RGB color model, which can accurately represent a certain color.

1.2HSV color model

RGB color model for the computer is easy to calculate, but not suitable for human understanding, so there is the HSV color model, the so-called HSV represents Hue (hue), Saturation (saturation), Value (hue) there is also a view is HSB model, B represents Brightness (brightness). Of course, there are also some theories, such as the HSL model, where L stands for Lightness. The HSV model uses a conical coordinate system. The V (Value hue) corresponding to the top surface is 1, which indicates that the color is lighter, and the Value of the bottom surface is 0, which indicates that the color is dark. While H (Hue hue) is given by the rotation angle around the V axis, calculated counterclockwise from red, red corresponds to 0 degrees, green corresponds to 120 degrees, and blue corresponds to 240 degrees. S (Saturation saturation) is represented by the radius of the model, and the Saturation increases gradually from inside to outside, with 0 at the center and 1 at the edge. The following is an illustration of the HSV color model:

Transformation between 1.3RGB Color Model and HSV Color Model

Since both color models can represent colors, there must be some conversion relationship between the two.

Convert RGB to HSV model:

Suppose that RGB is represented by (rjournal gpenb) respectively, where rforce gpenb is the real number between 0 and 1 respectively; max is the maximum value in rreco gjournal b and min is the minimum; HSV is represented by (h), respectively, and s and v are real numbers between 0 and 1, respectively. The transformation relationship is as follows:

two。 Concepts of brightness, saturation, contrast, grayscale 2.1 brightness

The size of the RGB value in the image, the larger the RGB value, the brighter the brightness, the smaller the brightness, and the darker the brightness. For example, if we want to increase the brightness, we can directly increase the RGB value.

2.2 saturation

Refers to the purity of the color. Generally, the degree to which the color deviates from the same luminance gray is represented by the chromaticity divided by the lightness. To put it simply, when the color deviates from a certain value, it deviates from the grayscale and the saturation is greater; when the color is biased towards grayscale, the saturation is smaller.

Here is a definition of saturation in Baidu Encyclopedia:

Saturation refers to the bright degree of color, also known as the purity of color. The saturation depends on the proportion of the color component and the achromatic component (gray) in the color. The larger the color component is, the greater the saturation is, and the larger the achromatic component is, the smaller the saturation is. Pure colors are highly saturated, such as bright red and bright green. Colors mixed with white, gray or other tones are unsaturated colors, such as crimson purple, pink, yellowish brown, etc. Completely unsaturated colors have no hue at all, such as gray between black and white

2.3 contrast

It refers to the measurement of different luminance levels between the brightest white and the darkest black in an image. The larger the difference range is, the larger the contrast is, and the smaller the difference range is, the smaller the contrast is. Generally speaking, the greater the contrast, the clearer the image and the brighter the color, while the smaller the contrast, it will make the whole picture gray.

2.4 Gray level

Grayscale uses a black tone to represent an object, that is, black is used as the reference color and black with different saturation is used to display the image. Each grayscale object has a luminance value from 0% (white) to 100% (black).

Once we understand some basic color concepts, we can start to deal with them. First of all, let's take a look at the principle of Unity post-processing effect.

II. The principle of Unity screen post-processing

The so-called screen post-processing is simply the final stage of rendering pipeline, processing a picture generated by the whole scene, such as HDR, motion blur and so on. Through the post-processing of screen space, you can change the style or effect of the whole game as a whole. So, to make screen post-processing, we need two things, one is shader for rendering post-processing effects, and the other is that we need to call this rendering script, fortunately, Unity provides us with relevant functions.

1.OnRenderImage function

This function is provided in MonoBehaviour. It is called only after all rendering is completed, that is, a scene image is generated as mentioned above. The prototype of the function is as follows:

Void OnRenderImage (RenderTexture sourceTexture,RenderTexture destTexture)

RenderTexture represents render texture. We render objects not only in screen space, but also on specific textures, that is, RenderTexture. SourceTexture is the scene image we rendered, and destTexture is the target render texture. We can do the relevant post-processing effect in this function, using the material with post-processing effect shader to re-render the scene content.

2.Graphics.Blit function

This function is a function of Graphics and is used to copy the source texture to the target texture. The function prototype is as follows:

Public static void Blit (Texture source,RenderTexture dest); public static void Blit (Texture source,RenderTexture dest, Material mat, int pass =-1); public static void Blit (Texture source,Material mat, int pass =-1)

Source is the source texture and dest is the target texture. When dest is null, copy the source texture directly to the screen Mat is the material used when copying, that is, the material we use for post-processing. Unity will use this material to process and copy the source texture to the target texture. Pass is the pass used by the material shader used. We know that there may be multiple pass in a shader. Which pass can be used for processing can be passed in from this parameter. Of course, the default of-1 means that all pass will be executed.

After understanding the post-processing process of Untiy, we can start to write our brightness contrast saturation adjustment post-processing.

three。 Post-processing effect code

The post-processing effect needs two parts, namely the script part and the shader part. Let's take a look at them separately.

1. Script part

The post-processing script mainly does two things, the first is to get the shader you need to generate the material, and the second is to use the material to process the screen effect through OnRenderImage. The first step has some universality. No matter what the post-processing effect is, it must have the same operation, so we extract this step and create a base class PostEffectBase for the post-processing effect. The code is as follows:

Using UnityEngine; using System.Collections; / / non-runtime trigger effect [ExecuteInEditMode] / / screen post-processing effects generally need to be bound to the camera [RequireComponent (typeof (Camera))] / / provide a post-processing base class. The main function is to drag the shader directly through the Inspector panel to generate the material public class PostEffectBase corresponding to shader: MonoBehaviour {/ / Inspector panel directly drag public Shader shader = null Private Material _ material = null; public Material _ Material {get {if (_ material = = null) _ material = GenerateMaterial (shader); return _ material }} / / create a material protected Material GenerateMaterial (Shader shader) {if (shader = = null) return null; / / based on shader for screen special effects. You need to determine whether shader supports if (shader.isSupported = = false) return null; Material material = new Material (shader); material.hideFlags = HideFlags.DontSave If (material) return material; return null;}}

Then, all of our post-processing scripts can inherit this class of PostEffectBase, and automatically have the ability to generate post-processing materials through shader.

Next is the script for brightness, saturation and contrast adjustment in this article. The script is very simple. The main function is to set several parameters. After overriding the OnRenderImage function, the parameters are passed to shader in real time, and then the post-processing effect is completed through the Blit function. The code is as follows:

Using UnityEngine; using System.Collections; / / inherits from PostEffectBase public class ColorAdjustEffect: PostEffectBase {/ / controls the range of parameters that can be entered by Range [Range (0.0f, 3.0f)] public float brightness = 1.0f public float saturation / brightness [Range (0.0f, 3.0f)] public float contrast = 1.0f / contrast [Range (0.0f, 3.0f)] public float saturation = 1.0f / / saturation / / override the OnRenderImage function void OnRenderImage (RenderTexture src, RenderTexture dest) {/ / Post-processing is performed only when there is a material, if _ Material is empty Without post-processing if (_ Material) {/ / the parameter value _ Material.SetFloat ("_ Brightness", brightness) in shader can be set through Material.SetXXX ("name", value). _ Material.SetFloat ("_ Saturation", saturation); _ Material.SetFloat ("_ Contrast", contrast); / / using Material to process Texture,dest is not necessarily a screen, and the post-processing effect can be superimposed! Graphics.Blit (src, dest, _ Material);} else {/ / directly draw Graphics.Blit (src, dest);}

In this way, our post-processing script is complete. The following knowledge points are involved:

1. You can use [Range (min,max)] to control the values in the Inspector panel, limit their range, and provide slider control.

The 2.OnRenderImage function is executed after rendering all the contents of each frame. We set the parameters of Material in each frame, and we can pass various parameters to shader through Material.SetXXX ("name", value).

3. Various post-processing effects can be superimposed, and the dest here is not necessarily a screen. However, post-processing is very performance-consuming, on the one hand, pixel shader full-screen overdraw, on the other hand, a rendertexture takes up a lot of memory, especially on high-resolution mobile phones, multiple post-processing effects may cause memory depletion and program crash.

2.shader part

Finally getting to the point, let's take a look at the shader of the post-processing effect. Because the post-processing effect is for the rendering of a scene, there is basically nothing to say about vertex shader, and most of the post-processing is based on pixel shader. Let's sort out our ideas first:

The simplest is the brightness, we can directly sample the texture by multiplying a coefficient to achieve the purpose of magnifying or reducing the RGB value, so we can adjust the brightness.

The second is the saturation, the greater the deviation from the gray scale, the greater the saturation, we can first calculate the lowest saturation value under the same luminance condition, according to the formula: gray = 0.2125 * r + 0.7154 * g + 0.0721 * b (the formula should be an empirical formula), and then we use a coefficient difference between the value and the original image to achieve the purpose of adjusting the saturation.

Finally, there is contrast, which means that the greater the color difference, the stronger the contrast. When the color is pure gray, that is, (0.5 ~ 0.5 ~ 0.5), the contrast is the smallest. We pass the coefficient difference between the image with the smallest contrast and the original image to achieve the purpose of adjusting the contrast. The code is as follows:

/ / shader directory Shader "Custom/ColorAdjustEffect" {/ / attribute block, attributes used by shader You can directly adjust Properties {_ MainTex ("Albedo (RGB)", 2D) = "white" {} _ Brightness ("Brightness", Float) = 1 _ Saturation ("Saturation", Float) = 1 _ Contrast ("Contrast", Float) = 1} / / each shader has Subshaer. There is a parallel relationship between each subshaer, and only one subshader can be run. It is Pass that works mainly for different hardware SubShader {/ /. There may be different pass in one shader, and you can execute multiple pass Pass {/ / to set some rendering states. The content of ZTest Always Cull Off ZWrite Off CGPROGRAM / / in Properties is only for use by Inspector panel without detailed explanation here. The real statement is here. Note that it is consistent with the above sampler2D _ MainTex. Half _ Brightness; half _ Saturation; half _ Contrast / / vert and frag function # pragma vertex vert # pragma fragment frag # include "Lighting.cginc" / / pass the parameter struct v2f {float4 pos: SV_POSITION of pixel shader from vertex shader / / Vertex position half2 uv: TEXCOORD0; / / UV coordinates}; / / vertex shader / / appdata_img: Vertex shader with position and a texture coordinate input v2f vert (appdata_img v) {v2f o / / change from one's own space to the projection space o.pos = mul (UNITY_MATRIX_MVP, v.vertex); / / uv coordinates are assigned to output o.uv = v. text; return o } / / fragment shader fixed4 frag (v2f I): SV_Target {/ / sample from _ MainTex according to uv coordinates fixed4 renderTex = tex2D (_ MainTex, i.uv) / / brigtness brightness is directly multiplied by a coefficient, that is, RGB is scaled as a whole, and brightness fixed3 finalColor = renderTex * _ Brightness is adjusted. / / saturation saturation: first, calculate the lowest saturation value under the same luminance according to the formula: fixed gray = 0.2125 * renderTex.r + 0.7154 * renderTex.g + 0.0721 * renderTex.b; fixed3 grayColor = fixed3 (gray, gray, gray) / / according to the difference of Saturation between the lowest saturation image and the original image finalColor = lerp (grayColor, finalColor, _ Saturation); / / contrast contrast: first calculate the lowest contrast value fixed3 avgColor = fixed3 (0.5,0.5,0.5) / / according to the difference of Contrast between the image with the lowest contrast and the original image finalColor = lerp (avgColor, finalColor, _ Contrast); / / returns the result, alpha channel unchanged return fixed4 (finalColor, renderTex.a) } ENDCG} / / safeguard measures to prevent shader failure FallBack Off} IV. Effect display

After completing the shader and post-processing scripts, we can create a scene, hang the script under the MainCamera of the scene, and then assign the shader of ColorAdjustEffect to the shader slot of the script, as shown in the following figure:

First, set the brightness, contrast, and saturation to 1, and the scene is as follows:

The image effect of adjusting the brightness is as follows:

The effect of adjusting the contrast is as follows:

The adjustment of saturation is shown below:

The above is all the content of this article "how to achieve simple color adjustment 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