扭曲效果
2018-07-25 本文已影响0人
星易乾川
用GrabPass抓屏,法线图扰动UV,最好是自己用脚本抓屏,应该会省点,主要是好进行后续控制
扭曲.jpgShader "Artist/Effect/Distort"
{
Properties
{
_DistortStrength("DistortStrength", Range(0,1)) = 0.2
_DistortTimeFactor("DistortTimeFactor", Range(0,1)) = 1
_NoiseTex("NoiseTexture", 2D) = "white" {}
}
SubShader
{
ZWrite Off
Cull Off
GrabPass
{
"_GrabTex"
}
Pass
{
Tags
{
"RenderType" = "Transparent"
"Queue" = "Transparent + 100"
}
CGPROGRAM
sampler2D _GrabTex;
float4 _GrabTex_ST;
sampler2D _NoiseTex;
float4 _NoiseTex_ST;
float _DistortStrength;
float _DistortTimeFactor;
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 grabPos : TEXCOORD1;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.grabPos = ComputeGrabScreenPos(o.pos);
o.uv = TRANSFORM_TEX(v.texcoord, _NoiseTex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
float4 offset = tex2D(_NoiseTex, i.uv - _Time.xy * _DistortTimeFactor);
i.grabPos.xy -= offset.xy * _DistortStrength;
fixed4 color = tex2Dproj(_GrabTex, i.grabPos);
return color;
}
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
}
据说会有安卓机上GrabPass读帧缓存卡死的问题,那么我转载了另一篇方法也很不错
先做全屏后处理,然后渲染一张黑白mask作为遮罩的Texture,代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DistortEffect : PostEffectBase {
[Range(0.0f, 1.0f)]
public float DistortTimeFactor = 0.15f;
[Range(0.0f, 0.2f)]
public float DistortStrength = 0.01f;
public Texture NoiseTexture = null;
public Shader maskObjShader = null;
public int downSample = 4;
private Camera mainCam = null;
private Camera additionalCam = null;
private RenderTexture renderTexture = null;
public void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (_Material)
{
_Material.SetTexture("_NoiseTex", NoiseTexture);
_Material.SetFloat("_DistortTimeFactor", DistortTimeFactor);
_Material.SetFloat("_DistortStrength", DistortStrength);
_Material.SetTexture("_MaskTex", renderTexture);
Graphics.Blit(source, destination, _Material);
}
else
{
Graphics.Blit(source, destination);
}
}
void Awake()
{
InitAdditionalCam();
}
private void InitAdditionalCam()
{
mainCam = GetComponent<Camera>();
if (mainCam == null)
return;
Transform addCamTransform = transform.FindChild("additionalDistortCam");
if (addCamTransform != null)
DestroyImmediate(addCamTransform.gameObject);
GameObject additionalCamObj = new GameObject("additionalDistortCam");
additionalCam = additionalCamObj.AddComponent<Camera>();
SetAdditionalCam();
}
private void SetAdditionalCam()
{
if (additionalCam)
{
additionalCam.transform.parent = mainCam.transform;
additionalCam.transform.localPosition = Vector3.zero;
additionalCam.transform.localRotation = Quaternion.identity;
additionalCam.transform.localScale = Vector3.one;
additionalCam.farClipPlane = mainCam.farClipPlane;
additionalCam.nearClipPlane = mainCam.nearClipPlane;
additionalCam.fieldOfView = mainCam.fieldOfView;
additionalCam.backgroundColor = Color.clear;
additionalCam.clearFlags = CameraClearFlags.Color;
additionalCam.cullingMask = 1 << LayerMask.NameToLayer("Distort");
additionalCam.depth = -999;
if (renderTexture == null)
renderTexture = RenderTexture.GetTemporary(Screen.width >> downSample, Screen.height >> downSample, 0);
}
}
void OnEnable()
{
SetAdditionalCam();
additionalCam.enabled = true;
}
void OnDisable()
{
additionalCam.enabled = false;
}
void OnDestroy()
{
if (renderTexture)
{
RenderTexture.ReleaseTemporary(renderTexture);
}
DestroyImmediate(additionalCam.gameObject);
}
void OnPreRender()
{
if (additionalCam.enabled)
{
additionalCam.targetTexture = renderTexture;
additionalCam.RenderWithShader(maskObjShader, "");
}
}
}
以下shader挂在模型上,对全屏图片处理并使用mask做遮罩
Shader "Custom/DistortPostEffect"
{
Properties
{
_MainTex("Base (RGB)", 2D) = "white" {}
_NoiseTex("Noise", 2D) = "black" {}
_MaskTex("Mask", 2D) = "black" {}
}
CGINCLUDE
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform sampler2D _NoiseTex;
uniform sampler2D _MaskTex;
uniform float _DistortTimeFactor;
uniform float _DistortStrength;
fixed4 frag(v2f_img i) : SV_Target
{
float4 noise = tex2D(_NoiseTex, i.uv - _Time.xy * _DistortTimeFactor);
float2 offset = noise.xy * _DistortStrength;
fixed4 factor = tex2D(_MaskTex, i.uv);
float2 uv = offset * factor.r + i.uv;
return tex2D(_MainTex, uv);
}
ENDCG
SubShader
{
Pass
{
ZTest Always
Cull Off
ZWrite Off
Fog{ Mode off }
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
ENDCG
}
}
Fallback off
}
mask专用shader
Shader "ApcShader/MaskObjPrepass"
{
//子着色器
SubShader
{
Pass
{
Cull Off
CGPROGRAM
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
};
v2f vert(appdata_full v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
//这个Pass直接输出颜色
return fixed4(1,1,1,1);
}
//使用vert函数和frag函数
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
}