【问题标题】:Unity Intersections MaskUnity 交叉口遮罩
【发布时间】:2017-07-05 19:40:31
【问题描述】:

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

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

这是我想要实现的一个示例:

干杯,迈克尔

【问题讨论】:

    标签: unity3d geometry mask intersection plane


    【解决方案1】:

    大多数游戏都会使用专门的着色​​器来实现这一点:

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

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

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

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

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

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

    【讨论】:

    • 你能不能给我一个统一的着色器的例子。我对着色器不太好?
    【解决方案2】:
    【解决方案3】:

    自己编写着色器我偶然发现了这个问题很多次,因为谷歌图像搜索每次都会显示它。

    我可能晚了 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
            }
        } 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-02
      • 2012-11-06
      • 1970-01-01
      • 1970-01-01
      • 2015-03-23
      • 2010-12-19
      • 1970-01-01
      相关资源
      最近更新 更多