Unity后處理效果之邊角壓暗
本文實(shí)例為大家分享了Unity后處理效果之邊角壓暗的具體代碼,供大家參考,具體內(nèi)容如下
我使用的版本為2019.4.12(LTS)版本,項(xiàng)目是HDRP項(xiàng)目。
邊角壓暗效果的觸發(fā),可以按鈕觸發(fā),也可以按鍵觸發(fā),按鈕觸發(fā)直接調(diào)用ButtonEvent()方法就好了。兩種方式稍微有點(diǎn)差距,但不大。
首先先在項(xiàng)目里新建后處理的配置文件,方法如下:

然后隨便創(chuàng)建一個空物體,掛上腳本DynamicVignette

腳本如下:
using System.Collections;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
/*
*
* Writer:June
*
* Date: 2020.10.14
*
* Function:動態(tài)邊角壓暗效果
*
* Remarks:
*
*/
/// <summary>
/// 掛載當(dāng)前腳本的GameObject必須確保有Volume組件
/// </summary>
[RequireComponent(typeof(Volume))]
public class DynamicVignette : MonoBehaviour
{
/// <summary>
/// 后處理體積容器
/// </summary>
private Volume volume;
/// <summary>
/// 對應(yīng)要修改的效果————>邊角壓暗效果
/// </summary>
private Vignette vignette;
/// <summary>
/// 是否成功獲取邊角壓暗屬性
/// </summary>
public bool IsGetAttribute { get; private set; }
/// <summary>
/// 動畫播放需要的時間
/// </summary>
public float animtionTime;
/// <summary>
/// 強(qiáng)度范圍
/// </summary>
[Range(0.1f, 1)]
public float vignetteIntensity = 0.1f;
/// <summary>
/// 動畫開關(guān)
/// </summary>
private bool isPlay = false;
/// <summary>
/// 計時器
/// </summary>
private float timer = 0;
/// <summary>
/// 每幀更新的強(qiáng)度總和(用于對邊角壓暗強(qiáng)度的賦值,并且每幀更新)
/// </summary>
private float frameIntensity = 0;
/// <summary>
/// 幀率
/// </summary>
[Range(10, 60)]
public float frameRate = 60;
private void Start()
{
//獲取引用
volume = GetComponent<Volume>();
//從配置文件或配置表中獲取屬性 TryGet方法返回的是bool類型的
IsGetAttribute = volume.profile.TryGet(out vignette);
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
//使用協(xié)程
StartCoroutine(VignetteEffect());
}
}
//經(jīng)過測試,每秒執(zhí)行51次,Update函數(shù)每秒執(zhí)行次數(shù)不一定
private void FixedUpdate()
{
//確保獲取到了屬性
if (!IsGetAttribute) return;
if (isPlay)
{
timer += Time.deltaTime;
VignetteEffect(timer);
}
}
/// <summary>
/// 按鈕觸發(fā)
/// </summary>
public void ButtonEvent()
{
isPlay = true;
}
/// <summary>
/// 邊角壓暗效果
/// tips:注意intensity不可以直接賦值,intensity的類型不是float
/// </summary>
private void VignetteEffect(float currentTime)
{
//判斷時間
if (currentTime >= animtionTime / 2f)
{
//用 總時間的一半 * 幀率 = 在這段時間要更新的幀數(shù),再用 規(guī)定的強(qiáng)度 / 總幀數(shù) = 每幀更新的強(qiáng)度
frameIntensity -= vignetteIntensity / (51 * animtionTime / 2f);
vignette.intensity.value = frameIntensity;
}
else
{
frameIntensity += vignetteIntensity / (51 * animtionTime / 2f);
vignette.intensity.value = frameIntensity;
}
//播放完成
if (currentTime >= animtionTime)
{
isPlay = false;
timer = 0;
frameIntensity = 0;
}
}
/// <summary>
/// 邊角壓暗效果協(xié)程
/// </summary>
/// <returns></returns>
IEnumerator VignetteEffect()
{
//從0->目標(biāo)強(qiáng)度
for (float i = 0; i <= vignetteIntensity; i+= vignetteIntensity / (frameRate * animtionTime / 2f))
{
vignette.intensity.value = i;
//每0.02秒更新一幀
yield return new WaitForSeconds(0.02f);
}
//從目標(biāo)強(qiáng)度->0
for (float i = vignetteIntensity; i >= 0; i -= vignetteIntensity / (frameRate * animtionTime / 2f))
{
vignette.intensity.value = i;
yield return new WaitForSeconds(0.02f);
}
}
}
最后的效果:

2020.11.09更新
做了一些處理,不是通過時間來限制,而是用變化速度,以及一些小優(yōu)化,外部只要直接調(diào)用TriggerEffect() ,就有邊角壓暗的漸變效果(可以用來做被敵人攻擊的后,屏幕效果,不過有點(diǎn)大材小用了,哈哈,這里我只是做一個引申?。?/p>
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
/*
*
* Writer:June
*
* Date: 2020.11.09
*
* Function:控制后處理效果之邊角壓暗效果
*
* Remarks:
*
*/
[RequireComponent(typeof(Volume))]
public class ControlPP_Vignette : MonoBehaviour
{
/// <summary>
/// 后期處理容器
/// </summary>
private Volume volume;
/// <summary>
/// 邊角壓暗效果
/// </summary>
private Vignette vignette;
/// <summary>
/// 是否成功獲取邊角壓暗屬性
/// </summary>
public bool IsGetAttribute { get; private set; }
/// <summary>
/// 顯示/隱藏邊角壓暗
/// </summary>
private bool IsFadeIn, IsFadeOut;
/// <summary>
/// 壓暗的變化速度
/// </summary>
[Header("壓暗效果的變化速度"),Range(0.5f,5),SerializeField]
private float fadeSpeed = 1f;
/// <summary>
/// 壓暗強(qiáng)度最大值
/// </summary>
[Header("壓暗強(qiáng)度最大值"), Range(0, 1),SerializeField]
private float effectMax = 0.6f;
/// <summary>
/// 默認(rèn)初始化顏色
/// </summary>
public Color defaultColor;
private void Start()
{
//獲取引用
volume = GetComponent<Volume>();
//默認(rèn)關(guān)閉
IsFadeIn = false;
//從配置文件或配置表中獲取屬性 TryGet方法返回的是bool類型的
IsGetAttribute = volume.profile.TryGet(out vignette);
//如果沒有獲取到邊角壓暗效果,則創(chuàng)建邊角壓暗效果
if (!IsGetAttribute) CreatVignetteEffect(defaultColor);
}
private void Update()
{
if (IsFadeIn)
{
vignette.intensity.value += fadeSpeed * Time.deltaTime;
//判斷是否達(dá)到目標(biāo),到達(dá)后設(shè)置為false
IsFadeIn = vignette.intensity.value < effectMax;
IsFadeOut = !IsFadeIn;
}
if (IsFadeOut)
{
vignette.intensity.value -= fadeSpeed * Time.deltaTime;
IsFadeOut = vignette.intensity.value < effectMax;
}
}
/// <summary>
/// 觸發(fā)邊角壓暗效果(提供給外部調(diào)用)
/// </summary>
public void TriggerEffect()
{
//先判斷是否獲取得到了邊角壓暗
if (IsGetAttribute) IsFadeIn = true;
}
/// <summary>
/// 創(chuàng)建邊角壓暗效果
/// </summary>
/// <param name="color">初始顏色</param>
private void CreatVignetteEffect(Color color)
{
//將邊角壓暗效果添加到配置文件中 ture:將所有屬性激活
vignette = volume.profile.Add<Vignette>(true);
//初始化顏色
vignette.color.value = color;
//初始化強(qiáng)度
vignette.intensity.value = 0;
//標(biāo)記為獲取到邊角壓暗
IsGetAttribute = true;
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#?wpf利用附加屬性實(shí)現(xiàn)界面上定義裝飾器
裝飾器是wpf中可以浮在控件上面的一種組件,我們通??梢杂脕韺?shí)現(xiàn)一些諸如控件拖動點(diǎn)、提示框、自定義鼠標(biāo)等界面功能。本文主要是利用附加屬性實(shí)現(xiàn)界面上定義裝飾器,需要的可以參考下2022-12-12
C#中哈希表(HashTable)用法實(shí)例詳解(添加/移除/判斷/遍歷/排序等)
這篇文章主要介紹了C#中哈希表(HashTable)用法,簡單講述了哈希表的原理并結(jié)合實(shí)例形式詳細(xì)分析了C#針對哈希表進(jìn)行添加、移除、判斷、遍歷、排序等操作的實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-06-06

