这个系列主要是通过阅读《Unity Shader入门精要》之后的一些感想,给读者一些启发。
联系邮箱:glasirius@gmail.com
最近事情有点多,总算抽出时间
本来想接着高斯模糊实现景深的
但是可能写不完。。先写个运动模糊吧。。。
运动模糊就是物体在移动的时候加上模糊效果
比如赛车在加速的时候可能需要加点模糊的效果表示很快
有一种很简单的做法就是不断叠加颜色,用alpha做系数就行了
但是有时候想实现一些残影效果,比如有很多重残影
其实就是记录连续x帧的RT,做混合就好了
基于这种思路,其实shader的写法都一样,只需要改一下后处理代码就行了
Shader "Test/Unity Shaders Book/Chapter 12/Motion Blur Test"
{
Properties
{
_MainTex("MainTex",2D)="white"{}
}
SubShader
{
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
struct a2v
{
float4 pos:POSITION;
float2 uv:TEXCOORD0;
};
struct v2f
{
float4 pos:SV_POSITION;
float2 uv:TEXCOORD0;
};
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.pos);
o.uv = v.uv;
return o;
}
fixed4 frag(v2f f):SV_TARGET
{
fixed4 o;
o = tex2D(_MainTex,f.uv);
//这个混合系数可以调整
o.a = 0.5;
return o;
}
ENDCG
}
}
}
运动模糊:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[ExecuteInEditMode]
public class MotionBlurTest : MonoBehaviour
{
public Shader shader;
private Material _mat;
private RenderTexture _rt;
void OnEnable()
{
if (shader)
{
_mat = new Material(shader);
}
}
void OnRenderImage(RenderTexture src, RenderTexture dest)
{
if (_mat == null)
return;
if (_rt == null)
_rt = RenderTexture.GetTemporary(src.width, src.height);
Graphics.Blit(src, _rt, _mat);
Graphics.Blit(_rt, dest, _mat);
}
}
残影:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[ExecuteInEditMode]
public class MotionBlurTest : MonoBehaviour
{
public Shader shader;
public int num = 4;
private Material _mat;
private RenderTexture _rt;
private RenderTexture[] _rts;
void OnEnable()
{
if (shader)
{
_mat = new Material(shader);
}
_rts = new RenderTexture[num];
}
void OnRenderImage(RenderTexture src, RenderTexture dest)
{
if (_mat == null)
return;
if (_rts[num - 1] != null)
{
RenderTexture.ReleaseTemporary(_rts[num - 1]);
}
for (int i = num - 1; i > 0; i--)
{
_rts[i] = _rts[i - 1];
}
_rts[0] = RenderTexture.GetTemporary(src.width, src.height);
Graphics.Blit(src, _rts[0], _mat);
for (int i = 0; i < num; i++)
{
if (_rts[i])
Graphics.Blit(_rts[i], dest, _mat);
}
}
}