Как сделать 3d объект видимым за стеной, но невидимым если за стеной и под землей

Я хотел бы начать с того, что мои познания в кодировании шейдеров довольно ограничены. Я знаю основы и со временем могу понять, как работает шейдер, но не более того.

Пожалуйста, взгляните на следующее изображение: Как сделать 3d объект видимым за стеной, но невидимым если за стеной и под землей

У меня есть 4 объекта в сцене выше. Земля (бежевая), один красный куб с левой стороны над землей, один красный куб с правой стороны наполовину над землей и наполовину под землей и стена (синяя) перед двумя кубами. Красные кубы отображаются только в том случае, если они находятся за стеной, поэтому, если я удалю стену, они станут невидимыми.

Чего я хотел бы добиться, так это чтобы красные кубы были видны за стеной, но не под землей. Таким образом, правильный куб должен отображать только верхнюю красную часть, а не нижнюю бежевую часть. Я предполагаю, что нижняя бежевая часть — это рендеринг земли за стеной в области, где за ней находится куб.

Вот 3 шейдера, которые я использую:

Кубики: https://pastebin.com/msuyi1zj

Shader "ZTest Shaders/Cube"
{
    Properties
    {
        ObjectColor("Object Color", Color) = (1, 1, 1, 1)
    }
    SubShader
    {
        Tags {
            "Queue" = "Transparent+10"
        }

        Pass
        {

            ZWrite On
            ZTest Greater

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                fixed4 color : COLOR;
                float4 vertex : SV_POSITION;
            };

            uniform fixed4 ObjectColor;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.color = ObjectColor;
                return o;
            }

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

Земля: https://pastebin.com/ttL45Gjm

Shader "ZTest Shaders/Ground"
{
    Properties
    {
        ObjectColor("Object Color", Color) = (1, 1, 1, 1)
    }
    SubShader
    {
        Tags {
            "Queue" = "Transparent+15"
        }

        Pass
        {

            ZWrite On
            ZTest Less

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                fixed4 color : COLOR;
                float4 vertex : SV_POSITION;
            };

            uniform fixed4 ObjectColor;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.color = ObjectColor;
                return o;
            }

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

Стена: https://pastebin.com/QcL0uY8j

Shader "ZTest Shaders/Wall"
{
    Properties
    {
        ObjectColor("Object Color", Color) = (1, 1, 1, 1)
    }
    SubShader
    {
        Tags {
            "Queue" = "Transparent+5"
        }

        Pass
        {

            ZWrite On

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                fixed4 color : COLOR;
                float4 vertex : SV_POSITION;
            };

            uniform fixed4 ObjectColor;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.color = ObjectColor;
                return o;
            }

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

Чтобы дать вам сценарий, в котором я бы использовал что-то подобное, представьте себе игру RTS, в которой вы хотите, чтобы юниты за стенами или другие объекты были видны, чтобы шейдер куба был похож на шейдер контура или силуэта. Теперь представьте, что вы также хотите, чтобы эти юниты спрятались, уйдя под землю. В настоящее время, если бы они ушли под землю, но также были бы за стеной, их было бы видно.

Заранее большое спасибо!

Одной из идей может быть сравнение выходного цвета, и если он не красный, то ничего не выводить, но я не очень уверен, как это написать, чтобы это работало :(. Если вы посмотрите на pulciu.com/screenshot.jpg, правый куб, который наполовину выше земля и половина под ней, печатает верхнюю часть красной, и это все, что я хотел бы сохранить.

stefanplc 31.07.2019 13:26

Если кто-то еще столкнется с этой проблемой, ответ был опубликован здесь: forum.unity.com/threads/…

stefanplc 31.07.2019 16:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
3 343
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если кто-то еще столкнется с этой проблемой, ответ был опубликован здесь: https://forum.unity.com/threads/need-help-with-my-outline-shaders-visibility-behind-walls.718499/

Это обновленный шейдер:

Shader "ZTest Shaders/Cube"
{
    Properties
    {
        ObjectColor("Object Color", Color) = (1, 1, 1, 1)
    }
    SubShader
    {
        Tags {
            "Queue" = "Transparent+10"
        }

        Pass
        {

            ZWrite On
            ZTest Greater

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                fixed4 color : COLOR;
                float4 vertex : SV_POSITION;
                float3 worldPos : TEXCOORD0;
            };

            uniform fixed4 ObjectColor;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.color = ObjectColor;
                o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                if (i.worldPos.y < 0.0) discard;
                return i.color;
            }
            ENDCG
        }
    }
}

Другие вопросы по теме