Unity 交叉路口遮罩

Unity Intersections Mask

有没有什么方法可以检测一个有一定数量顶点的物体是否撞到一个平面上?如果是这样,我想用二进制 (black/white) 将它绘制到平面上或用它创建纹理。

而且我也不关心这是否只能通过光线投射或一些棘手的物理操作/着色器等来创建。我只是想知道什么数学算法可以创建它。

这是我正在努力实现的一个例子:

干杯,迈克尔

大多数游戏将通过专门的着色​​器实现这一点:

  1. 第一遍渲染场景中不透明物体的深度图
  2. 第二遍使用交叉着色器用于透明对象

相交着色器查找深度等于(或几乎等于)第一遍深度的片段,然后对这些片段进行不同的着色。

A question on the Game Development Stack Exchange 进入更多细节,包括屏幕截图和 WebGL 演示。

在你的情况下,这可能看起来像:

  1. 将平面渲染为不透明几何体
  2. 使用相交着色器渲染其他对象
    • 绘制与平面相交的片段
    • 与平面相交的片段被丢弃

无论您是为整个场景执行此操作,还是只是为了生成可应用于其他对象的纹理,无论哪种方式,着色器原理都保持不变。

您可以在 unity 论坛上查看类似的帖子:

图片link: https://forum.unity.com/proxy.php?image=https%3A%2F%2Flh3.googleusercontent.com%2FRnj-LM2i238HSMGSEhRUEn81M7TrdifT6WZziEU2LpwpAYShVkXbdpBImOSc4DSxlsGyaN6eTG1HWP9qKrG7E7StGGMgF4e27bHVLsoWvQXelyPw0fHhZ2fpRPeERg8twaeo3omd3Q%3Dw660-h558-no&hash=41a049afb39e6495d86db0ab14a8e936

论坛主题: https://forum.unity.com/threads/intersection-shader-cull-front-minus-cull-back.536812/

自己编写着色器我多次偶然发现这个问题,因为 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
        }
    } 
}