文章目錄
- 建立一個基本的后處理腳本系統
- 調整螢屏的亮度、飽和度和對比度
- 邊緣檢測
- 高斯模糊
- Bloom效果
螢屏后處理效果(screen post-processing effects) 是游戲中實作螢屏特效的常見方法
建立一個基本的后處理腳本系統
螢屏后處理通常指的是在渲染完整個場景得到螢屏影像后,再對這個影像進行一系列操作,實作各種螢屏特效,使用螢屏后處理可以為游戲畫面添加更多的藝術效果,例如景深、運動模糊,
OnRenderImage函式
Unity為我們提供了一個介面——OnRenderImage函式,用于得到渲染后的螢屏影像,即抓取螢屏,
MonoBehaviour.OnRenderImage(RenderTexture src, RenderTexture dest)
- src: 源紋理(當前渲染得到的影像)
- dest: 目標渲染紋理
當我們在腳本中宣告了此函式后,Unity會把當前渲染得到的影像存盤在src引數中,通過一系列操作后,再把目標渲染紋理dest顯示在螢屏上,
Graphics.Blit函式
在OnRenderImage函式當中,我們通常利用Graphics.Blit函式來完成對渲染紋理的處理
public static void Blit(Texture src, RenderTexture dest);
public static void Blit(Texture src, RenderTexture dest, Material mat, int pass = -1);
public static void Blit(Texture src, Material mat, int pass = -1);
- src: 源紋理(當前渲染得到的影像),將會傳遞給Shader中命名為_MainTex的紋理屬性
- dest: 目標渲染紋理
- mat: 使用的材質,該材質使用的Shader將會進行各種螢屏后處理的操作
- pass: pass的索引,默認值為-1,表示會依次呼叫Shader內所有的Pass,否則呼叫給定索引的Pass
using UnityEngine;
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
public class PostEffectsBase : MonoBehaviour
{
protected void Start()
{
CheckResources();
}
protected void CheckResources()
{
bool isSupported = CheckSupport();
if (isSupported == false)
{
NotSupported();
}
}
protected bool CheckSupport()
{
if (SystemInfo.supportsImageEffects == false)
{
Debug.LogWarning("該設備不支持影像處理");
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;
return material;
}
}
}
調整螢屏的亮度、飽和度和對比度
using UnityEngine;
public class BrightnessSaturationAndContrast : PostEffectsBase
{
public Shader briSatConShader;
private Material briSatConMaterial;
public Material material
{
get
{
briSatConMaterial = CheckShaderAndCreateMaterial(briSatConShader, briSatConMaterial);
return briSatConMaterial;
}
}
[Range(0f, 3f)]
public float brightness = 1.0f;
[Range(0f, 3f)]
public float saturation = 1.0f;
[Range(0f, 3f)]
public float contrast = 1.0f;
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);
}
}
}
Shader "Unlit/BrightnessSaturationAndContrast"
{
Properties
{
// 基礎紋理
_MainTex("Base (RGB)", 2D) = "white" { }
// 亮度
_Brightness("Brightness", Float) = 1
// 飽和度
_Saturation("Saturation", Float) = 1
// 對比度
_Contrast("Contrast", 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;
// 調整飽和度
// 亮度值(飽和度為0的顏色) = 每個顏色分量 * 特定系數
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);
// 調整對比度
// 對比度為0的顏色
fixed3 avgColor = fixed3(0.5, 0.5, 0.5);
finalColor = lerp(avgColor, finalColor, _Contrast);
return fixed4(finalColor, renderTex.a);
}
ENDCG
}
}
}
邊緣檢測
高斯模糊
Bloom效果
(未完待續)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/298737.html
標籤:其他
