Unity 仅从 2D 网格内的层渲染对象

Unity only render objects from a layer inside a 2D mesh

我正在尝试制作一个具有视野的 2D 俯视游戏。

我的视野显示为 fov 的二维网格,无法穿过墙壁。

我需要能够将一些对象(例如敌人)放在仅在视锥内时才渲染的图层中。

我一直在关注 this 教程,但找不到 18:16 处显示的覆盖设置(我相信这是因为 Unity 中不再存在 LWRP)。是否有任何替代方案或其他解决方案?

教程中使用的解决方案是让着色器使用模板缓冲区仅显示站在 FOV 网格内的敌人部分。

这个解决方案在任何渲染管线中都是可行的

希望对您有所帮助 ;)

使用逐层渲染通道和模板缓冲区的概念在 URP(LWRP 的替代品)中也基本相同。

默认情况下配置它的资产应该在

 Assets/UniversalRenderPipelineAsset_Renderer

另见 See Through Objects with Stencil Buffers using Unity URP 解释得很好。


或者,如果您使用内置渲染管道,您将需要通过 Stencil 通道或子着色器直接实现此功能的着色器。


您也可以使用 DepthTexture 作为替代。对于一些使用它和 ShaderGraph 结帐的示例 Creating Overlap Shader Effects, Such as Underwater and Night Vision, in Unity's Shader Graph.

如果您使用的是 2019.3 URP 或更高版本,则需要将 FieldOfView 着色器类型更改为 Universal Render Pipeline/Simple Lit。它具有与视频中的着色器相同的 Render Face 功能。 https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@7.1/manual/simple-lit-shader.html

如果您想从头开始实施并使用内置渲染管道,您可以继续阅读:

假设这是场景,白色平面是 fov,立方体是敌人:

fov 可以有一个简单的着色器。非常简单的着色器。例如:

Shader "Unlit/simple_shader"
{
    Properties
    {
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                return 1;
            }
            ENDCG
        }
    }
}

然后您将需要一个单独的相机来仅渲染 fov 网格并将其保存为图像,我们将其称为 RenderTexture。这看起来像一个黑白面具:

然后制作另一个只渲染敌人的相机层:

然后将生成的掩码添加到其中:

然后放在主摄像头上面: