Unity后处理效果之边角压暗

时间:2021-05-20

本文实例为大家分享了Unity后处理效果之边角压暗的具体代码,供大家参考,具体内容如下

我使用的版本为2019.4.12(LTS)版本,项目是HDRP项目。

边角压暗效果的触发,可以按钮触发,也可以按键触发,按钮触发直接调用ButtonEvent()方法就好了。两种方式稍微有点差距,但不大。

首先先在项目里新建后处理的配置文件,方法如下:

然后随便创建一个空物体,挂上脚本DynamicVignette

脚本如下:

using System.Collections;using UnityEngine;using UnityEngine.Rendering;using UnityEngine.Rendering.HighDefinition; /* * * Writer:June * * Date: 2020.10.14 * * Function:动态边角压暗效果 * * Remarks: * */ /// <summary>/// 挂载当前脚本的GameObject必须确保有Volume组件/// </summary>[RequireComponent(typeof(Volume))]public class DynamicVignette : MonoBehaviour{ /// <summary> /// 后处理体积容器 /// </summary> private Volume volume; /// <summary> /// 对应要修改的效果————>边角压暗效果 /// </summary> private Vignette vignette; /// <summary> /// 是否成功获取边角压暗属性 /// </summary> public bool IsGetAttribute { get; private set; } /// <summary> /// 动画播放需要的时间 /// </summary> public float animtionTime; /// <summary> /// 强度范围 /// </summary> [Range(0.1f, 1)] public float vignetteIntensity = 0.1f; /// <summary> /// 动画开关 /// </summary> private bool isPlay = false; /// <summary> /// 计时器 /// </summary> private float timer = 0; /// <summary> /// 每帧更新的强度总和(用于对边角压暗强度的赋值,并且每帧更新) /// </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)) { //使用协程 StartCoroutine(VignetteEffect()); } } //经过测试,每秒执行51次,Update函数每秒执行次数不一定 private void FixedUpdate() { //确保获取到了属性 if (!IsGetAttribute) return; if (isPlay) { timer += Time.deltaTime; VignetteEffect(timer); } } /// <summary> /// 按钮触发 /// </summary> public void ButtonEvent() { isPlay = true; } /// <summary> /// 边角压暗效果 /// tips:注意intensity不可以直接赋值,intensity的类型不是float /// </summary> private void VignetteEffect(float currentTime) { //判断时间 if (currentTime >= animtionTime / 2f) { //用 总时间的一半 * 帧率 = 在这段时间要更新的帧数,再用 规定的强度 / 总帧数 = 每帧更新的强度 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> /// 边角压暗效果协程 /// </summary> /// <returns></returns> IEnumerator VignetteEffect() { //从0->目标强度 for (float i = 0; i <= vignetteIntensity; i+= vignetteIntensity / (frameRate * animtionTime / 2f)) { vignette.intensity.value = i; //每0.02秒更新一帧 yield return new WaitForSeconds(0.02f); } //从目标强度->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更新

做了一些处理,不是通过时间来限制,而是用变化速度,以及一些小优化,外部只要直接调用TriggerEffect() ,就有边角压暗的渐变效果(可以用来做被敌人攻击的后,屏幕效果,不过有点大材小用了,哈哈,这里我只是做一个引申!)

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> /// 压暗强度最大值 /// </summary> [Header("压暗强度最大值"), Range(0, 1),SerializeField] private float effectMax = 0.6f; /// <summary> /// 默认初始化颜色 /// </summary> public Color defaultColor; private void Start() { //获取引用 volume = GetComponent<Volume>(); //默认关闭 IsFadeIn = false; //从配置文件或配置表中获取属性 TryGet方法返回的是bool类型的 IsGetAttribute = volume.profile.TryGet(out vignette); //如果没有获取到边角压暗效果,则创建边角压暗效果 if (!IsGetAttribute) CreatVignetteEffect(defaultColor); } private void Update() { if (IsFadeIn) { vignette.intensity.value += fadeSpeed * Time.deltaTime; //判断是否达到目标,到达后设置为false IsFadeIn = vignette.intensity.value < effectMax; IsFadeOut = !IsFadeIn; } if (IsFadeOut) { vignette.intensity.value -= fadeSpeed * Time.deltaTime; IsFadeOut = vignette.intensity.value < effectMax; } } /// <summary> /// 触发边角压暗效果(提供给外部调用) /// </summary> public void TriggerEffect() { //先判断是否获取得到了边角压暗 if (IsGetAttribute) IsFadeIn = true; } /// <summary> /// 创建边角压暗效果 /// </summary> /// <param name="color">初始颜色</param> private void CreatVignetteEffect(Color color) { //将边角压暗效果添加到配置文件中 ture:将所有属性激活 vignette = volume.profile.Add<Vignette>(true); //初始化颜色 vignette.color.value = color; //初始化强度 vignette.intensity.value = 0; //标记为获取到边角压暗 IsGetAttribute = true; }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章