文章目录
- 前言
- 一、我们先创建一个默认的后处理Shader,用于脚本测试
- 二、在脚本中使用Graphics.Blit();
- 1、我们先公开一个材质,用于测试后处理效果
- 2、因为在实际开发中,我们不可能为每一个后处理Shader创建对应的材质球。所以,需要对该脚本进行修改,让脚本直接使用Shader
- 三、后处理Shader
- 1、后处理Shader需要遵守的条件
- 2、后处理效果 几乎都是 在片元着色器中实现的
- 3、这是简化后的 后处理Shader代码
- 三、最终测试脚本
前言
我们在上篇文章中提到,在Unity中实现后处理效果,需要同时结合 脚本 和 Shader,我们在这篇文章中编写所需要使用的C#脚本 和 Shader。
- Unity中后处理简介
一、我们先创建一个默认的后处理Shader,用于脚本测试
- 在该Shader的片元着色器中,我们可以看出,这个Shader主要做了一个反色处理。
二、在脚本中使用Graphics.Blit();
该语句需要在OnRenderImage生命周期函数内使用。
而该生命周期只对我们的摄像机生效
1、我们先公开一个材质,用于测试后处理效果
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//后处理脚本
public class P2_7_3 : MonoBehaviour
{
public Material Mat;
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
Graphics.Blit(source,destination,Mat);
}
}
-
把该脚本挂载在摄像机上
-
开启游戏后,我们看见我们的后处理Shader生效了
2、因为在实际开发中,我们不可能为每一个后处理Shader创建对应的材质球。所以,需要对该脚本进行修改,让脚本直接使用Shader
- 创建一个公共成员变量,用于接收Shader
public Shader PostProcessingShader;
- 创建一个成员属性,对其get方法进行修改,使其返回一个用我们Shader创建的材质
private Material mat;
public Material Mat
{
get
{
if (PostProcessingShader == null)
{
Debug.LogError("没有赋予Shader");
return null;
}
if (!PostProcessingShader.isSupported)
{
Debug.LogError("当前Shader不支持");
return null;
}
Material _newMaterial = new Material(PostProcessingShader);
_newMaterial.hideFlags = HideFlags.HideAndDontSave;
return _newMaterial;
}
}
- 把我们的脚本挂载在摄像机,把Shader赋予脚本,我们看看效果
- 使用[ExecuteInEditMode]特性给我们的Mono脚本,能使我们的脚本在编辑器模式下运行。
三、后处理Shader
1、后处理Shader需要遵守的条件
因为,后处理效果处理的是摄像机前的一个面片效果。
所以,是不需要面片剔除 和 深度效果的。需要把这两个功能相关的东西关闭,防止影响处理后的效果
Cull Off
ZWrite Off
ZTest Always
2、后处理效果 几乎都是 在片元着色器中实现的
因为后处理效果几乎都是在片元着色器中实现。所以,其余部分的功能几乎都没有变化。Unity对此进行了一些优化,我们可以直接使用。
- Unity在 UnityCG.cginc 中帮我们定义了后处理中常用的 appdata 结构体
- Unity在 UnityCG.cginc 中帮我们定义了后处理中常用的 v2f 结构体
- Unity在 UnityCG.cginc 中帮我们定义了后处理中常用的 顶点着色器
3、这是简化后的 后处理Shader代码
Shader "Hidden/P2_7_4"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
// No culling or depth
Cull Off
ZWrite Off
ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
fixed4 frag (v2f_img i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
// just invert the colors
col.rgb = 1 - col.rgb;
return col;
}
ENDCG
}
}
}
三、最终测试脚本
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//后处理脚本
public class P2_7_3 : MonoBehaviour
{
public Shader PostProcessingShader;
private Material mat;
public Material Mat
{
get
{
if (PostProcessingShader == null)
{
Debug.LogError("没有赋予Shader");
return null;
}
if (!PostProcessingShader.isSupported)
{
Debug.LogError("当前Shader不支持");
return null;
}
Material _newMaterial = new Material(PostProcessingShader);
_newMaterial.hideFlags = HideFlags.HideAndDontSave;
return _newMaterial;
}
}
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
Graphics.Blit(source,destination,Mat);
}
}