Маска пересечения единства

Есть ли способ определить, попадает ли объект с определенным количеством вершин в плоскость? Если это так, я хочу нарисовать его в двоичном виде (черный / белый) на плоскости или создать текстуру с ним.

И меня также не волнует, может ли это быть создано только с помощью радиопередач или некоторых хитрых физических операций / шейдеров / и т. Д. Мне просто интересно, какой математический алгоритм может создать это.

Вот пример того, чего я пытаюсь достичь: Вот пример того, чего я пытаюсь достичь

Ура, Майкл

3 ответа

Решение

Большинство игр добиваются этого с помощью специализированных шейдеров:

  1. Первый проход отображает карту глубины для непрозрачных объектов в сцене
  2. Второй проход использует шейдер пересечения для прозрачных объектов

Шейдер пересечения ищет фрагменты, глубина которых равна (или почти равна) глубине от первого прохода, а затем по-разному окрашивает эти фрагменты.

Вопрос об обмене стеками в разработке игр более детален, включая скриншоты и демонстрацию WebGL.

В вашем случае это может выглядеть так:

  1. Сделать плоскость непрозрачной геометрией
  2. Визуализируйте другие объекты, используя шейдер пересечения
    • Фрагменты, которые пересекают плоскость, нарисованы
    • Фрагменты, которые не пересекают плоскость, отбрасываются

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

Написав шейдер самостоятельно, я много раз сталкивался с этим вопросом, потому что поиск изображений Google показывает его каждый раз.

Возможно, я опоздал на 4 года, но для всех остальных я написал шейдер, который делает именно то, что на картинке:

Шейдер для стены (ShaderOne)

      Shader "Custom/ShaderOne"
{
    SubShader {
        Tags { "RenderType"="Opaque" "Queue"="Geometry"}
            Pass {
            Stencil {
                Ref 2
                Comp always
                Pass replace 
            }

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            struct appdata {
                float4 vertex : POSITION;
            };
            struct v2f {
                float4 pos : SV_POSITION;
            };
            v2f vert(appdata v) {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                return o;
            }
            half4 frag(v2f i) : SV_Target {
                return half4(0.5,0.5,0.5,1);
            }
            ENDCG
        }
    } 
}

Шейдер для объекта(ов) (ShaderTwo)

      Shader "Custom/ShaderTwo"
{
    SubShader {
        Tags {"Queue" = "Transparent" "RenderType"="Transparent" }
        Blend SrcAlpha OneMinusSrcAlpha

        Pass {

            Stencil {
                Ref 2
                Comp equal
                Pass IncrWrap
                ZFail keep
            }

            ZTest less
            Cull Front
            ZWrite OFF

            CGPROGRAM
            #pragma vertex vert 
            #pragma fragment frag alpha
            struct appdata {
                float4 vertex : POSITION;
            };
            struct v2f {
                float4 pos : SV_POSITION;
            };
            v2f vert(appdata v) {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                return o;
            }
            half4 frag(v2f i) : SV_Target {
                return half4(0,0,1,0.0);
            }
            ENDCG
        }
   
        Pass {

            Stencil {
                Ref 2
                Comp equal
                Pass keep
                ZFail keep
            }

            ZTest less
            Cull Back
            ZWrite OFF

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            struct appdata {
                float4 vertex : POSITION;
            };
            struct v2f {
                float4 pos : SV_POSITION;
            };
            v2f vert(appdata v) {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                return o;
            }
            half4 frag(v2f i) : SV_Target {
                return half4(1,0,0,0.5);
            }
            ENDCG
        }
    } 
}
Другие вопросы по тегам