313 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			313 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								## BrightnessSaturationAndContrast
							 | 
						|||
| 
								 | 
							
								### 给摄像机添加脚本
							 | 
						|||
| 
								 | 
							
								添加2个Meta,让其可以在编辑器模式下运行,并且只能绑定Camera组件。
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								[ExecuteInEditMode]
							 | 
						|||
| 
								 | 
							
								[RequireComponent(typeof(Camera))]
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								实现基础类
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								using UnityEngine;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								[ExecuteInEditMode]
							 | 
						|||
| 
								 | 
							
								[RequireComponent(typeof(Camera))]
							 | 
						|||
| 
								 | 
							
								public class PostEffectsBase : MonoBehaviour
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    protected void CheckResources()
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        bool isSupported = CheckSupport();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (isSupported == false)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            NotSupported();
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    protected bool CheckSupport()
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        if (SystemInfo.supportsImageEffects == false || SystemInfo.supportsRenderTextures == false)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            Debug.LogWarning("Not Supported!");
							 | 
						|||
| 
								 | 
							
								            return false;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        return true;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    protected void NotSupported()
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        enabled = false;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    protected Material CheckShaderAndCreateMaterial(Shader shader, Material material)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        if (shader == null)
							 | 
						|||
| 
								 | 
							
								            return null;
							 | 
						|||
| 
								 | 
							
								        if (shader.isSupported && material && material.shader == shader)
							 | 
						|||
| 
								 | 
							
								            return material;
							 | 
						|||
| 
								 | 
							
								        if (!shader.isSupported)
							 | 
						|||
| 
								 | 
							
								            return null;
							 | 
						|||
| 
								 | 
							
								        else
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            material = new Material(shader);
							 | 
						|||
| 
								 | 
							
								            material.hideFlags = HideFlags.DontSave;
							 | 
						|||
| 
								 | 
							
								            if (material)
							 | 
						|||
| 
								 | 
							
								                return material;
							 | 
						|||
| 
								 | 
							
								            else
							 | 
						|||
| 
								 | 
							
								                return null;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    protected void Start()
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        CheckResources();
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								之后根据需求在子类中添加变量:
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								using UnityEngine;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								public class BrightnessSaturationAndContrast : PostEffectsBase
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    [Range(0.0f, 3.0f)]
							 | 
						|||
| 
								 | 
							
								    public float brightness = 1.0f;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    [Range(0.0f, 3.0f)]
							 | 
						|||
| 
								 | 
							
								    public float saturation = 1.0f;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    [Range(0.0f, 3.0f)]
							 | 
						|||
| 
								 | 
							
								    public float contrast = 1.0f;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public Shader briSatConShader;
							 | 
						|||
| 
								 | 
							
								    private Material briSatConMaterial;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public Material material
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        get
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            briSatConMaterial = CheckShaderAndCreateMaterial(briSatConShader, briSatConMaterial);
							 | 
						|||
| 
								 | 
							
								            return briSatConMaterial;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    private void OnRenderImage(RenderTexture src, RenderTexture dest)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        if (material != null)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            material.SetFloat("_Brightness", brightness);
							 | 
						|||
| 
								 | 
							
								            material.SetFloat("_Saturation", saturation);
							 | 
						|||
| 
								 | 
							
								            material.SetFloat("_Contrast", contrast);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            Graphics.Blit(src, dest, material);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            Graphics.Blit(src, dest);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								最后在OnRenderImage中调用Graphics.Blit()进行渲染。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### 添加后处理Shader
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								Shader "PostProcess/BrightnessSaturationAndContrast" {
							 | 
						|||
| 
								 | 
							
									
							 | 
						|||
| 
								 | 
							
									Properties {
							 | 
						|||
| 
								 | 
							
										_MainTex ("Base", 2D) = "white" {}
							 | 
						|||
| 
								 | 
							
								        _Brightness("Brightness",Float)=1
							 | 
						|||
| 
								 | 
							
								        _Saturation("Saturation",Float)=1
							 | 
						|||
| 
								 | 
							
								        _Contrast("Constrast",Float)=1
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									SubShader {
							 | 
						|||
| 
								 | 
							
								        Pass{
							 | 
						|||
| 
								 | 
							
								            ZTest Always Cull Off ZWrite Off
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            CGPROGRAM
							 | 
						|||
| 
								 | 
							
								            #pragma vertex vert
							 | 
						|||
| 
								 | 
							
								            #pragma fragment frag
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            #include "UnityCG.cginc"
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            sampler2D _MainTex;
							 | 
						|||
| 
								 | 
							
								            half _Brightness;
							 | 
						|||
| 
								 | 
							
								            half _Saturation;
							 | 
						|||
| 
								 | 
							
								            half _Contrast;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            struct v2f{
							 | 
						|||
| 
								 | 
							
								                float4 pos : SV_POSITION;
							 | 
						|||
| 
								 | 
							
								                half2 uv : TEXCOORD0;
							 | 
						|||
| 
								 | 
							
								            };
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            v2f vert(appdata_img v)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                v2f o;
							 | 
						|||
| 
								 | 
							
								                o.pos = UnityObjectToClipPos(v.vertex);
							 | 
						|||
| 
								 | 
							
								                o.uv=v.texcoord;
							 | 
						|||
| 
								 | 
							
								                return o;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            fixed4 frag(v2f i) : SV_Target{
							 | 
						|||
| 
								 | 
							
								                fixed4 renderTex=tex2D(_MainTex,i.uv);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                fixed3 finalColor=renderTex.rgb * _Brightness;
							 | 
						|||
| 
								 | 
							
								                fixed luminance=0.2125*renderTex.r+0.7154*renderTex.g+0.0721*renderTex.b;
							 | 
						|||
| 
								 | 
							
								                fixed3 luminanceColor=fixed3(luminance,luminance,luminance);
							 | 
						|||
| 
								 | 
							
								                finalColor =lerp(luminanceColor,finalColor,_Saturation);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                fixed3 avgColor=fixed3(0.5,0.5,0.5);
							 | 
						|||
| 
								 | 
							
								                finalColor=lerp(avgColor,finalColor,_Contrast);
							 | 
						|||
| 
								 | 
							
								                return fixed4(finalColor,renderTex.a);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            ENDCG
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    Fallback Off
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## 高斯模糊
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								与之前不同,这里利用RenderTexture.GetTemporary函数分配了一块与屏幕图像大小相同的缓冲区。这是因为,高斯模糊需要调用两个Pass,我们需要使用一块中间缓存来存储第一个Pass执行完毕后得到的模糊结果。`RenderTexture buffer = RenderTexture.GetTemporary(rtW, rtH, 0);`我们首先调用`Graphics.Blit(src, buffer, material, 0),`使用Shader中的第一个pass对src进行处理,并将结果存储在了buffer中。然后在调用`Graphics.Blit(src, buffer, material, 1)`,使用Shader中的第二个Pass对buffer进行处理,返回最终的屏幕图像。最后,我们还需要调用`RenderTexture.ReleaseTemporary`来释放之前分配的缓存。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								private void OnRenderImage(RenderTexture src, RenderTexture dest)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    if (material != null)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        int rtW = src.width;
							 | 
						|||
| 
								 | 
							
								        int rtH = src.height;
							 | 
						|||
| 
								 | 
							
								        RenderTexture buffer = RenderTexture.GetTemporary(rtW, rtH, 0);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        Graphics.Blit(src, buffer, material, 0);
							 | 
						|||
| 
								 | 
							
								        Graphics.Blit(buffer, dest, material, 1);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        RenderTexture.Release(buffer);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    else
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        Graphics.Blit(src, dest);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								实现降采样:
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								private void OnRenderImage(RenderTexture src, RenderTexture dest)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    if (material != null)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        int rtW = src.width / downSample;
							 | 
						|||
| 
								 | 
							
								        int rtH = src.height / downSample;
							 | 
						|||
| 
								 | 
							
								        RenderTexture buffer = RenderTexture.GetTemporary(rtW, rtH, 0);
							 | 
						|||
| 
								 | 
							
								        buffer.filterMode=FilterMode.Bilinear;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        Graphics.Blit(src, buffer, material, 0);
							 | 
						|||
| 
								 | 
							
								        Graphics.Blit(buffer, dest, material, 1);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        RenderTexture.Release(buffer);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    else
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        Graphics.Blit(src, dest);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								### CGINCLUDE
							 | 
						|||
| 
								 | 
							
								使用CGINCLUDE与ENDCG关键字将通用部分引用给其他Pass
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								Shader "Unity Shaders Book/Chapter 12/Gaussian Blur" {
							 | 
						|||
| 
								 | 
							
									Properties {
							 | 
						|||
| 
								 | 
							
										_MainTex ("Base (RGB)", 2D) = "white" {}
							 | 
						|||
| 
								 | 
							
										_BlurSize ("Blur Size", Float) = 1.0
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									SubShader {
							 | 
						|||
| 
								 | 
							
										CGINCLUDE
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										#include "UnityCG.cginc"
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										sampler2D _MainTex;  
							 | 
						|||
| 
								 | 
							
										half4 _MainTex_TexelSize;
							 | 
						|||
| 
								 | 
							
										float _BlurSize;
							 | 
						|||
| 
								 | 
							
										  
							 | 
						|||
| 
								 | 
							
										struct v2f {
							 | 
						|||
| 
								 | 
							
											float4 pos : SV_POSITION;
							 | 
						|||
| 
								 | 
							
											half2 uv[5]: TEXCOORD0;
							 | 
						|||
| 
								 | 
							
										};
							 | 
						|||
| 
								 | 
							
										  
							 | 
						|||
| 
								 | 
							
										v2f vertBlurVertical(appdata_img v) {
							 | 
						|||
| 
								 | 
							
											v2f o;
							 | 
						|||
| 
								 | 
							
											o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
							 | 
						|||
| 
								 | 
							
											
							 | 
						|||
| 
								 | 
							
											half2 uv = v.texcoord;
							 | 
						|||
| 
								 | 
							
											
							 | 
						|||
| 
								 | 
							
											o.uv[0] = uv;
							 | 
						|||
| 
								 | 
							
											o.uv[1] = uv + float2(0.0, _MainTex_TexelSize.y * 1.0) * _BlurSize;
							 | 
						|||
| 
								 | 
							
											o.uv[2] = uv - float2(0.0, _MainTex_TexelSize.y * 1.0) * _BlurSize;
							 | 
						|||
| 
								 | 
							
											o.uv[3] = uv + float2(0.0, _MainTex_TexelSize.y * 2.0) * _BlurSize;
							 | 
						|||
| 
								 | 
							
											o.uv[4] = uv - float2(0.0, _MainTex_TexelSize.y * 2.0) * _BlurSize;
							 | 
						|||
| 
								 | 
							
													 
							 | 
						|||
| 
								 | 
							
											return o;
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										v2f vertBlurHorizontal(appdata_img v) {
							 | 
						|||
| 
								 | 
							
											v2f o;
							 | 
						|||
| 
								 | 
							
											o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
							 | 
						|||
| 
								 | 
							
											
							 | 
						|||
| 
								 | 
							
											half2 uv = v.texcoord;
							 | 
						|||
| 
								 | 
							
											
							 | 
						|||
| 
								 | 
							
											o.uv[0] = uv;
							 | 
						|||
| 
								 | 
							
											o.uv[1] = uv + float2(_MainTex_TexelSize.x * 1.0, 0.0) * _BlurSize;
							 | 
						|||
| 
								 | 
							
											o.uv[2] = uv - float2(_MainTex_TexelSize.x * 1.0, 0.0) * _BlurSize;
							 | 
						|||
| 
								 | 
							
											o.uv[3] = uv + float2(_MainTex_TexelSize.x * 2.0, 0.0) * _BlurSize;
							 | 
						|||
| 
								 | 
							
											o.uv[4] = uv - float2(_MainTex_TexelSize.x * 2.0, 0.0) * _BlurSize;
							 | 
						|||
| 
								 | 
							
													 
							 | 
						|||
| 
								 | 
							
											return o;
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										fixed4 fragBlur(v2f i) : SV_Target {
							 | 
						|||
| 
								 | 
							
											float weight[3] = {0.4026, 0.2442, 0.0545};
							 | 
						|||
| 
								 | 
							
											
							 | 
						|||
| 
								 | 
							
											fixed3 sum = tex2D(_MainTex, i.uv[0]).rgb * weight[0];
							 | 
						|||
| 
								 | 
							
											
							 | 
						|||
| 
								 | 
							
											for (int it = 1; it < 3; it++) {
							 | 
						|||
| 
								 | 
							
												sum += tex2D(_MainTex, i.uv[it*2-1]).rgb * weight[it];
							 | 
						|||
| 
								 | 
							
												sum += tex2D(_MainTex, i.uv[it*2]).rgb * weight[it];
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
											
							 | 
						|||
| 
								 | 
							
											return fixed4(sum, 1.0);
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
										    
							 | 
						|||
| 
								 | 
							
										ENDCG
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										ZTest Always Cull Off ZWrite Off
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										Pass {
							 | 
						|||
| 
								 | 
							
											NAME "GAUSSIAN_BLUR_VERTICAL"
							 | 
						|||
| 
								 | 
							
											
							 | 
						|||
| 
								 | 
							
											CGPROGRAM
							 | 
						|||
| 
								 | 
							
											  
							 | 
						|||
| 
								 | 
							
											#pragma vertex vertBlurVertical  
							 | 
						|||
| 
								 | 
							
											#pragma fragment fragBlur
							 | 
						|||
| 
								 | 
							
											  
							 | 
						|||
| 
								 | 
							
											ENDCG  
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										Pass {  
							 | 
						|||
| 
								 | 
							
											NAME "GAUSSIAN_BLUR_HORIZONTAL"
							 | 
						|||
| 
								 | 
							
											
							 | 
						|||
| 
								 | 
							
											CGPROGRAM  
							 | 
						|||
| 
								 | 
							
											
							 | 
						|||
| 
								 | 
							
											#pragma vertex vertBlurHorizontal  
							 | 
						|||
| 
								 | 
							
											#pragma fragment fragBlur
							 | 
						|||
| 
								 | 
							
											
							 | 
						|||
| 
								 | 
							
											ENDCG
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
									} 
							 | 
						|||
| 
								 | 
							
									FallBack "Diffuse"
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```
							 |