Search code examples
unity-game-enginetexturesshader

How to transparent Unity3D custom shader?


I have a custom shader which can render texture inside an object (such as : Sphere). But I can't make it transparent because Unity says there is no _Color property added in that shader.

I am not an expert in Unity Shader, so need some help how to make my existing shader. Here is my shader code.

Shader "InsideVisible" 
{
    Properties 
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }

    SubShader 
    {
        Tags { "RenderType"="Opaque" }
        Cull front
        LOD 100

        Pass 
        {  
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata_t {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f {
                float4 vertex : SV_POSITION;
                half2 texcoord : TEXCOORD0;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata_t v)
            {
                v2f o;

                o.vertex     = mul(UNITY_MATRIX_MVP, v.vertex);
                v.texcoord.x = 1 - v.texcoord.x;                
                o.texcoord   = TRANSFORM_TEX(v.texcoord, _MainTex);

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.texcoord);
                return col;
            }

            ENDCG
        }
    }
}

Solution

  • Your script is probably trying to access a property named _Color to set its alpha value, but there is no _Color property on this shader, so the script fails.

    Also the shader is not set up to render transparency, so we'll need to fix that.

    Shader properties are kind of like the public properties you expose on C# classes: the outside world can manipulate them to change the way the shader renders.

    In the fragment, we multiply the image color by the _Color property so that it can control tint and alpha.

    To make your shader render transparency, you also need to add a few lines to the SubShader and the pragma.

    Shader "InsideVisible" 
    {
        Properties 
        {
            _MainTex ("Base (RGB)", 2D) = "white" {}
            _Color ("Color (RGBA)", Color) = (1, 1, 1, 1) // add _Color property
        }
    
        SubShader 
        {
            Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
            Cull front 
            LOD 100
    
            Pass 
            {
                CGPROGRAM
    
                #pragma vertex vert alpha
                #pragma fragment frag alpha
    
                #include "UnityCG.cginc"
    
                struct appdata_t 
                {
                    float4 vertex   : POSITION;
                    float2 texcoord : TEXCOORD0;
                };
    
                struct v2f 
                {
                    float4 vertex  : SV_POSITION;
                    half2 texcoord : TEXCOORD0;
                };
    
                sampler2D _MainTex;
                float4 _MainTex_ST;
                float4 _Color;
    
                v2f vert (appdata_t v)
                {
                    v2f o;
    
                    o.vertex     = mul(UNITY_MATRIX_MVP, v.vertex);
                    v.texcoord.x = 1 - v.texcoord.x;
                    o.texcoord   = TRANSFORM_TEX(v.texcoord, _MainTex);
    
                    return o;
                }
    
                fixed4 frag (v2f i) : SV_Target
                {
                    fixed4 col = tex2D(_MainTex, i.texcoord) * _Color; // multiply by _Color
                    return col;
                }
    
                ENDCG
            }
        }
    }