Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Need help with clip function in HLSL

Discussion in 'Universal Render Pipeline' started by Kalita2127, Jan 20, 2021.

  1. Kalita2127

    Kalita2127

    Joined:
    Dec 6, 2014
    Posts:
    279
    So I want to convert this custom built in shader to custom URP shader
    Code (CSharp):
    1. Shader "Custom/CoiledWire"
    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.         _NumSpirals("Spirals", Range(0,50)) = 20
    10.         _CableThickness("CableThickness", Range(0,50)) = 0.5
    11.     }
    12.     SubShader
    13.     {
    14.         Tags { "RenderType"="Opaque" }
    15.         LOD 200
    16.         Cull Off
    17.  
    18.         CGPROGRAM
    19.         // Physically based Standard lighting model, and enable shadows on all light types
    20.         #pragma surface surf Standard 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.         fixed4 _Color;
    35.         float _NumSpirals;
    36.         float _CableThickness;
    37.  
    38.         // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
    39.         // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
    40.         // #pragma instancing_options assumeuniformscaling
    41.         UNITY_INSTANCING_BUFFER_START(Props)
    42.             // put more per-instance properties here
    43.         UNITY_INSTANCING_BUFFER_END(Props)
    44.  
    45.         float3 lerp3(float3 a, float3 b, float3 c, float t)
    46.         {
    47.             if (t <= 0.5f)
    48.                 return lerp(a, b, t / 0.5);
    49.             else
    50.                 return lerp(b, c, (t - 0.5) / 0.5);
    51.         }
    52.  
    53.         void surf (Input IN, inout SurfaceOutputStandard o)
    54.         {
    55.             // ported from https://medium.com/xrlo-extended-reality-lowdown/how-to-create-a-coiled-cable-shader-in-ue4-8bb47777d8ab
    56.  
    57.             // build coilded uvs
    58.             float2 coiledUVs = IN.uv_MainTex;
    59.             coiledUVs.x = frac(coiledUVs.x + coiledUVs.y * _NumSpirals);
    60.      
    61.             // normalize cable:
    62.             float cable = saturate((coiledUVs.x / _CableThickness + 0.5) - (0.5 /_CableThickness));
    63.  
    64.             // buld normals:
    65.             o.Normal = normalize(lerp3(float3(0,-1,0), float3(0,0,1), float3(0,1,0),cable));
    66.  
    67.             // build height map:
    68.             float height = min(1 - cable, cable) * 2;
    69.  
    70.             // clip fragments outside the cable thickness:
    71.             clip (height-0.01);
    72.  
    73.             // flat albedo color (could sample a texture here if desired)
    74.             o.Albedo = _Color;
    75.  
    76.             // Metallic and smoothness come from slider variables
    77.             o.Metallic = _Metallic;
    78.             o.Smoothness = _Glossiness;
    79.             o.Alpha = 1;
    80.         }
    81.         ENDCG
    82.     }
    83.     FallBack "Diffuse"
    84. }
    85.  
    So far I've done this
    Code (CSharp):
    1. // This shader visuzlizes the normal vector values on the mesh.
    2. Shader "Custom/CoiledWireURP"
    3. {
    4.     Properties
    5.     {
    6.         _Color("Color", Color) = (1,1,1,1)
    7.         _MainTex("Albedo (RGB)", 2D) = "white" {}
    8.         _Glossiness("Smoothness", Range(0,1)) = 0.5
    9.         _Metallic("Metallic", Range(0,1)) = 0.0
    10.         _NumSpirals("Spirals", Range(0,50)) = 20
    11.         _CableThickness("CableThickness", Range(0,50)) = 0.5
    12.     }
    13.  
    14.         SubShader
    15.     {
    16.         Tags { "RenderType" = "Opaque" }
    17.  
    18.         LOD 200
    19.         Cull Off
    20.  
    21.         Pass
    22.         {
    23.             HLSLPROGRAM
    24.             #pragma vertex vert        
    25.             #pragma fragment frag
    26.             #pragma target 3.0
    27.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    28.  
    29.             CBUFFER_START(UnityPerMaterial)
    30.                 float _NumSpirals;
    31.                 float _CableThickness;
    32.                 half4 _Color;
    33.             CBUFFER_END
    34.  
    35.             float2 coiledUVs;// = IN.attributes;
    36.  
    37.             struct Attributes
    38.             {
    39.                 float4 positionOS   : POSITION;
    40.                 // Declaring the variable containing the normal vector for each
    41.                 // vertex.
    42.                 half3 normal        : NORMAL;
    43.                 float2 attributes   : TEXCOORD0;
    44.             };
    45.  
    46.             struct Varyings
    47.             {
    48.                 float4 positionHCS  : SV_POSITION;
    49.                 half3 normal        : TEXCOORD0;
    50.             };
    51.  
    52.             float3 lerp3(float3 a, float3 b, float3 c, float t)
    53.             {
    54.                 if (t <= 0.5f)
    55.                     return lerp(a, b, t / 0.5);
    56.                 else
    57.                     return lerp(b, c, (t - 0.5) / 0.5);
    58.             }
    59.  
    60.             Varyings vert(Attributes IN)
    61.             {
    62.                 Varyings OUT;
    63.                 OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
    64.                 // Use the TransformObjectToWorldNormal function to transform the
    65.                 // normals from object to world space. This function is from the
    66.                 // SpaceTransforms.hlsl file, which is referenced in Core.hlsl.
    67.                 coiledUVs = IN.attributes;
    68.                 coiledUVs.x = frac(coiledUVs.x + coiledUVs.y * _NumSpirals);
    69.        
    70.                 // // normalize cable:
    71.                 float cable = saturate((coiledUVs.x / _CableThickness + 0.5) - (0.5 /_CableThickness));
    72.  
    73.                 OUT.normal = normalize(lerp3(float3(0,-1,0), float3(0,0,1), float3(0,1,0),cable));
    74.            
    75.                 // float height = min(1 - cable, cable) * 2;
    76.  
    77.                 // clip fragments outside the cable thickness:
    78.                 // clip (height-0.01);
    79.            
    80.                 return OUT;
    81.             }
    82.  
    83.             half4 frag(Varyings IN) : SV_Target
    84.             {
    85.                 // half4 color = 0;
    86.                 // // IN.normal is a 3D vector. Each vector component has the range
    87.                 // // -1..1. To show all vector elements as color, including the
    88.                 // // negative values, compress each value into the range 0..1.
    89.                 // color.rgb = IN.normal * 0.5 + 0.5;
    90.                 // return color;
    91.                 half4 output = 0;
    92.  
    93.                 coiledUVs = IN.normal;
    94.                 coiledUVs.x = frac(coiledUVs.x + coiledUVs.y * _NumSpirals);
    95.        
    96.                 // // normalize cable:
    97.                 // float cable = saturate((coiledUVs.x / _CableThickness + 0.5) - (0.5 /_CableThickness));
    98.  
    99.                 // // buld normals:
    100.                 // o.Normal = normalize(lerp3(float3(0,-1,0), float3(0,0,1), float3(0,1,0),cable));
    101.  
    102.                 // // build height map:
    103.                 // float height = min(1 - cable, cable) * 2;
    104.                 output.rgb = float3(coiledUVs.x, coiledUVs.y, 0);
    105.  
    106.                 return output;
    107.             }
    108.  
    109.             //  half4 frag() : SV_Target
    110.             // {          
    111.             //     return _Color;
    112.             // }
    113.             ENDHLSL
    114.         }
    115.     }
    116. }
    I'm new to shader programming but I think I noticed that I need some clip function to work to achieve it. But it looks like I can't use clip function in HLSL. What's the equivalent function to this?
    Any help will be appreciated. Thanks!
     
    Last edited: Jan 20, 2021
  2. lilacsky824

    lilacsky824

    Joined:
    May 19, 2018
    Posts:
    171
    You should use clip inside fragment stage.
     
  3. Kalita2127

    Kalita2127

    Joined:
    Dec 6, 2014
    Posts:
    279
    It will cause error. I've tried it
     
  4. lilacsky824

    lilacsky824

    Joined:
    May 19, 2018
    Posts:
    171
    You only need past normal and position data from vertex to fragment stage.
    For calculation of coiledUV should done inside fragment stage, then use clip.
    I just modified you shader.Maybe you can take a look?
    Code (CSharp):
    1. // This shader visuzlizes the normal vector values on the mesh.
    2. Shader "Custom/CoiledWireURP"
    3. {
    4.     Properties
    5.     {
    6.         _Color("Color", Color) = (1,1,1,1)
    7.         _MainTex("Albedo (RGB)", 2D) = "white" {}
    8.         _Glossiness("Smoothness", Range(0,1)) = 0.5
    9.         _Metallic("Metallic", Range(0,1)) = 0.0
    10.         _NumSpirals("Spirals", Range(0,50)) = 20
    11.         _CableThickness("CableThickness", Range(0,50)) = 0.5
    12.     }
    13.    
    14.     SubShader
    15.     {
    16.         Tags { "RenderType" = "Opaque" }
    17.        
    18.         LOD 200
    19.         Cull Off
    20.        
    21.         Pass
    22.         {
    23.             HLSLPROGRAM
    24.             #pragma vertex vert      
    25.             #pragma fragment frag
    26.             #pragma target 3.0
    27.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    28.            
    29.             CBUFFER_START(UnityPerMaterial)
    30.             float _NumSpirals;
    31.             float _CableThickness;
    32.             half4 _Color;
    33.             CBUFFER_END
    34.  
    35.             sampler2D _MainTex;
    36.            
    37.             struct Attributes
    38.             {
    39.                 float4 positionOS   : POSITION;
    40.                 // Declaring the variable containing the normal vector for each
    41.                 // vertex.
    42.                 half3 normal        : NORMAL;
    43.             };
    44.            
    45.             struct Varyings
    46.             {
    47.                 float4 positionHCS  : SV_POSITION;
    48.                 half3 normal        : TEXCOORD0;
    49.             };
    50.            
    51.             float3 lerp3(float3 a, float3 b, float3 c, float t)
    52.             {
    53.                 if (t <= 0.5f)
    54.                 return lerp(a, b, t / 0.5);
    55.                 else
    56.                 return lerp(b, c, (t - 0.5) / 0.5);
    57.             }
    58.            
    59.             Varyings vert(Attributes IN)
    60.             {
    61.                 Varyings OUT;
    62.                 OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
    63.                 // Use the TransformObjectToWorldNormal function to transform the
    64.                 // normals from object to world space. This function is from the
    65.                 // SpaceTransforms.hlsl file, which is referenced in Core.hlsl.
    66.                 OUT.normal = TransformObjectToWorldNormal(IN.normal);
    67.                 return OUT;
    68.             }
    69.            
    70.             half4 frag(Varyings IN) : SV_Target
    71.             {
    72.                 // half4 color = 0;
    73.                 // // IN.normal is a 3D vector. Each vector component has the range
    74.                 // // -1..1. To show all vector elements as color, including the
    75.                 // // negative values, compress each value into the range 0..1.
    76.                 // color.rgb = IN.normal * 0.5 + 0.5;
    77.                 // return color;
    78.                 half4 output = 0;
    79.                
    80.                 float2 coiledUVs = IN.normal;
    81.                 coiledUVs.x = frac(coiledUVs.x + coiledUVs.y * _NumSpirals);
    82.                
    83.                 //normalize cable:
    84.                 float cable = saturate((coiledUVs.x / _CableThickness + 0.5) - (0.5 /_CableThickness));
    85.                
    86.                 //buld normals:
    87.                 IN.normal = normalize(lerp3(float3(0,-1,0), float3(0,0,1), float3(0,1,0),cable));
    88.                
    89.                 //build height map:
    90.                 float height = min(1 - cable, cable) * 2;
    91.  
    92.                 // build height map:
    93.                 clip (height - 0.01f);
    94.  
    95.                 output.rgb = float3(coiledUVs.x, coiledUVs.y, 0);
    96.                
    97.                 return output;
    98.             }
    99.             ENDHLSL
    100.         }
    101.     }
    102. }
    未命名-1.png
     
  5. Kalita2127

    Kalita2127

    Joined:
    Dec 6, 2014
    Posts:
    279
    Hey sorry for the late reply.Yes I've checked it and it looks like it. Now the problem is how do we get the spiral like the one in my first shader script? Anyway thanks for taking your time to help me.
    Maybe this will help you a bit
     
  6. lilacsky824

    lilacsky824

    Joined:
    May 19, 2018
    Posts:
    171
    Calculate spiral uv from original uv instead of normal.
    So you need pass uv coordinate form vertex to fragment stage.
    Then calculate spiral uv like this.
    Actually is what you did from first post.:)
    Code (CSharp):
    1.  
    2. float2 coiledUVs = IN.uv;
    3. //Number of spirals should be integer so spiral will be seamless.
    4. coiledUVs = frac(coiledUVs.y * floor(_NumSpirals) + coiledUVs.x);
    5.  
    Entire code here.
    Code (CSharp):
    1. // This shader visuzlizes the normal vector values on the mesh.
    2. Shader "Custom/CoiledWireURP"
    3. {
    4.     Properties
    5.     {
    6.         _Color("Color", Color) = (1,1,1,1)
    7.         _MainTex("Albedo (RGB)", 2D) = "white" {}
    8.         _Glossiness("Smoothness", Range(0,1)) = 0.5
    9.         _Metallic("Metallic", Range(0,1)) = 0.0
    10.         _NumSpirals("Spirals", Range(0,50)) = 20
    11.         _CableThickness("CableThickness", Range(0,50)) = 0.5
    12.     }
    13.    
    14.     SubShader
    15.     {
    16.         Tags { "RenderType" = "Opaque" }
    17.        
    18.         LOD 200
    19.         Cull Off
    20.        
    21.         Pass
    22.         {
    23.             HLSLPROGRAM
    24.             #pragma vertex vert    
    25.             #pragma fragment frag
    26.             #pragma target 3.0
    27.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    28.            
    29.             CBUFFER_START(UnityPerMaterial)
    30.             float _NumSpirals;
    31.             float _CableThickness;
    32.             half4 _Color;
    33.             CBUFFER_END
    34.            
    35.             sampler2D _MainTex;
    36.            
    37.             struct Attributes
    38.             {
    39.                 float4 positionOS   : POSITION;
    40.                 // Declaring the variable containing the normal vector for each
    41.                 // vertex.
    42.                 half3 uv        : TEXCOORD0;
    43.                 half3 normal        : NORMAL;
    44.             };
    45.            
    46.             struct Varyings
    47.             {
    48.                 float4 positionHCS  : SV_POSITION;
    49.                 float2 uv        : TEXCOORD0;
    50.                 half3 normal        : TEXCOORD1;
    51.             };
    52.            
    53.             Varyings vert(Attributes IN)
    54.             {
    55.                 Varyings OUT;
    56.                 OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
    57.                 // Use the TransformObjectToWorldNormal function to transform the
    58.                 // normals from object to world space. This function is from the
    59.                 // SpaceTransforms.hlsl file, which is referenced in Core.hlsl.
    60.                 OUT.uv = IN.uv;
    61.                 OUT.normal = TransformObjectToWorldNormal(IN.normal);
    62.                 return OUT;
    63.             }
    64.            
    65.             half4 frag(Varyings IN) : SV_Target
    66.             {
    67.                 // half4 color = 0;
    68.                 // // IN.normal is a 3D vector. Each vector component has the range
    69.                 // // -1..1. To show all vector elements as color, including the
    70.                 // // negative values, compress each value into the range 0..1.
    71.                 // color.rgb = IN.normal * 0.5 + 0.5;
    72.                 // return color;
    73.                 half4 output = 0;
    74.                
    75.                 float2 coiledUVs = IN.uv;
    76.                 coiledUVs = frac(coiledUVs.y * floor(_NumSpirals) + coiledUVs.x);
    77.  
    78.                 output.rgb = float3(coiledUVs, 0);
    79.                
    80.                 return output;
    81.             }
    82.             ENDHLSL
    83.         }
    84.     }
    85. }
    86.