Search Unity

Resolved Make a cone sag on a sphere

Discussion in 'Shaders' started by ookk47oo, Feb 25, 2022.

  1. ookk47oo

    ookk47oo

    Joined:
    Mar 17, 2017
    Posts:
    80
    Hi all, I want to dig a cone on a sphere and write the surface shader below.
    Code (CSharp):
    1. Shader "Custom/ConeSag"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (1,1,1,1)
    6.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    7.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    8.         _Metallic ("Metallic", Range(0,1)) = 0.0
    9.         _Direction("Direction", vector) = (0,0,0,0)
    10.         _SagRange("SagRange", Range(0, 90)) = 0
    11.         _SagDistance ("SagDistance", Range(0, 1)) = 0.0
    12.     }
    13.     SubShader
    14.     {
    15.         Tags { "RenderType"="Opaque" }
    16.         LOD 200
    17.  
    18.         CGPROGRAM
    19.         // Physically based Standard lighting model, and enable shadows on all light types
    20.         #pragma surface surf Standard vertex:vert  fullforwardshadows
    21.  
    22.         // Use shader model 3.0 target, to get nicer looking lighting
    23.         #pragma target 3.0
    24.  
    25.         sampler2D _MainTex;
    26.  
    27.         struct Input
    28.         {
    29.             float2 uv_MainTex;
    30.         };
    31.  
    32.         half _Glossiness;
    33.         half _Metallic;
    34.         half _SagDistance;
    35.         half _SagRange;
    36.         float4 _Direction;
    37.         fixed4 _Color;
    38.  
    39.         // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
    40.         // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
    41.         // #pragma instancing_options assumeuniformscaling
    42.         UNITY_INSTANCING_BUFFER_START(Props)
    43.             // put more per-instance properties here
    44.         UNITY_INSTANCING_BUFFER_END(Props)
    45.  
    46.         void surf (Input IN, inout SurfaceOutputStandard o)
    47.         {
    48.             // Albedo comes from a texture tinted by color
    49.             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    50.             o.Albedo = c.rgb;
    51.             // Metallic and smoothness come from slider variables
    52.             o.Metallic = _Metallic;
    53.             o.Smoothness = _Glossiness;
    54.             o.Alpha = c.a;
    55.         }
    56.  
    57.         void vert (inout appdata_full v)
    58.         {
    59.             float sagRange = radians(_SagRange);
    60.             if(sagRange > 0)
    61.             {
    62.                 float3 dir = normalize(_Direction.xyz);
    63.                 float3 normal = normalize(v.vertex.xyz);
    64.                 float angle = acos(dot(dir, normal) / (length(dir) * length(normal)));
    65.                 if(angle <= sagRange)
    66.                 {
    67.                     v.vertex = float4(v.vertex.xyz - normal * _SagDistance, v.vertex.z);
    68.                 }
    69.             }
    70.         }
    71.  
    72.         ENDCG
    73.     }
    74.     FallBack "Diffuse"
    75. }
    76.  
    But when i apply it to the sphere, I find that the edge of cone is irregular.
    I expect it will behave like the black curve .
    sc.png
    Is there anything I got wrong?
     
  2. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,448
    is that unity default sphere? it is quite low poly for that.
    (could add tesselation in shader or use higher resolution mesh)

    tested something similar while ago,
    no tesselation
    upload_2022-2-25_12-34-51.png

    high tesselation
    upload_2022-2-25_12-35-4.png
     
  3. ookk47oo

    ookk47oo

    Joined:
    Mar 17, 2017
    Posts:
    80
    Yep, I used the default sphere.
    The sphere with high tesselation looks awesome. I will try it.
    Many thanks!
     
  4. ookk47oo

    ookk47oo

    Joined:
    Mar 17, 2017
    Posts:
    80
    got it.
    sc.png
    _Tess is about 30 for the best looking.:)
    Here is the new code.
    Code (CSharp):
    1. Shader "Custom/ConeSag"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (1,1,1,1)
    6.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    7.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    8.         _Metallic ("Metallic", Range(0,1)) = 0.0
    9.         _Direction("Direction", vector) = (0,0,0,0)
    10.         _SagRange("SagRange", Range(0, 90)) = 0
    11.         _SagDistance ("SagDistance", Range(0, 1)) = 0.0
    12.         _Tess ("Tessellation", Range(1,32)) = 4
    13.     }
    14.     SubShader
    15.     {
    16.         Tags { "RenderType"="Opaque" }
    17.         LOD 200
    18.  
    19.         CGPROGRAM
    20.         // Physically based Standard lighting model, and enable shadows on all light types
    21.         #pragma surface surf Standard vertex:vert tessellate:tess  fullforwardshadows
    22.  
    23.         // Use shader model 3.0 target, to get nicer looking lighting
    24.         #pragma target 3.0
    25.         #include "Tessellation.cginc"
    26.  
    27.         sampler2D _MainTex;
    28.  
    29.         struct Input
    30.         {
    31.             float2 uv_MainTex;
    32.         };
    33.  
    34.         float _Tess;
    35.  
    36.  
    37.         half _Glossiness;
    38.         half _Metallic;
    39.         half _SagDistance;
    40.         half _SagRange;
    41.         float4 _Direction;
    42.         fixed4 _Color;
    43.  
    44.         // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
    45.         // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
    46.         // #pragma instancing_options assumeuniformscaling
    47.         UNITY_INSTANCING_BUFFER_START(Props)
    48.             // put more per-instance properties here
    49.         UNITY_INSTANCING_BUFFER_END(Props)
    50.  
    51.         float4 tess ()
    52.         {
    53.             return _Tess;
    54.         }
    55.  
    56.  
    57.         void surf (Input IN, inout SurfaceOutputStandard o)
    58.         {
    59.             // Albedo comes from a texture tinted by color
    60.             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    61.             o.Albedo = c.rgb;
    62.             // Metallic and smoothness come from slider variables
    63.             o.Metallic = _Metallic;
    64.             o.Smoothness = _Glossiness;
    65.             o.Alpha = c.a;
    66.         }
    67.  
    68.         void vert (inout appdata_full v)
    69.         {
    70.             float sagRange = radians(_SagRange);
    71.             if(sagRange > 0)
    72.             {
    73.                 float3 dir = normalize(_Direction.xyz);
    74.                 float3 normal = normalize(v.vertex.xyz);
    75.                 float angle = acos(dot(dir, normal) / (length(dir) * length(normal)));
    76.                 if(angle <= sagRange)
    77.                 {
    78.                     v.vertex = float4(v.vertex.xyz - v.normal * _SagDistance, v.vertex.z);
    79.                 }
    80.             }
    81.         }
    82.  
    83.         ENDCG
    84.     }
    85.     FallBack "Diffuse"
    86. }
    87.