기사 디렉토리
UV 애니메이션 - 변환
코드
Shader "shader forge/L19_Translate"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {
}
_Opacity ("Opacity",Range(0,1)) = 0.5
_TransRange ("Translate Range", Range(0,1)) = 2
_TransSpeed ("Translate Speed", Range(0,1)) = 2
}
SubShader
{
Tags {
"Queue"="Transparent"
"RenderType" = "Transparent"
"ForceNoShadowCasting" = "True"
"IgnoreProjector" = "True"
}
LOD 100
Pass
{
Blend One OneMinusSrcAlpha //AB
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase_fullshadow
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform half _Opacity;
uniform half _TransRange;
uniform half _TransSpeed;
#define TWO_PI 2 * 3.1415926
void Translate(inout float3 vertex1){
vertex1.y += _TransRange * sin(frac(_Time.z * _TransSpeed)* TWO_PI);
}
v2f vert (appdata v)
{
v2f o;
Translate(v.vertex.xyz);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
half4 var_MainTex = tex2D(_MainTex, i.uv);
half3 finalRGB = var_MainTex.rgb;
half opacity = _Opacity * var_MainTex.a;
return half4(finalRGB * opacity , opacity);
}
ENDCG
}
}
}
최종 효과
UV 애니메이션 - 회전
코드
Shader "shader forge/L19_Rotate"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {
}
_Opacity ("Opacity",Range(0,1)) = 0.5
_RotateRange ("Rotate Range", Range(0,50)) = 2
_RotateSpeed ("Rotate Speed", Range(0,1)) = 2
}
SubShader
{
Tags {
"Queue"="Transparent"
"RenderType" = "Transparent"
"ForceNoShadowCasting" = "True"
"IgnoreProjector" = "True"
}
LOD 100
Pass
{
Blend One OneMinusSrcAlpha //AB
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase_fullshadow
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform half _Opacity;
uniform half _RotateRange;
uniform half _RotateSpeed;
#define TWO_PI 2 * 3.1415926
void Rotate(inout float3 vertex1){
//算出要增加的角度
float theta = _RotateRange * sin(frac(_Time.z * _RotateSpeed)* TWO_PI);
//转化为弧度
float radY = radians(theta);
float sinY, cosY;
//算出该弧度的sin和cos值
sincos(radY,sinY,cosY);
//根据旋转角度,推算出新的xz的坐标
vertex1.xz = float2(vertex1.x * cosY - vertex1.z * sinY,vertex1.x * sinY + vertex1.z * cosY);
}
v2f vert (appdata v)
{
v2f o;
Rotate(v.vertex.xyz);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
half4 var_MainTex = tex2D(_MainTex, i.uv);
half3 finalRGB = var_MainTex.rgb;
half opacity = _Opacity * var_MainTex.a;
return half4(finalRGB * opacity , opacity);
}
ENDCG
}
}
}
최종 효과
UV 애니메이션 - 스케일링
코드
Shader "shader forge/L19_Scale"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {
}
_Opacity ("Opacity",Range(0,1)) = 0.5
_ScaleRange ("Scale Range", Range(0,1)) = 2
_ScaleSpeed ("Scale Speed", Range(0,1)) = 2
}
SubShader
{
Tags {
"Queue"="Transparent"
"RenderType" = "Transparent"
"ForceNoShadowCasting" = "True"
"IgnoreProjector" = "True"
}
LOD 100
Pass
{
Blend SrcAlpha OneMinusSrcAlpha //AB
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase_fullshadow
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform half _Opacity;
uniform half _ScaleRange;
uniform half _ScaleSpeed;
#define TWO_PI 2 * 3.1415926
void Scale(inout float3 vertex1){
vertex1.xyz *= 1.0 + _ScaleRange * sin(frac(_Time.z * _ScaleSpeed)* TWO_PI);
}
v2f vert (appdata v)
{
v2f o;
Scale(v.vertex.xyz);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
half4 var_MainTex = tex2D(_MainTex, i.uv);
half3 finalRGB = var_MainTex.rgb;
half opacity = _Opacity * var_MainTex.a;
return half4(finalRGB * opacity , opacity);
}
ENDCG
}
}
}
최종 효과
변환, 회전 및 크기 조정의 혼합 응용 프로그램 - 고스트 플로팅
이 부분의 원리는 위의 3가지를 혼합한 것이지만 버텍스 컬러를 기준으로 다른 부분의 UV 애니메이션을 처리하는 것도 매우 중요한 포인트가 있습니다 .
코드
Shader "shader forge/L19_BlendTRS"
{
Properties
{
_MainTex ("Texture", 2D) = "gray" {
}
_Opacity ("Opacity",Range(0,1)) = 0.5
//天使圈缩放。Z是高度校正,因为缩放是基于模型中心进行缩放,这就导致如果不对天使圈进行高度校正,天使圈就会变高或者变低
_ScaleParams ("Circle Scale X:Intensity Y:Speed Z:jiaozheng", vector) = (0.2, 1.0, 4.5, 0.0)
//左右扭动。
_SwingXParams ("X_niudong X:Intensity Y:Speed Z:WaveLength", vector) = (1.0, 3.0, 1.0, 0.0)
//前后扭动
_SwingZParams ("Z_niudong X:Intensity Y:Speed Z:WaveLength", vector) = (1.0, 3.0, 1.0, 0.0)
//上下起伏
_SwingYParams ("Y_qifu X:Intensity Y:Speed Z:Delay", vector) = (1.0, 3.0, 1.0, 0.0)
//摇头
_ShakeYParams ("Y_yaotou X:Intensity Y:Speed Z:Delay", vector) = (20.0, 3.0, 0.3, 0.0)
}
SubShader
{
Tags {
"Queue"="Transparent"
"RenderType" = "Transparent"
"ForceNoShadowCasting" = "True"
"IgnoreProjector" = "True"
}
LOD 100
Pass
{
Blend One OneMinusSrcAlpha //AB
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase_fullshadow
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 color1 : COLOR;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 color1 : COLOR;
float4 vertex : SV_POSITION;
};
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform half _Opacity;
uniform half3 _ScaleParams;
uniform half3 _SwingXParams;
uniform half3 _SwingZParams;
uniform half3 _SwingYParams;
uniform half3 _ShakeYParams;
#define TWO_PI 2 * 3.1415926
//顶点动画方法
void AnimGhost(inout float3 vertex1, inout float3 color){
//天使圈缩放,天使圈能缩放的范围只有顶点色为绿色的部分,所以要乘颜色的g通道
float scale = _ScaleParams.x * color.g * sin(frac(_Time.z * _ScaleParams.y) * TWO_PI);
//天使圈的xyz都发生缩放,加一是为了不让缩放发生颠倒
vertex1.xyz *= 1.0 + scale;
//对天使圈的高度进行校正,使它不会上下移动,并且是在原点以上的区域内进行缩放
vertex1.y += _ScaleParams.z * -scale;
//幽灵身体摆动,身体也就是顶点色为红色的部分
//跟每个顶点的高度有关,每个顶点的高度是不一样的,所以波动的大小也是不一样的
float swingX = _SwingXParams.x * sin(frac(_Time.z * _SwingXParams.y + vertex1.y * _SwingXParams.z) * TWO_PI);
//同上
float swingZ = _SwingZParams.x * sin(frac(_Time.z * _SwingZParams.y + vertex1.y * _SwingZParams.z) * TWO_PI);
vertex1.xz += float2(swingX, swingZ) * color.r;
//幽灵摇头,天使圈的摇动滞后
float radY = radians(_ShakeYParams.x) * (1.0 - color.r) * sin(frac(_Time.z * _ShakeYParams.y - color.g * _ShakeYParams.z) * TWO_PI);
float sinY, cosY = 0;
sincos(radY,sinY,cosY);
vertex1.xz = float2(vertex1.x * cosY - vertex1.z * sinY,vertex1.x * sinY + vertex1.z * cosY);
//整体起伏动画,同样,天使圈的起伏滞后
float swingY = _SwingYParams.x * sin(frac(_Time.z * _SwingYParams.y - color.g * _SwingYParams) * TWO_PI);
vertex1.y += swingY;
//处理顶点色,主要是为了增加天使圈的动画效果,让它变亮且闪烁(scale的值有时为-1,那lightness就为0,就闪烁),其他区域则保持不变
float lightness = 1.0 + color.g * 1.0 + scale * 2.0;
color = float3(lightness, lightness,lightness);
}
v2f vert (appdata v)
{
v2f o;
AnimGhost(v.vertex.xyz, v.color1.rgb);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.color1 = v.color1;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
half4 var_MainTex = tex2D(_MainTex, i.uv);
half3 finalRGB = var_MainTex.rgb * i.color1.rgb;
half opacity = _Opacity * var_MainTex.a;
return half4(finalRGB * opacity , opacity);
}
ENDCG
}
}
}