Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Trying to cut transparency into a semi-transparent surface, but it has to be opaque?

Discussion in 'Shaders' started by BenjaminApprill, Jul 16, 2023.

  1. BenjaminApprill

    BenjaminApprill

    Joined:
    Aug 1, 2022
    Posts:
    106
    Hey what's up. I 've got an HLSL shader that cuts a circle around a point, by setting the pixel alphas to 0.

    I am running into an issue however, where changing the alpha of the surface removes the cutouts. If I lower the alpha to anything but 1, the cutouts disappear, and the surface becomes uniformly transparent. I suspect this has to do with the settings I'm using in my Shader Pass.

    Is there a specific configuration in HLSL that allows for affecting the transparency of an already transparent fragment? I've not found a good answer for this online.
     
  2. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    4,362
    Maybe the alpha clip value is really high?
    Maybe share the shader code
     
  3. BenjaminApprill

    BenjaminApprill

    Joined:
    Aug 1, 2022
    Posts:
    106
    Here's the shader code. I'm really roughing it out right now in HLSL, so I am sure there are improvements to be made. I am not familiar with the alpha clipping you mentioned, I likely haven't configured that properly in the shader.

    Code (CSharp):
    1. Shader "Unlit/UnlitFOW"
    2. {
    3.     Properties
    4.     {
    5.         _MainColor ("Color", Color) = (0,0,0,1)
    6.         _MainTex ("Texture", 2D) = "white" {}
    7.     }
    8.     SubShader
    9.     {
    10.         Tags { "RenderType"="Transparent" "Queue" = "Transparent" }
    11.         LOD 100
    12.  
    13.         Pass
    14.         {
    15.             Blend SrcAlpha OneMinusSrcAlpha
    16.             ZWrite Off
    17.  
    18.             HLSLPROGRAM
    19.             #pragma vertex vert
    20.             #pragma fragment frag
    21.  
    22.             #include "UnityCG.cginc"
    23.  
    24.             struct appdata
    25.             {
    26.                 float4 vertex : POSITION;
    27.                 float2 uv : TEXCOORD0;
    28.             };
    29.  
    30.             struct v2f
    31.             {
    32.                 float4 vertex : SV_POSITION;
    33.                 float2 uv : TEXCOORD0;              
    34.             };
    35.  
    36.             struct VisionData
    37.             {
    38.                 float2 uv;
    39.                 float radius;
    40.             };
    41.  
    42.             float4 _MainColor;
    43.             sampler2D _MainTex;
    44.             float4 _MainTex_ST;
    45.             uint _VisionCount;
    46.  
    47.             StructuredBuffer<VisionData> _VisionData;
    48.  
    49.             v2f vert (appdata v)
    50.             {
    51.                 v2f o;
    52.                 o.vertex = UnityObjectToClipPos(v.vertex);
    53.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    54.                 return o;
    55.             }
    56.  
    57.             half4 frag (v2f i) : SV_Target
    58.             {
    59.                 float dist = 0;
    60.                 half4 col = _MainColor;
    61.                
    62.                 for(int j = 0; j < _VisionCount; j++)
    63.                 {
    64.                     if(col.w == 1)
    65.                     {
    66.                         dist = length(i.uv + _VisionData[j].uv) - _VisionData[j].radius;
    67.                         col = dist > 0 ? _MainColor : half4(0,0,0,0);
    68.                     }
    69.                 }
    70.                 return col;
    71.             }
    72.             ENDHLSL
    73.         }
    74.     }
    75. }
     
  4. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    4,362
    Code (CSharp):
    1. for(int j = 0; j < _VisionCount; j++)
    2.                 {
    3.                     if(col.w == 1)
    4.                     {
    5.                         dist = length(i.uv + _VisionData[j].uv) - _VisionData[j].radius;
    6.                         col = dist > 0 ? _MainColor : half4(0,0,0,0);
    7.                     }
    8.                 }
    9.                 return col;

    Here you check if the alpha is 1, where you do a distance check and return a blank pixel or the main color
     
  5. BenjaminApprill

    BenjaminApprill

    Joined:
    Aug 1, 2022
    Posts:
    106
    I see what you mean now... I forgot to variabalize the check for a variable transparency on the main color... That will probably be the culprit. Good catch!
     
  6. BenjaminApprill

    BenjaminApprill

    Joined:
    Aug 1, 2022
    Posts:
    106
    In my shader loop, I had:

    Code (CSharp):
    1. for(int j = 0; j < _VisionCount; j++)
    2.                 {
    3.                     if(col.w == 1)
    4.                     {
    5.                         dist = length(i.uv + _VisionData[j].uv) - _VisionData[j].radius;
    6.                         col = dist > 0 ? _MainColor : half4(0,0,0,0);
    7.                     }
    8.                 }
    But it actually needed to be:

    Code (CSharp):
    1. for(int j = 0; j < _VisionCount; j++)
    2.                 {
    3.                     if(col.w == _MainColor.w)
    4.                     {
    5.                         dist = length(i.uv + _VisionData[j].uv) - _VisionData[j].radius;
    6.                         col = dist > 0 ? _MainColor : half4(0,0,0,0);
    7.                     }
    8.                 }
    Thanks to DevDunk for pointing this out above.
     
    DevDunk likes this.