unity-game-engineglslshadershaderlab

Clip the region in Ellipse shape using ShaderLab in Unity


I am trying to draw an Ellipsoid using shaders in Unity

Following the steps
1. I have written a custom shader with the help of some internet tutorial
2. Added the shader on the material
3. Applied that material on the object

Shader "Custom/HoleMaker" {
    Properties{
            _Position("Position", Vector) = (0,0,0,0)
            _Radius("Radius", Range(0,1)) = 0.01
            _Color("Color", Color) = (1,1,1,1)
            _CutawayColor("Cutaway Color", Color) = (1,1,1,1)
    }
            SubShader{
                    Tags { "RenderType" = "Opaque"}
                    LOD 200
                    Cull Front

                    CGPROGRAMtypes
                    #pragma surface surf MonoColor fullforwardshadows vertex:vert

                    // Use shader model 3.0 target, to get nicer looking lighting
                    #pragma target 3.0

                    fixed4 _CutawayColor;

                    float4 _Position;
                    float _Radius;

                    struct Input
                    {
                            float2 uv_MainTex;
                            float3 worldPos;
                    };

                    void vert(inout appdata_full v, out Input o)
                    {
                            UNITY_INITIALIZE_OUTPUT(Input, o);
                            v.normal *= -1;
                    }

                    half4 LightingMonoColor(SurfaceOutput s, half3 lightDir, half atten) {
                            return _CutawayColor;
                    }

                    void surf(Input IN, inout SurfaceOutput o)
                    {

                            //spherical clipping
                            float dist = distance(IN.worldPos.xyz, _Position.xyz);
                            if (dist < _Radius)
                                    clip(-1);


                            o.Albedo = _CutawayColor.rgb;
                    }
                    ENDCG
            }
                    FallBack "Diffuse"
   }

This code is working for making a circle but when I try to use the function clip() to make an Ellipsoid, it is not working. According to the documentation, clip(float4 x) is also available to be used to clip the surface. The variable _Radius makes a perfect sphere in World Space but when I try to use _Radius.x and _Radius.y, the code does not work. Please refer to the image attached herewith.

enter image description here


Solution

  • _Radius.x and _Radius.y break the shader because _Radius is a float. It doesn't have x or y members. How could it possibly have a value for _Radius.y?

    Instead, consider adding a Scale property, then scaling the difference between world position and _Position by that amount, before comparing the magnitude of the difference to _radius:

    Shader "Custom/HoleMaker" {
        Properties{
                _Position("Position", Vector) = (0,0,0,0)
                _Scale("Scale", Vector) = (1,1,1,0)
                _Radius("Radius", Range(0,1)) = 0.01
                _Color("Color", Color) = (1,1,1,1)
                _CutawayColor("Cutaway Color", Color) = (1,1,1,1)
        }
                SubShader{
                        Tags { "RenderType" = "Opaque"}
                        LOD 200
                        Cull Front
    
                        CGPROGRAMtypes
                        #pragma surface surf MonoColor fullforwardshadows vertex:vert
    
                        // Use shader model 3.0 target, to get nicer looking lighting
                        #pragma target 3.0
    
                        fixed4 _CutawayColor;
    
                        float4 _Position;
                        float4 _Scale;
                        float _Radius;
    
                        struct Input
                        {
                                float2 uv_MainTex;
                                float3 worldPos;
                        };
    
                        void vert(inout appdata_full v, out Input o)
                        {
                                UNITY_INITIALIZE_OUTPUT(Input, o);
                                v.normal *= -1;
                        }
    
                        half4 LightingMonoColor(SurfaceOutput s, half3 lightDir, half atten) {
                                return _CutawayColor;
                        }
    
                        void surf(Input IN, inout SurfaceOutput o)
                        {
    
                                //spherical clipping
                                float dist = length(_Scale.xyz * IN.worldPos.xyz - _Position.xyz);
                                if (dist < _Radius)
                                        clip(-1);
    
    
                                o.Albedo = _CutawayColor.rgb;
                        }
                        ENDCG
                }
                        FallBack "Diffuse"
       }