在这之前试着通过计算输出正弦(sin)相关的uv坐标来实现波动效果,结果比较失望,那种方法大概适合使用在3D的波浪效果上。
shader使用噪声效果+屏幕捕获实现
Shader "Custom/wave" {
Properties{
_MainTex("Maintex", 2D) = "white" {}
_Noise_Mask("Noise_Mask", 2D) = "white" {}
_Noise("Noise", 2D) = "white" {}
_Noise_Power("Noise_Power", Float) = 0.05
_Noise_SV("Noise_SV", Vector) = (1,1,1,1)
_node_8634("node_8634", Color) = (0.5,0.5,0.5,1)
[HideInInspector]_Cutoff("Alpha cutoff", Range(0,1)) = 0.5
}
SubShader{
Tags{
"IgnoreProjector" = "True"
"Queue" = "Transparent"
"RenderType" = "Transparent"
}
//屏幕捕获
GrabPass{}
Pass{
Name "FORWARD"
Tags{
"LightMode" = "ForwardBase"
}
Blend SrcAlpha OneMinusSrcAlpha
Cull Off
ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#define UNITY_PASS_FORWARDBASE
#include "UnityCG.cginc"
#pragma multi_compile_fwdbase
#pragma exclude_renderers xbox360 xboxone ps3 ps4 psp2
#pragma target 3.0
uniform float4 _TimeEditor;
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform sampler2D _Noise; uniform float4 _Noise_ST;
uniform float4 _Noise_SV;
uniform float _Noise_Power;
uniform sampler2D _Noise_Mask; uniform float4 _Noise_Mask_ST;
uniform float4 _node_8634;
uniform sampler2D _GrabTexture;
float4 _GrabTexture_ST;
struct VertexInput {
float4 vertex : POSITION;
float2 texcoord0 : TEXCOORD0;
float4 vertexColor : COLOR;
};
struct VertexOutput {
float4 pos : SV_POSITION;
float2 uv0 : TEXCOORD0;
float4 vertexColor : COLOR;
};
VertexOutput vert(VertexInput v)
{
VertexOutput o = (VertexOutput)0;
o.uv0 = v.texcoord0;
o.vertexColor = v.vertexColor;
o.pos = UnityObjectToClipPos(v.vertex);
//计算该模型顶点在屏幕坐标的纹理信息(是的仅捕获对象后的屏幕纹理而非全屏)
float4 screenUV = ComputeGrabScreenPos(o.pos);
o.uv0 = screenUV.xy / screenUV.w;
return o;
}
float4 frag(VertexOutput i, float facing : VFACE) : COLOR
{
float isFrontFace = (facing >= 0 ? 1 : 0);
float faceSign = (facing >= 0 ? 1 : -1);
// Lighting:
// Emissive:
float4 node_7596 = _Time + _TimeEditor;
float2 node_3132 = (i.uv0 + (float2(_Noise_SV.r,_Noise_SV.g)*node_7596.g));
float4 node_6583 = tex2D(_Noise,TRANSFORM_TEX(node_3132, _Noise));
float2 node_5883 = (i.uv0 + (node_7596.g*float2(_Noise_SV.b,_Noise_SV.a)));
float4 node_133 = tex2D(_Noise,TRANSFORM_TEX(node_5883, _Noise));
float4 _Noise_Mask_var = tex2D(_Noise_Mask,TRANSFORM_TEX(i.uv0, _Noise_Mask));
float2 node_9379 = (i.uv0 + ((float2(node_6583.r,node_133.g)*_Noise_Power)*_Noise_Mask_var.r));
float4 _Maintex_var = tex2D(_GrabTexture,TRANSFORM_TEX(node_9379, _GrabTexture));
float3 emissive = (_Maintex_var.rgb*_node_8634.rgb*i.vertexColor.rgb*2.0);
float3 finalColor = emissive;
return fixed4(finalColor,(_node_8634.a*i.vertexColor.a*_Maintex_var.a));
}
ENDCG
}
}
FallBack "Diffuse"
}
修改不同的_Noise达到不同的效果
1.
2.
不过官方说GrabPass比较耗(感觉Pc上似乎没问题,具体手机上没测试过)。是这样的话,可以通过摄像机,将渲染的内容写到RenderTexture中,脚本赋值Tex实现(shader需要相应修改)。
网上现成的代码
public Camera m_camera; // 和主摄像机参数一样的拍照摄像机
private RenderTexture m_tex; // 摄像机渲染的材质
public Material mat; // 要控制的材质
void Start()
{
m_tex = new RenderTexture(Screen.width, Screen.height, 16);
m_camera.targetTexture = m_tex;
}
void OnPreCull()
{
mat.SetTexture("_MainTex", m_tex); // 给shader的主材质赋值,为屏幕纹理
}
void OnPostRender()
{
mat.SetTexture("_MainTex", null);
}