Unity3D学习笔记11——后处理
目录
1. 概述
一般来说,图形渲染引擎都会把帧缓冲(Framebuffer)技术封装成两个接口,其中之一就是后处理(Post-process)。直观来理解,后处理指的是场景在渲染完成之后,不进入屏幕的颜色缓冲区,而是暂时进入帧缓冲区;在对帧缓冲区的画面进行处理之后,再进入颜色缓冲区被屏幕显示出来。这个步骤只处理二维的画面,所以有点像图像处理的过程,或者可以看成对二维画面进行PS。
2. 详论
2.1. 实现
第一点需要明确的是,Unity后处理既不是写在脚本类MonoBehaviour的Start()中,也不是写在Update()中,而是写在专门的函数OnRenderImage()中。这是由内置渲染流水线决定的:在相机渲染整个场景完成之后,最后再进行全屏后期处理效果。因而,处理后处理的脚本,需要Camera组件。
在Unity中创建随意一个场景,创建一个脚本挂到Camera游戏对象上:
using UnityEngine; [ExecuteInEditMode] [RequireComponent(typeof(Camera))] public class Note11Main : MonoBehaviour { public Material material; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } private void OnRenderImage(RenderTexture source, RenderTexture destination) { Graphics.Blit(source, destination, material); } }
传入的材质使用的Shader为:
Shader "Custom/PostProcessingTest" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { // No culling or depth Cull Off ZWrite Off ZTest Always Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } sampler2D _MainTex; fixed4 frag (v2f i) : SV_Target { if(i.uv.x>0.5f) { discard; } fixed4 col = tex2D(_MainTex, i.uv); // just invert the colors col.rgb = 1 - col.rgb; return col; } ENDCG } } }
最终的效果为:
2.2. 解析
需要理解的是,后处理的Shader虽然大部分都是在片元着色器中写,但是后处理本质上还是一个或者多个渲染指令,只要是渲染指令,就要经过从顶点着色器到片元着色器的过程。实际上,后处理的一个指令就是绘制了一个屏幕大小的矩形,纹理是帧缓冲中存储的场景画面。理解这一点,才能理解后处理是一个全屏幕操作,与具体的三维物体无关。
在这个例子中,在片元着色器中把颜色取反,所以最终整个屏幕的颜色RGB颠倒了;设置纹理坐标在X方向上的值大于一半时不显示,所以整个屏幕的右边就不显示颜色。
可以在Frame Debug中看到这个后处理指令:
分类: Unity3D