unity urp 实现遮挡显示角色轮廓
Posted 暮志未晚Webgl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity urp 实现遮挡显示角色轮廓相关的知识,希望对你有一定的参考价值。
这个效果在大部分手游中都有此效果。
就是如果角色被场景物体遮挡住了,会显示一个结构描边的效果。没有挡住的部分,则正常显示。
接下来讲解一下简单实现思路,模型需要渲染两次:
第一次一次是在正常渲染模型时,写入模板测试数据,深度测试不通过则不会写入模板测试数据,以此来判断当前哪些部分被遮挡住。
第二次是在后处理之前进行渲染,因为在后处理中是无法获取模板数据的。第二次渲染时,深度测试是全通过的,如果不全通过,被遮挡的部分还是无法渲染出来相关内容。模板测试则判断是否与第一次写入的值是否相等,因为第一次渲染写入模板测试值时,被遮挡部分是没有写入的。
将值不相等的部分渲染出来,则实现了次效果。
接下来进入实现。
你需要在角色shader上面增加此段代码,含义为,写入模板,数值为2,Comp Always 意思 GPU 为所有像素的模板测试执行的操作。后面两个是通过了模板和深度测试后替换成2,没有通过深度通过模板了也设置成2 。反正只要深度没通过的,其它的模板值全设置成2 。这样方便后面做对比。
在renderFeature这里,我直接用了内置的增加pass的,懒得再写了。
设置在后处理之前添加pass。
内置的需要设置LayerMask,大家需要将角色设置成相应的layer,要不然就自己实现一下renderFeature。
添加材质。
深度测试始终可以通过。
模板测试设置成和角色设置的相同的数值。
然后只在不相等的情况下进行渲染。
这样就实现了相应的效果。
轮廓shader也只是一个简单的fresnel效果,列一下。
Shader "Universal Render Pipeline/ROLE/RoleOutLine"
Properties
[MainTexture] _BaseMap ("Albedo", 2D) = "white"
[MainColor] _BaseColor ("Color", Color) = (1, 1, 1, 1)
_Cutoff ("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
_VertexOffset ("顶点偏移", Float) = 0
_Power("Power", Range(0.0, 10.0)) = 1
_FresnelIntensity("FresnelIntensity", Range(0.0, 5.0)) = 1
_Cull ("Cull", Int) = 2
SubShader
Pass
Cull[_Cull]
ZTest Always
Blend SrcAlpha OneMinusSrcAlpha
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma instancing_options renderinglayer
#pragma multi_compile _ DOTS_INSTANCING_ON
#pragma vertex LitPassVertex
#pragma fragment LitPassFragment
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
//需要光照系统时增加此引入
// #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Attributes
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 tangentOS : TANGENT;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
;
struct Varyings
float2 uv : TEXCOORD0;
float4 positionCS : SV_POSITION;
float3 normalWS : TEXCOORD1;
float3 positionWS : TEXCOORD2;
UNITY_VERTEX_INPUT_INSTANCE_ID
;
TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap);
CBUFFER_START(UnityPerMaterial)
half4 _BaseColor;
half4 _BaseMap_ST;
half _Cutoff;
half _VertexOffset;
half _Power;
half _FresnelIntensity;
CBUFFER_END
// Used in Standard (Physically Based) shader
Varyings LitPassVertex(Attributes input)
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
//通过法向偏移顶点
half3 positionOS = input.positionOS.xyz;
positionOS += input.normalOS * _VertexOffset;
output.positionCS = TransformObjectToHClip(positionOS);
output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap);
output.normalWS = normalInput.normalWS;
output.positionWS = TransformObjectToWorld(positionOS);
return output;
half4 LitPassFragment(Varyings input) : SV_Target
UNITY_SETUP_INSTANCE_ID(input);
//---------------输入数据-----------------
float2 UV = input.uv;
half3 viewDirWS = normalize(GetWorldSpaceViewDir(input.positionWS));
half fresnel = saturate(1.0 - dot(input.normalWS, viewDirWS));
fresnel = pow(fresnel, _Power);
half4 color = _BaseColor * _FresnelIntensity;
// clip(color.r - _Cutoff);
return half4(color.rgb, fresnel);
ENDHLSL
FallBack "Hidden/Universal Render Pipeline/FallbackError"
// CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.RoleShader"
就这么简单,你们学废了吗。
以上是关于unity urp 实现遮挡显示角色轮廓的主要内容,如果未能解决你的问题,请参考以下文章