0
\$\begingroup\$

I am a beginner shader worlds, it is much difficult to learn(anyhow i try sometime).I am searching a shader that can sense collision/intersection with other objects so that i can stop its rendering at that intersection point. I currently get this shader it allow to detect the intersection(don't know how) but its mesh rendering doesn't stop.

Shader "Custom/IntersectionHighlights"
{
    Properties
    {
        _RegularColor("Main Color", Color) = (1, 1, 1, .5) //Color when not intersecting
        _HighlightColor("Highlight Color", Color) = (1, 1, 1, .5) //Color when intersecting
        _HighlightThresholdMax("Highlight Threshold Max", Float) = 1 //Max difference for intersections
    }
    SubShader
    {
        Tags { "Queue" = "Transparent" "RenderType"="Transparent"  }
        Pass
        {
            Blend SrcAlpha OneMinusSrcAlpha
            ZWrite Off
            Cull Off

            CGPROGRAM
            #pragma target 3.0
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            uniform sampler2D _CameraDepthTexture; //Depth Texture
            uniform float4 _RegularColor;
            uniform float4 _HighlightColor;
            uniform float _HighlightThresholdMax;

            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 projPos : TEXCOORD1; //Screen position of pos
            };

            v2f vert(appdata_base v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.projPos = ComputeScreenPos(o.pos);

                return o;
            }

            half4 frag(v2f i) : COLOR
            {
                float4 finalColor = _RegularColor;

                //Get the distance to the camera from the depth buffer for this point
                float sceneZ = LinearEyeDepth (tex2Dproj(_CameraDepthTexture,
                                                         UNITY_PROJ_COORD(i.projPos)).r);

                //Actual distance to the camera
                float partZ = i.projPos.z;

                //If the two are similar, then there is an object intersecting with our object
                float diff = (abs(sceneZ - partZ)) /
                    _HighlightThresholdMax;

                if(diff <= 1)
                {
                    finalColor = lerp(_HighlightColor,
                                      _RegularColor,
                                      float4(diff, diff, diff, diff));
                }

                half4 c;
                c.r = finalColor.r;
                c.g = finalColor.g;
                c.b = finalColor.b;
                c.a = finalColor.a;

                return c;
            }

            ENDCG
        }
    }
    FallBack "VertexLit"
}

Current effect of this shader is enter image description here

The marked area by arrow should not need to be render

\$\endgroup\$
  • \$\begingroup\$ An image comparing your intended effect with your current results would help clarify this question. By "stop its rendering at that intersection point" do you mean depth testing? It sounds like the depth ordering we do with a depth buffer (ie. each fragment checks the depth buffer at the location it will be drawn, and if there's already a surface rendered nearer to the camera, it aborts its rendering rather than drawing "through" the other object). Transparent shaders need a little extra care to approximate correct depth ordering \$\endgroup\$ – DMGregory Dec 22 '16 at 15:14
  • \$\begingroup\$ Actually you got it right. I am not familiar with the terms of shaders and graphics. I just want to stop the rendering at specific point where it intersect with other object. \$\endgroup\$ – Muhammad Faizan Khan Dec 23 '16 at 4:26
  • \$\begingroup\$ @DMGregory I have also update the question with picture. please check \$\endgroup\$ – Muhammad Faizan Khan Dec 23 '16 at 4:34
  • \$\begingroup\$ Ahh, you're asking for something completely different. You won't get this from a shader alone, as you effectively need a raycast from each drawn point back to its source to check if any occluders lie in-between. You could approximate this by rendering a depth map from the source point of view, effectively a shadow map. Or, if your geometry is simple, do your raycasts CPU-side and deform your mesh to conform to what it hits. Try telling us a bit more about the context in which you're using this effect - there may be some options better-suited to your case than others. \$\endgroup\$ – DMGregory Dec 23 '16 at 4:37
  • \$\begingroup\$ but you told me that "each fragment checks the depth buffer at the location it will be drawn, and if there's already a surface rendered nearer to the camera, it aborts its rendering rather than drawing "through" the other object". I guess it is possible? \$\endgroup\$ – Muhammad Faizan Khan Dec 23 '16 at 4:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.