【Unity3D】运动模糊特效
1 运动模糊原理
开启混合(Blend)后,通过 Alpha 通道控制当前屏幕纹理与历史屏幕纹理进行混合,当有物体运动时,就会将当前位置的物体影像与历史位置的物体影像进行混合,从而实现运动模糊效果,即模糊拖尾效果。主要代码如下:
Pass {
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert_img // 使用内置的vert_img顶点着色器
#pragma fragment fragRGB // _BlurAmount只参与混合, 不影响alpha值
fixed4 fragRGB (v2f_img i) : SV_Target { // v2f_img为内置结构体, 里面只包含pos和uv
return fixed4(tex2D(_MainTex, i.uv).rgb, _BlurAmount); // 模糊值, 通过alpha通道控制当前屏幕纹理与历史屏幕纹理进行混合
}
ENDCG
}
本文完整资源 见→Unity3D运动模糊特效。
2 代码实现
MotionBlur.cs
using UnityEngine;
[RequireComponent(typeof(Camera))] // 需要相机组件
public class MotionBlur : MonoBehaviour {
[Range(0.0f, 0.9f)]
public float blurAmount = 0.5f; // 模糊值, 值越大拖尾效果越明显
private RenderTexture historyTexture; // 历史屏幕纹理
private Material material = null; // 材质
private void Start() {
material = new Material(Shader.Find("MyShader/MotionBlur"));
material.hideFlags = HideFlags.DontSave;
}
void OnDisable() { // 脚本不运行时立即销毁, 下次开始应用运动模糊时, 重新混合图像
DestroyImmediate(historyTexture);
}
void OnRenderImage(RenderTexture src, RenderTexture dest) {
if (material != null) {
// 初始化时或窗口尺寸变化时, 创建叠加纹理
if (historyTexture == null || historyTexture.width != src.width || historyTexture.height != src.height) {
DestroyImmediate(historyTexture);
historyTexture = new RenderTexture(src.width, src.height, 0);
historyTexture.hideFlags = HideFlags.HideAndDontSave;
Graphics.Blit(src, historyTexture);
}
material.SetFloat("_BlurAmount", 1.0f - blurAmount); // 设置模糊值, 通过alpha通道控制当前屏幕纹理与历史屏幕纹理进行混合
Graphics.Blit(src, historyTexture, material);
Graphics.Blit(historyTexture, dest);
} else {
Graphics.Blit(src, dest);
}
}
}
MotionBlur.shader
Shader "MyShader/MotionBlur" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {} // 主纹理
_BlurAmount ("Blur Amount", Float) = 1.0 // 模糊值, 通过alpha通道控制当前屏幕纹理与历史屏幕纹理进行混合
}
SubShader {
CGINCLUDE
#include "UnityCG.cginc"
sampler2D _MainTex; // 主纹理
fixed _BlurAmount; // 模糊值, 通过alpha通道控制当前屏幕纹理与历史屏幕纹理进行混合
fixed4 fragRGB (v2f_img i) : SV_Target { // v2f_img为内置结构体, 里面只包含pos和uv
return fixed4(tex2D(_MainTex, i.uv).rgb, _BlurAmount);
}
half4 fragA (v2f_img i) : SV_Target { // v2f_img为内置结构体, 里面只包含pos和uv
return tex2D(_MainTex, i.uv);
}
ENDCG
ZTest Always Cull Off ZWrite Off
Pass {
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGB // 允许通过的颜色通道, 取值有: 0、R、G、B、A、RGBA的组合(RG、RGB等)
CGPROGRAM
#pragma vertex vert_img // 使用内置的vert_img顶点着色器
#pragma fragment fragRGB // _BlurAmount只参与混合, 不影响alpha值
ENDCG
}
Pass {
Blend One Zero
ColorMask A // 允许通过的颜色通道, 取值有: 0、R、G、B、A、RGBA的组合(RG、RGB等)
CGPROGRAM
#pragma vertex vert_img // 使用内置的vert_img顶点着色器
#pragma fragment fragA // 使用纹理原本的alpha值
ENDCG
}
}
FallBack Off
}
说明: vert_img 是 Unity 内置的顶点着色器,v2f_img 是 Unity 内置的结构体变量,vert_img 和 v2f_img 的实现见→Shader常量、变量、结构体、函数;第一个 Pass 通过 Alpha 通道控制当前屏幕纹理与历史屏幕纹理进行混合,通过 ColorMask RGB 保证混合不影响 Alpha 通道值;第二个 Pass 对当前屏幕的 Alpha 通道进行采样,通过 ColorMask A 保证采样不影响 RGB 通道的值。
3 运行效果
1)原图效果
将 blurAmount 设置为 0,无运动模糊特效,如下:

2)运动模糊效果
将 blurAmount 设置为 0.9,运动模糊特效如下:

声明:本文转自【Unity3D】运动模糊特效。
【Unity3D】运动模糊特效的更多相关文章
- 基于HTML5 Canvas实现的图片马赛克模糊特效
效果请点击下面网址: http://hovertree.com/texiao/html5/1.htm 一.开门见山受美国肖像画家Chuck Close的启发,此脚本通过使用HTML5 canvas元素 ...
- 从单幅图像高质量去除运动模糊——读JiaYaJia同名英文论文总结
原始论文在这里 http://www.cse.cuhk.edu.hk/leojia/projects/motion_deblurring/ 一.概述 论文根据以下的基本模糊图像模型建立 其中I是我们观 ...
- Java 运动模糊
Java 运动模糊代码 想用Java 写个运动模糊的效果,无奈本人水平有限,国内也没找到资源,于是Google到了一个文档,特地分享出来! 本代码源自 http://www.jhlabs.com/ip ...
- Unity shader学习之屏幕后期处理效果之运动模糊
运动模糊,代码如下: using UnityEngine; public class MotionBlurRenderer : PostEffectRenderer { [Range(0.1f, 0. ...
- 维纳滤波和编码曝光PSF去除运动模糊【matlab】
编码曝光知识 - ostartech - 博客园 https://www.cnblogs.com/wxl845235800/p/8276362.html %%%%%%%%%%%%%%%%%%%%%%% ...
- Win8 Metro(C#)数字图像处理--2.50图像运动模糊
原文:Win8 Metro(C#)数字图像处理--2.50图像运动模糊 [函数名称] 图像运动模糊算法 MotionblurProcess(WriteableBitmap src,int ...
- OpenCV3入门(十三)图像运动模糊
1.原理 运动模糊产生: 由于相机传感器或物体相对运动, 按快门瞬间造成图像产生运动模糊. 在用摄像机获取景物图像时,如果在相机曝光期间景物和摄像机之间存在相对运动,例如用照相机拍摄快速运动的物体,或 ...
- Unity3D图像后处理特效——Depth of Field 3.4
Depth of Field 3.4 is a common postprocessing effect that simulates the properties of a camera lens. ...
- Unity Shader 屏幕后效果——摄像机运动模糊(速度映射图实现)
速度映射图主要是为了得到每个像素相对于前一帧的运动矢量,其中一种方法是使用摄像机的深度纹理来推导. 推导过程如下: 先由深度纹理逆推出NDC(归一化的设备坐标)下的顶点坐标,利用VP矩阵(视角*投影矩 ...
- unity3d 摄像机抖动特效
摄像机抖动特效 在须要的地方调用CameraShake.Shake()方法就能够
随机推荐
- 【C++】requires关键字简介
requires 是 C++20 中引入的一个新关键字,用于在函数模板或类模板中声明所需的一组语义要求,它可以用来限制模板参数,类似于 typename 和 class 关键字. requires关键 ...
- vue之关闭eslint及vue/require-v-for-key 、vue/no-unsed-vars报错解决方法
报错:Page1组件已经注册但是没有被使用. vue/no-unused-components 如果报错以下: 解决方法: 首先打开项目中的package,json 找到eslint-config ...
- Maven安装、阿里云镜像配置、Idea中创建Maven项目、Tomcat的部署
我为什么要学这个技术? 为了更快创建web开发项目和jar包 在javaweb开发中,需要使用大量的jar包,我们手动去导入: 如何能够让一个东西自动帮我导入和配置这个jar包 因此,Maven诞生了 ...
- AcWing 1024. 装箱问题
有一个箱子容量为 V,同时有 n 个物品,每个物品有一个体积(正整数). 要求 n 个物品中,任取若干个装入箱内,使箱子的剩余空间为最小. 输入格式 第一行是一个整数 V,表示箱子容量. 第二行是一个 ...
- L2-035 完全二叉树的层序遍历
题目描述: 一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是完美二叉树.对于深度为 D 的,有 N 个结点的二叉树,若其结点对应于相同深度完美二叉树的层序遍历的前 N 个结点,这样的树就 ...
- Linux 下 R 源码安装指南
本文章同步自作者的语雀知识库,请点击这里阅读原文. 如果你使用的 Linux 系统 GCC 版本太低, 又没有 root 权限 (即使有 root 权限又担心升级 GCC 带来的风险) ; 同时你又不 ...
- uniapp主题切换功能的第二种实现方式(scss变量+require)
在上一篇 "uniapp主题切换功能的第一种实现方式(scss变量+vuex)" 中介绍了第一种如何切换主题,但我们总结出一些不好的地方,例如扩展性不强,维护起来也困难等等,那么接 ...
- 一篇随笔入门Java
Java helloWorld 随便新建一个文件夹存放代码 新建一个java文件 文件后缀名.java Hello.java [注意]系统可能不显示后缀名要手动打开 代码 public class H ...
- 02LED灯
目录 一.LED灯是什么 二.原理图 三.对LED进行操作 1.点亮第一个LED灯 2.LED双数点亮 3.LED流水灯 四.延迟函数的生成 一.LED灯是什么 LED是一个发光二极管,当一段为高电平 ...
- Linux切换Root权限配置和无法切换排查
1.wheel组 普通用户禁止su切换root 在默认的情况下,普通用户通过su可以切换到root用户下,为了加强系统安全性,使用Linux的特殊用户组wheel来实现,只有用户加入到wheel组当中 ...