微网站怎么做的好湖南正规seo公司
这个效果在大部分手游中都有此效果。
就是如果角色被场景物体遮挡住了,会显示一个结构描边的效果。没有挡住的部分,则正常显示。
接下来讲解一下简单实现思路,模型需要渲染两次:
第一次一次是在正常渲染模型时,写入模板测试数据,深度测试不通过则不会写入模板测试数据,以此来判断当前哪些部分被遮挡住。
第二次是在后处理之前进行渲染,因为在后处理中是无法获取模板数据的。第二次渲染时,深度测试是全通过的,如果不全通过,被遮挡的部分还是无法渲染出来相关内容。模板测试则判断是否与第一次写入的值是否相等,因为第一次渲染写入模板测试值时,被遮挡部分是没有写入的。
将值不相等的部分渲染出来,则实现了次效果。
接下来进入实现。
你需要在角色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 AlwaysBlend SrcAlpha OneMinusSrcAlphaHLSLPROGRAM#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) shaderVaryings 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"}
就这么简单,你们学废了吗。