简介
最近刚刚通关《耻辱2》,在有一关的时候,竟然送给我了一个能够穿越时空的“神器”,有了这货,就可以一下子传送到过去或者回到现在。在使用这个道具的时候,会有一个屏幕扭曲的穿越的效果,感觉效果不错。
在穿越了无数回之后,我终于下决心准备在Unity里面实现一个简化的版本(肯定还原不到这种大作的水平,就当是练习啦,2333)。
屏幕收缩的效果
观察上面的效果图,最明显的一块就是屏幕有一个收缩的效果,这也是这种屏幕扭曲里面最明显也最容易实现的一部分。首先,扭曲效果就是uv偏移,超哪偏移,这个我们可以自己输入一个点给shader,默认就是屏幕中心点。我们让每个采样的点都朝着我们定义的中心点的方向偏移一段距离,就可以实现类似的屏幕收缩的效果。关于扭曲效果的基本知识可以参考一下
屏幕水波纹效果以及
热空气扭曲效果,这里就不多说了。下面附上收缩效果第一版。
c#脚本如下:
/********************************************************************
FileName: PassthoughEffect.cs
Description: "传说中的穿越"效果
Created: 2017/05/07
by :puppet_master
*********************************************************************/
using UnityEngine;
public class PassthoughEffect : PostEffectBase
{
//扭曲强度
[Range(0, 0.15f)]
public float distortFactor = 1.0f;
//扭曲中心(0-1)屏幕空间,默认为中心点
public Vector2 distortCenter = new Vector2(0.5f, 0.5f);
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (_Material)
{
_Material.SetFloat("_DistortFactor", distortFactor);
_Material.SetVector("_DistortCenter", distortCenter);
Graphics.Blit(source, destination, _Material);
}
else
{
Graphics.Blit(source, destination);
}
}
}
shader代码如下:
//屏幕收缩效果
//by:puppet_master
Shader "ApcShader/PaththoughEffect"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
}
CGINCLUDE
uniform sampler2D _MainTex;
uniform float _DistortFactor; //扭曲强度
uniform float4 _DistortCenter; //扭曲中心点xy值(0-1)屏幕空间
#include "UnityCG.cginc"
fixed4 frag(v2f_img i) : SV_Target
{
//计算偏移的方向
float2 dir = i.uv - _DistortCenter.xy;
//最终偏移的值:方向 * (1-长度),越靠外偏移越小
float2 offset = _DistortFactor * normalize(dir) * (1 - length(dir));
//计算采样uv值:正常uv值+从中间向边缘逐渐增加的采样距离
float2 uv = i.uv + offset;
return tex2D(_MainTex, uv);
}
ENDCG
SubShader
{
Pass
{
ZTest Always
Cull Off
ZWrite Off
Fog { Mode off }
//调用CG函数
CGPROGRAM
//使效率更高的编译宏
#pragma fragmentoption ARB_precision_hint_fastest
//vert_img是在UnityCG.cginc中定义好的,当后处理vert阶段计算常规,可以直接使用自带的vert_img
#pragma vertex vert_img
#pragma fragment frag
ENDCG
}
}
}
找个测试场景,未收缩前的效果如下:
调整扭曲系数后,屏幕朝中心点收缩的效果如下: