复刻万恶之源二游中人物虚化效果
Github源码传送门————>CharacterFadeOutPixelation
Bilibili教程传送门————>小祥带你实现绝区零人物虚化效果
Bilibili教程传送门————>小祥带你实现绝区零人物虚化效果透明度剔除(AlphaClip)

1.整体思路
最开始的思路是单独渲染人物层级并调整透明度然后混合叠加到其他画面上,同时生成一张人物遮罩,在后处理阶段对人物区域进行像素化。这种做法一方面在渲染人物的时候是作为非透明物体渲染的,人物的深度已经写进深度贴图,会导致混合叠加画面之后,人物身后的透明物体不渲染,所以还需要单独处理人物深度,另一方面需要渲染三张贴图,还是有点繁杂了。不过视频和Github上的代码并没有删除,感兴趣的小伙伴依旧可以通过视频了解。实际上只需要一个步骤就可以实现这种效果,那就是使用网格遮罩进行透明度剔除(AlphaClip),剔除部分像素来得到类似透明度降低的效果。原理实际上跟我们人眼的特性(bug笑)有关,人眼无法分辨单个像素,而是会对一个区域内的颜色亮度进行平均感知。那么部分像素被剔除后,形成了一种视觉平均混合的疏密变化,人眼会误认为是整体变透明了。
2.Shader代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| Shader "Custom/CharacterAlphaClip" { Properties { _GridTex ("Grid Pattern", 2D) = "white" {} _GridPixelSize ("Grid Pixel Size", Float) = 64 _GridAlphaIntensity ("Grid Alpha Intensity", Float) = 12 _AlphaClipThreshold ("Alpha Clip Threshold", Range(0, 1)) = 0.5
} SubShader { Tags { "RenderType"="Transparent" "Queue"="Transparent" "RenderPipeline"="UniversalPipeline" } Blend SrcAlpha OneMinusSrcAlpha Cull Off ZWrite Off Pass { Name "CharacterAlphaClip"
HLSLPROGRAM #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
#pragma vertex Vert #pragma fragment Frag
TEXTURE2D(_GridTex); SAMPLER(sampler_GridTex); float _GridPixelSize; float _GridAlphaIntensity; float _AlphaClipThreshold; float4 Frag(Varyings input) : SV_Target0 { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = input.texcoord.xy;
half4 color = SAMPLE_TEXTURE2D_X_LOD(_BlitTexture, sampler_LinearRepeat, uv, _BlitMipLevel);
float2 screenUV = uv * _ScreenParams.xy / _GridPixelSize;
float grid = SAMPLE_TEXTURE2D(_GridTex, sampler_GridTex, screenUV).a; float alpha = saturate(grid * _GridAlphaIntensity); clip(alpha - _AlphaClipThreshold);
return color; } ENDHLSL } } }
|
代码思路也很清晰,_GridTex是网格遮罩贴图,采样贴图的值乘上一个强度值(_GridAlphaIntensity),得到当前像素的alpha值,然后减去透明剔除阈值(_AlphaClipThreshold),也就是小于阈值的像素被剔除,在相机角度变化时通过控制_AlphaClipThreshold来使得更多的像素被剔除,就会角色透明度降低的效果。同时使用剔除的话这一部分的深度也不会被写入,可以说是一步到位。
3.ShaderGraph
实际上这一段透明度剔除的代码应该加在角色材质对应shader内,渲染的同时同步进行透明度剔除。但是另外写玩家渲染的shader或者改官方的LitShader太繁琐了,这里直接给出ShaderGraph实现。

需要关注的点是,ScreenPosition节点在Default模式下输出的是归一化屏幕坐标(0~1),乘以_ScreenParams.xy(像素分辨率),就得到了当前像素的屏幕绝对位置(以像素为单位),可以用于进行逐像素精确对齐的采样。也就是恒定像素密度采样UV,让采样结果在屏幕空间中映射时,不随屏幕分辨率或物体位置角度变化,而保持像素对齐的视觉效果,其余内容和代码版完全一致。
完结撒花~
