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

Viewed 783

I'm trying to make a 2D top down game with a field of view.

My field of view is shown by a 2D mesh of the fov, not being able to pass through walls.

I need to be able to put some objects such as enemies in a layer that's only rendered when it's inside the view cone.

I was following this tutorial but couldn't find the overwrite setting shown at 18:16 (I believe this is because the LWRP no longer exists in Unity). Are there any alternatives or other solutions?

4 Answers

The concept of using Layer-wise render passes and the stencil buffer is basically still the same also in URP (the replacement for LWRP).

The asset to configure this should by default be in

 Assets/UniversalRenderPipelineAsset_Renderer

Also see See Through Objects with Stencil Buffers using Unity URP which explains it pretty good.


Or if you use the built-in render pipeline you would need shaders that directly implement this via a Stencil pass or subshader.


As an alternative you can also use the DepthTexture. For some examples using that and the ShaderGraph checkout Creating Overlap Shader Effects, Such as Underwater and Night Vision, in Unity's Shader Graph.

The solution used in your tutorial is to have a shader using the stencil buffer to only show the part of the enemies that stands inside your FOV mesh.

This solution a quite possible in any Render Pipeline

Hope that helped ;)

if you want to implement it from scratch and WITH BUILT-IN RENDER PIPELINE, you can read along :

lets say this is the scene , the white plane is fov and cubes are enemies: enter image description here

the fov can have a simple shader. very simple shader. this for example:

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
        }
    }
}

Then you'll need a seperate camera to render ONLY the fov mesh and save it as an image, which we know as RenderTexture. which will look like a black and white mask: enter image description here

then make another camera layer that only renders enemies: enter image description here

then add the generated mask to it: enter image description here

then put it on top of the main camera: enter image description here

Related