• 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
            }
        }
    }
    

    最终的效果为:
    imglink1

    2.2. 解析

    需要理解的是,后处理的Shader虽然大部分都是在片元着色器中写,但是后处理本质上还是一个或者多个渲染指令,只要是渲染指令,就要经过从顶点着色器到片元着色器的过程。实际上,后处理的一个指令就是绘制了一个屏幕大小的矩形,纹理是帧缓冲中存储的场景画面。理解这一点,才能理解后处理是一个全屏幕操作,与具体的三维物体无关。

    在这个例子中,在片元着色器中把颜色取反,所以最终整个屏幕的颜色RGB颠倒了;设置纹理坐标在X方向上的值大于一半时不显示,所以整个屏幕的右边就不显示颜色。

    可以在Frame Debug中看到这个后处理指令:
    imglink2

    代码地址

  • 相关阅读:
    华为OD机试 - 压缩报文还原 - 正则表达式(Java 2023 B卷 100分)
    关于白盒测试,这些技巧你得游刃有余~
    php 家政服务管理系统
    剑指offer 08. 用两个栈实现队列
    谣言检测(PSIN)——《Divide-and-Conquer: Post-User Interaction Network for Fake News Detection on Social Media》
    【Java】SE练习项目 —》图书管理系统
    常见的 web 安全问题总结
    2-11 基于matlab的BP-Adaboost的强分类器分类预测
    Argo CD入门、实战指南
    三维GIS的业务导向
  • 原文地址:https://www.cnblogs.com/charlee44/p/16578062.html