嗨~~!,熊猫老师又来了 ,这次为大家分享项目中非常实用的一个技术点:遮挡显示。
老规矩,上才艺:
实现原理 :对模型渲染两次。
第一次: 正常渲染物体,深度测试不通过的情况下不会写入模板测试数据,以此来判断遮挡或者没有遮挡部分。
第二次:在后处理之前进行渲染(后处理渲染之后是无法获取模板数据),深度测试不通过,无法渲染相关信息。
具体实现方案
1:在原物体(角色)shader 中 写入深度测试模板:
代码如下:
Stencil{Ref 2 //写入模板,数值为2 Comp Always // Gpu 执行所有的像素模板测试Pass Replace //只要深度测试没有通过,值设成2Fail Replace //只要深度测试没有通过,值设成2}
2:创建边缘光效果shader
比较简单,一个Fresnel 效果实现。
half fresnel = saturate(1.0 - dot(normalize(i.normalWS), normalize(i.viewDir));fresnel = pow(fresnel, _Power);
2:创建renderFeature
如图 一样的操作就可以了
1:Project Settings ———> Quality
双击进入后:
再双击进入后:
创建一个renderFeature
然后照搬我的就可以了:
注意:Layer Mask 需要和物件(角色)保持同一个层里面
为了方便大家测试,我提供了我的两个shader代码:
物件原生shader(角色)
Shader "XiongMaoWuDao/Player"
{Properties{[MainColor] _BaseColor("BaseColor", Color) = (1,1,1,1)[MainTexture] _BaseMap("BaseMap", 2D) = "white" {}}SubShader{Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalRenderPipeline" "Queue"="Geometry"}Stencil{Ref 2Comp AlwaysPass ReplaceFail Replace }Pass{HLSLPROGRAM#pragma vertex vert#pragma fragment frag#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"struct Attributes{float4 positionOS : POSITION;float2 uv : TEXCOORD0;};struct Varyings{float2 uv : TEXCOORD0;float4 positionHCS : SV_POSITION;};TEXTURE2D(_BaseMap);SAMPLER(sampler_BaseMap);CBUFFER_START(UnityPerMaterial)float4 _BaseMap_ST;half4 _BaseColor;CBUFFER_ENDVaryings vert(Attributes IN){Varyings OUT;OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);return OUT;}half4 frag(Varyings IN) : SV_Target{return SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv) * _BaseColor;}ENDHLSL}}
}
遮挡后的高亮显示shader :
Shader "XiongMaoWuDao/PlayerLine"
{Properties{_FresnelColor ("Fresnel Color", Color) = (1, 1, 1, 1) _Power("Power", Range(0.0, 10.0)) = 1_FresnelIntensity("FresnelIntensity", Range(0.0, 5.0)) = 1 _Cull ("Cull", Int) = 2}SubShader{Tags { "RenderType"="Transparent" "RenderPipeline"="UniversalRenderPipeline" "Queue"="Transparent"}Pass{Name "XiongMaoWuDao"Cull[_Cull]ZTest AlwaysBlend SrcAlpha OneMinusSrcAlphaHLSLPROGRAM#pragma vertex vert#pragma fragment frag#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"struct Attributes{float4 positionOS : POSITION;half3 normalOS : NORMAL;};struct Varyings{float4 positionCS : SV_POSITION;half3 normalWS : TEXCOORD0;half3 viewDir :TEXCOORD1 ;};CBUFFER_START(UnityPerMaterial)half4 _FresnelColor;half _Power;half _FresnelIntensity;CBUFFER_END//菲尼尔反射half XionmgMaoWuDao_Fresnel( half3 normal ,half3 viewDir ,half power){//菲尼尔公式: (1-dot (v,n))^power ;return pow( 1.0- saturate(dot(normal,viewDir).x) ,power);}Varyings vert(Attributes v){Varyings o;o.positionCS = TransformObjectToHClip(v.positionOS.xyz); o.normalWS = TransformObjectToWorldNormal (v.normalOS );float3 positionWS = TransformObjectToWorld(v.positionOS.xyz);o.viewDir =GetWorldSpaceViewDir(positionWS);return o;}half4 frag(Varyings i) : SV_Target{half3 normalWS = normalize (i.normalWS);half3 viewDir = normalize (i.viewDir);half fresnel = XionmgMaoWuDao_Fresnel(normalWS,viewDir,_Power); half4 color = _FresnelColor * _FresnelIntensity;return half4(color.rgb, fresnel);}ENDHLSL}}
}