Unity Intersections Mask
Asked Answered
L

3

6

Is there any way to detect if an object with a certain amount of vertices hits a plane? If so, I want to draw it in binary (black/white) onto the plane or create a texture with it.

And I also don't care about if this can only be created with raycasts or some tricky physics operations / shaders / etc.. I'm just wondering what mathematical algorithm could create this.

Here is an example of what I'm trying to achieve: Here is an example of what im trying to achieve

Cheers, Michael

Lawson answered 16/2, 2017 at 15:34 Comment(0)
P
3

Most games will achieve this with specialized shaders:

  1. First pass renders a depth map for opaque objects in the scene
  2. Second pass uses an intersection shader for transparent object(s)

The intersection shader looks for fragments where depth is equal (or nearly equal) to the depth from the first pass, then colors those fragments differently.

A question on the Game Development Stack Exchange goes into more detail, including screenshots and a WebGL demo.

In your case, this might look like:

  1. Render the plane as opaque geometry
  2. Render the other objects using intersection shader
    • Fragments that intersect the plane are drawn
    • Fragments that do not intersect the plane are discarded

Whether you are doing this for an entire scene, or just to generate a texture that you can apply to some other object, the shader principles remain the same either way.

Preciosity answered 16/2, 2017 at 17:23 Comment(1)
Could u maybe give me an example of this shader in unity.. im not that good with shaders?Lawson
V
2

Writing the shader myself I stumbled across this Question so many times because google image search shows it every time.

I might be 4 years to late but for everyone else, I've written a shader that does exactly what's on the picture:

Showcase

Shader for the Wall (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
        }
    } 
}

Shader for the Object(s) (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
        }
    } 
}
Vorous answered 18/12, 2021 at 9:58 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.