Home Unity

Highlighting intersections problem

Guessmyname
polycounter lvl 6
Offline / Send Message
Guessmyname polycounter lvl 6
The game I'm working on is turn-based tactics but done in a 3D world; one result from this is that unit ranges are technically spheres rather circles. For the UI that displays attack ranges, I need a way to highlight 'everything within this sphere'.

So far I've been mucking around with a spherical mesh with fresnel and an inversion of the depth-blending for particles trick:


This gives a nice highlight of the volume bounds and intersection, but I'd really like to be able to highlight the inner area; the region of the map within the sphere (or to look at it another way; 'behind the front face rendering and in front of the back face rendering'). It's rather important that this be mesh based; virtually no unit will actually be able to aim in a perfect 360 sphere, and I can't assume only the one mesh either; ideally we could have multiple range displays on the screen.

Ideally, we'd be getting something like this:


I've been looking into stencil tests from poking through the docs (see the 'Hole' example at the bottom), but it's hit a snag; mostly it works... but only mostly; in certain camera positions the effect doesn't render, and I have a sneaking suspicion it will also fail if the camera happens to be inside the sphere, which is likely to happen during gameplay. I'm not wholly sure what causes it to fail; it seems to be by camera position rather than orientation.

I wouldn't call myself an expert on these kind of topics, but I'm sure something like this has been done before; does anyone have any advice / any potential avenues of approach?

Replies

  • Monkzoren
    Options
    Offline / Send Message
    Monkzoren polycounter lvl 8
    can you post your shader? You could in theory do a if check on the depth map to find the "Whitest" pixels, then apply o.Emission = Edge color 
  • Guessmyname
    Options
    Offline / Send Message
    Guessmyname polycounter lvl 6
    Current buggy volume shader is:
    Shader "Unlit/VolumeHighlight"
    {
        Properties
        {
            _MainTex ("Texture", 2D) = "white" {}
            _Color ("Colour", Color) = (1,1,1,1)
        }
        SubShader
        {
            Tags { "RenderType"="Opaque" "Queue"="Geometry+1"}

            CGINCLUDE
            struct appdata {
                float4 vertex : POSITION;
            };
            struct v2f {
                float4 pos : SV_POSITION;
            };
            v2f vert(appdata v) {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                return o;
            }
            half4 frag(v2f i) : SV_Target{
                return half4(1,1,0,1);
            }
            ENDCG

            Pass {
                ColorMask 0
                ZWrite off
                Stencil{
                    Ref 1
                    Comp always
                    Pass replace
                }
                Cull Front
                ZTest LEqual

                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag1
                half4 frag1(v2f i) : SV_Target{
                    return half4(1,1,0,1);
                }
                ENDCG
            }
            Pass {
                ColorMask 0
                ZWrite off
                Stencil{
                    Ref 1
                    Comp always
                    Pass replace
                }
                Cull Back
                ZTest GEqual

                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag2
                half4 frag2(v2f i) : SV_Target{
                    return half4(1,0,0,1);
                }
                ENDCG
            }
           
            Pass {
                ColorMask RGB
                ZTest Always
                Stencil{
                    Ref 1
                    Comp notequal
                }

                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                ENDCG
            }
        }
    }

    One alternative if I stick to spherical shapes is to outright define the arc of fire in the shader itself, find the world position of the pixel being rendered and check if it is within the volume or not, though that would potentially be a touch expensive and limit the potential shapes we could use.
Sign In or Register to comment.