文章目录
- 前言
- 一、实现思路
- 二、实现URP下的顶点偏移
- 1、在顶点着色器中使用正弦函数,实现左右摇摆的效果
- 2、在正弦函数的传入参数中,加入一个扰度值,实现不规则的顶点偏移
- 3、修改正弦函数的振幅 A,让我们的偏移程度合适
- 4、修改正弦函数的 ω 来调节周期,调节偏移频率
- 5、对其 x 也做同样的偏移(该效果根据个人喜好添加)
- 6、在属性面板定义一个四维变量 用来控制 正弦的振幅 和 周期
- 三、测试代码
前言
在上篇文章中,我们实现了URP下的半透明效果。
- Unity中URP下的半透明效果实现
在这篇文章中,我们实现一下像鬼魂一样的顶点偏移效果。
一、实现思路
在顶点着色器中,对模型本地空间坐标在转化成齐次裁剪坐标前,进行赋值修改
- y = A sin(ωx + φ) + B
二、实现URP下的顶点偏移
1、在顶点着色器中使用正弦函数,实现左右摇摆的效果
v.vertexOS.z += sin(_Time.y);
2、在正弦函数的传入参数中,加入一个扰度值,实现不规则的顶点偏移
这里用模型顶点本地空间下的 y 值 作为扰度值
v.vertexOS.z += sin(_Time.y + v.vertexOS.y);
3、修改正弦函数的振幅 A,让我们的偏移程度合适
- 在图形计算器中,看一下效果
v.vertexOS.z += 0.3 * sin(_Time.y + v.vertexOS.y);
4、修改正弦函数的 ω 来调节周期,调节偏移频率
- 在图形计算器中,看一下效果
v.vertexOS.z += 0.3 * sin((_Time.y + v.vertexOS.y)*6);
5、对其 x 也做同样的偏移(该效果根据个人喜好添加)
v.vertexOS.x += 0.3 * sin((_Time.y + v.vertexOS.y)*6);
6、在属性面板定义一个四维变量 用来控制 正弦的振幅 和 周期
_Animation(“Repeat(XY) Intensity(ZW)”,Vector) = (0,0,0,0)
- 在顶点着色器中
v.vertexOS.z += _Animation.z * sin((_Time.y + v.vertexOS.y)_Animation.x);
v.vertexOS.x += _Animation.w * sin((_Time.y + v.vertexOS.y)_Animation.y);
三、测试代码
为了同时支持 Universal Render Pipeline 和 BuildIn Render Pipeline。
需要写一个同样逻辑 BRP 下的SubShader
//URP下的菲涅尔效果
//URP下的透明效果
//URP下的顶点偏移
Shader "MyShader/URP/P3_2_5"
{Properties{_FresnelColor("FresnelColor",Color) = (0,0,0,0)_Fresnel("Fade(X) Intensity(Y) Top(Z) Offset(W)",Vector) = (4,1,1,0)_Animation("Repeat(XY) Intensity(ZW)",Vector) = (0,0,0,0)}SubShader{Tags{//告诉引擎,该Shader只用于 URP 渲染管线"RenderPipeline"="UniversalPipeline"//渲染类型"RenderType"="Transparent"//渲染队列"Queue"="Transparent"}Blend One One ZWrite OnPass{HLSLPROGRAM#pragma vertex vert#pragma fragment frag#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"struct Attributes{float3 vertexOS : POSITION;float3 normalOS : NORMAL;};struct Varyings{float3 vertexOS : TEXCOORD0;float4 vertexCS : SV_POSITION;float3 vertexWS : TEXCOORD1;float3 normalWS : TEXCOORD2;};CBUFFER_START(UnityPerMaterial)half4 _FresnelColor;half4 _Fresnel;float _Offset;float4 _Animation;CBUFFER_ENDVaryings vert(Attributes v){Varyings o;o.vertexOS = v.vertexOS;v.vertexOS.z += _Animation.z * sin((_Time.y + v.vertexOS.y) * _Animation.x);v.vertexOS.x += _Animation.w * sin((_Time.y + v.vertexOS.y) * _Animation.y);o.vertexWS = TransformObjectToWorld(v.vertexOS);o.vertexCS = TransformWorldToHClip(o.vertexWS);o.normalWS = TransformObjectToWorldNormal(v.normalOS);return o;}half4 frag(Varyings i) : SV_Target{//dot(N,L)half3 N = normalize(i.normalWS);half3 L = normalize(_WorldSpaceCameraPos - i.vertexWS);half NdotL = dot(N, L);//菲涅尔效果 1 - dot(N,L)half fresnel = 1 - saturate(NdotL);//菲涅尔自定义half4 fresnel1 = pow(fresnel, _Fresnel.x) * _Fresnel.y * _FresnelColor;//透明渐变效果float alphaMask = saturate(i.vertexOS.y * -1 + i.vertexOS.x * -1 + _Fresnel.w);fresnel1 = alphaMask * fresnel1;//头部菲涅尔效果和下部菲涅尔效果做出区别fresnel1 = lerp(fresnel1, _FresnelColor * alphaMask * fresnel1, alphaMask * _Fresnel.z);return fresnel1;}ENDHLSL}}SubShader{Tags{//渲染类型"RenderType"="Transparent"//渲染队列"Queue"="Transparent"}Blend One One ZWrite OnPass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float3 vertexOS : POSITION;float3 normalOS : NORMAL;};struct v2f{float3 vertexOS : TEXCOORD0;float4 vertexCS : SV_POSITION;float3 vertexWS : TEXCOORD1;float3 normalWS : TEXCOORD2;};half4 _FresnelColor;half4 _Fresnel;float _Offset;float4 _Animation;v2f vert(appdata v){v2f o;o.vertexOS = v.vertexOS;v.vertexOS.z += _Animation.z * sin((_Time.y + v.vertexOS.y) * _Animation.x);v.vertexOS.x += _Animation.w * sin((_Time.y + v.vertexOS.y) * _Animation.y);o.vertexWS = mul(unity_ObjectToWorld,v.vertexOS);o.vertexCS = UnityWorldToClipPos(o.vertexWS);o.normalWS = UnityObjectToWorldNormal(v.normalOS);return o;}half4 frag(v2f i) : SV_Target{//dot(N,L)half3 N = normalize(i.normalWS);half3 L = normalize(_WorldSpaceCameraPos - i.vertexWS);half NdotL = dot(N, L);//菲涅尔效果 1 - dot(N,L)half fresnel = 1 - saturate(NdotL);//菲涅尔自定义half4 fresnel1 = pow(fresnel, _Fresnel.x) * _Fresnel.y * _FresnelColor;//透明渐变效果float alphaMask = saturate(i.vertexOS.y * -1 + i.vertexOS.x * -1 + _Fresnel.w);fresnel1 = alphaMask * fresnel1;//头部菲涅尔效果和下部菲涅尔效果做出区别fresnel1 = lerp(fresnel1, _FresnelColor * alphaMask * fresnel1, alphaMask * _Fresnel.z);return fresnel1;}ENDCG}}
}