美文网首页
Shader笔记——遮挡半透效果

Shader笔记——遮挡半透效果

作者: 莫忘初心_倒霉熊 | 来源:发表于2021-11-18 22:49 被阅读0次

在游戏中经常会出现这样的效果,当角色跑到其他物体(如建筑,墙)背后的时候,被物体遮挡的部分会出现半透高亮效果(X-Ray效果),而没有被遮挡的部分依然正常显示,这种效果被称为遮挡半透效果。

1.0 实现原理

遮挡半透效果中包含了俩种显示效果,即半透高亮效果和正常显示效果,因此需要一个Shader中实现这俩种效果,并且需要在被遮挡和不被遮挡俩种不同的条件下分别执行对于的效果。

(1)被遮挡效果:被遮挡的部分并没有被剔除,而是显示为中间半透,边缘发亮效果,类似于菲涅尔效果。因此需要将这个Pass的深度测试比较方法设定为Greater,是被遮挡之后依然可以通过深度测试。
(2)未被遮挡效果:这一部分其实就是正常的Shader效果。

当物体没有被遮挡的时候,遮挡效果的Pass就不会通过深度测试,于是只会显示未被遮挡的正常效果;当物体被遮挡的时候,遮挡效果的Pass就会通过深度测试,而未被遮挡的正常效果则不会通过深度测试,因此不会覆盖已经绘制的遮挡效果。

2.0 实现逻辑

Shader代码如下:

Shader "Samples/X-Ray"
{
    Properties
    {
        [Header(The Blocked Part)]
        [Space(10)]
        _Color ("X-Ray Color", Color) = (0,1,1,1)
        _Width ("X-Ray Width", Range(1, 2)) = 1
        _Brightness ("X-Ray Brightness",Range(0, 2)) = 1

        [Header(The Normal Part)]
        [Space(10)]
        _Albedo("Albedo", 2D) = "white"{}
        [NoScaleOffset]_Specular ("Specular (RGB-A)", 2D) = "black"{}
        [NoScaleOffset]_Normal ("Nromal", 2D) = "bump"{}
        [NoScaleOffset]_AO ("AO", 2D) = "white"{}
    }

    SubShader
    {
        // 本Shader属于不透明效果,因此将渲染类型设置为Opaque
        // 遮挡半透明不需要显示后面的物体,因此将渲染队列设置为Geometry而不是Transparent
        Tags{"RenderType" = "Opaque" "Queue" = "Geometry"}

        //---------- 遮挡效果 ----------
        Pass
        {
            // 深度测试比较方法设置为Greater,从而是物体即使被遮挡也会显示出来
            ZTest Greater
            // 为了不遮挡住后面的Pass,需要将深度写入关闭
            ZWrite Off

            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct v2f
            {
                float4 vertexPos : SV_POSITION;
                float3 viewDir : TEXCOORD0;
                float3 worldNor : TEXCOORD1;
            };

            v2f vert(appdata_base v)
            {
                v2f o;
                o.vertexPos = UnityObjectToClipPos(v.vertex);
                // 获取世界空间视角方向
                o.viewDir = normalize(WorldSpaceViewDir(v.vertex));
                // 获取世界空间法线向量
                o.worldNor = UnityObjectToWorldNormal(v.normal);

                return o;
            }

            fixed4 _Color;
            fixed _Width;
            half _Brightness;

            float4 frag(v2f i) : SV_Target
            {
                // 菲涅尔(Fresnel)算法
                half NDotV = saturate( dot(i.worldNor, i.viewDir));
                NDotV = pow(1 - NDotV, _Width) * _Brightness;

                fixed4 color;
                color.rgb = _Color.rgb;
                color.a = NDotV;
                return color;
            }
            ENDCG
        }

        //---------- 未被遮挡效果 ----------
        CGPROGRAM
        #pragma surface surf StandardSpecular
        #pragma target 3.0

        struct Input
        {
            float2 uv_Albedo;
        };

        sampler2D _Albedo;
        sampler2D _Specular;
        sampler2D _Normal;
        sampler2D _AO;

        void surf(Input IN, inout SurfaceOutputStandardSpecular o)
        {
            o.Albedo = tex2D(_Albedo, IN.uv_Albedo).rgb;

            fixed4 specular = tex2D(_Specular, IN.uv_Albedo);
            o.Specular = specular.rgb;
            o.Smoothness = specular.a;

            o.Normal = UnpackNormal(tex2D(_Normal, IN.uv_Albedo));
        }
        ENDCG
    }
}

效果如图:


遮挡半透效果

3.0 遮挡半透算法缺陷

该描边算法只适合顶点法线方向各异的模型(如球),而对于一些顶点法线方向比较一致的模型(如立方体),当相机朝向与该模型法线方向平行时,不会出现X-Ray效果。如图:


相机朝向对效果的影响
相机朝向对效果的影响

相关文章

  • Shader笔记——遮挡半透效果

    在游戏中经常会出现这样的效果,当角色跑到其他物体(如建筑,墙)背后的时候,被物体遮挡的部分会出现半透高亮效果(X-...

  • 碰撞半透效果

    当物体进入碰撞射线的时候逐渐变成半透效果,离开射线时逐渐恢复原状 源码分享:脚本 Shader

  • Unity Shader深度测试-透视xray(转)

    Unity Shader深度测试-透视xray 透视XRay效果常常用来显示被墙体及其它物体遮挡的物体的轮廓,下面...

  • 遮挡显示

    遮挡显示 Shader "Unlit/MyOwnShader"{Properties{_MainTex ("Tex...

  • Shader笔记-透明效果

    ●透明是游戏中经常使用的一种效果,在实时渲染透明效果,通常会在渲染模型时控制它的透明通道。在unity中实现透明效...

  • Unity_遮挡物体透视效果(一 )

    前言 暂时不太方便上截图,有时间会补上。效果是被遮挡的部分会以设定的颜色亮起,且边缘高亮. shader 直接看s...

  • Godot Shader特效:3D描边(outline)效果 原

    前段时间根据油管上的教程写过一篇Godot Shader特效:2D描边(outline)效果的笔记,此效果实现原理...

  • Shader笔记——描边效果

    在游戏中,为了表现道具的选中效果,通常会在被选中的物体添加一圈描边效果。那么如何通过Shader实现物体的描边效果...

  • Godot Shader特效:SpatialShader(即3D

    之前写过canvas_item类型即2d Shader的溶解效果,原文请见Godot Shader特效:溶解效果(...

  • shader 效果

    闪电https://blog.csdn.net/panda1234lee/article/details/5219...

网友评论

      本文标题:Shader笔记——遮挡半透效果

      本文链接:https://www.haomeiwen.com/subject/gfvjtrtx.html