Unity后处理效果之边角压暗的实现方法
本篇内容介绍了“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; } }
“Unity后处理效果之边角压暗的实现方法”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!