1. 程式人生 > 實用技巧 >URP中原神中人物虛化的效果實現

URP中原神中人物虛化的效果實現

原神中當相機距離角色很近的時候會表現出如下虛化的效果:

經過筆者仔細觀察,發現其實就是做了個鏤空效果,所以開始動手實現,程式碼如下:

Shader "Unlit/VirtualShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _TilingTex("TileMap",2D) = "white"{}
        _TilingValue("TilingValue",float) = 20
    }
    SubShader
    {
        Tags { "
RenderType"="Transparent"} LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float3 normal:NORMAL; };
struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float4 screenPos : TEXCOORD1; float3 worldNormal:TEXCOORD2; }; sampler2D _MainTex; sampler2D _TilingTex; float4 _MainTex_ST;
float _TilingValue; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.screenPos = ComputeScreenPos(o.vertex); o.worldNormal = UnityObjectToWorldNormal(v.normal); return o; } fixed4 frag (v2f i) : SV_Target { float2 uv = i.screenPos.xy/i.screenPos.w; half clipValue = tex2D(_TilingTex,uv*_TilingValue).r-0.5; half3 lightDir = normalize(_WorldSpaceLightPos0.xyz); half3 worldNormal = normalize(i.worldNormal); clip(clipValue); fixed4 col = tex2D(_MainTex, i.uv)*saturate(dot(lightDir,worldNormal)); return col; } ENDCG } } }

主要思路就是從螢幕空間取樣一張tiling的mask,根據mask去做alphatest。效果如下:

需要擴充套件自行新增,shader本身也沒有什麼難度,就不做贅述了。