Unity图像后期处理基本概念(post-processing effects)

发表于2019-01-03
评论0 8.5k浏览
图像效果处理

在unity中使用图像效果处理非常简单,用一个脚本使用OnRenderImage 方法并将该方法挂载在camera上面,OnRenderImage 有两个参数,第一个是unity传进来的图像(当前渲染的),第二个是目标纹理

这里一般使用一个shader对每个像素进行处理使用Graphics.Blit ,可以渲染的目标纹理中也可以渲染到自己创建的render texture中


OnRenderImage(RenderTexture src, RenderTexture dest)

src: 是当前渲染帧最后的图像,如果使用特性 ImageEffectOpaque 得到的是渲染不透明之后的帧图像

注意事项

一般使用 Graphics.Blit 渲染到目标纹理
1.如果不设置目标纹理,那么会直接渲染的back buffer(直接用于显示)
2.unity期望使用目标纹理的,所以我们Graphics.Blit 或者手动操作dest 应该是最后的操作
3.使用的shader 应该关闭一些操作 Cull Off ZWrite Off ZTest Always 这些应该是都有的
4.使用Graphics.SetRenderTarget.渲染到不同的目标中
5.如果使用纹理坐标来做一些计算的话注意不同平台的坐标可能不同平台相关信息
6.多个效果的话unity按照从脚本从上到下执行上一个的目标是下一个的source.如图所示


效果

来个简单的屏幕图片变灰的效果
效果图

关键代码
   //[ImageEffectOpaque]
    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        Shader sd = Shader.Find("Hidden/GreyPost");
        Material mt = new Material(sd);
        Graphics.Blit(source, destination, mt);
    }

shader
fixed4 frag (v2f i) : SV_Target
{
    fixed4 col = tex2D(_MainTex, i.uv);
    fixed grey = dot(col.rgb,fixed3(0.2,0.7,0.1));
    return fixed4(grey.xxx,1);
}

完整代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PostTest : MonoBehaviour {
    //[ImageEffectOpaque]
    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        Shader sd = Shader.Find("Hidden/GreyPost");
        Material mt = new Material(sd);
        Graphics.Blit(source, destination, mt);
    }
}

Shader "Hidden/GreyPost"
{
    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
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                // just invert the colors
                fixed grey = dot(col.rgb,fixed3(0.2,0.7,0.1));
                return fixed4(grey.xxx,1);
            }
            ENDCG
        }
    }
}

参考链接
https://docs.unity3d.com/Manual/PostProcessingWritingEffects.html
https://docs.unity3d.com/ScriptReference/Graphics.Blit.html
https://docs.unity3d.com/ScriptReference/Graphics.SetRenderTarget.html

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引