Can't add vertex colors to this shader

Hey forum, I’m running into undiscovered territory here. Basically, this is just a simple flag waving shader with culling and cutoff added to it. Right now, I also want it to obtain vertex color from the mesh, but unfortunately for me, the structs have ‘:’ in them. Does anyone know how to still retain this current shader but have the frag and struct be in a way I can add float3 vertColors?

Shader "FlagShader"
{
    Properties
    {
        _Color("color", Color) = (1,1,1,1)
        _MainTex("Albedo (RGB)", 2D) = "white" {}
        _Speed("Speed", Range(0, 5.0)) = 1
        _Frequency("Frequency", Range(0, 1.3)) = 1
        _Amplitude("Amplitude", Range(0, 5.0)) = 1
        _CutOff("Cut off", float) = 0.1
        [Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull", Float) = 1
    }
    SubShader
    {
        Tags { "RenderType" = "Opaque" }
        Cull [_Cull]
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma alphatest:_Cutoff
            #include "UnityCG.cginc"
            sampler2D _MainTex;
            float4 _MainTex_ST;
            uniform float _CutOff;

            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
            };
            float _Speed;
            float _Frequency;
            float _Amplitude;
            float3 _Color;

            v2f vert(appdata_base v)
            {
                v2f o;
                v.vertex.y += cos((v.vertex.x + _Time.y * _Speed) * _Frequency) * _Amplitude * (v.vertex.x - 5);
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                return o;
            }
            float4 frag(v2f i) : SV_Target
            {
                float4 Result = tex2D(_MainTex,  i.uv);
                float3 col = _Color;
                Result.rgb = Result.rgb*col;
                if(Result.a < _CutOff) discard;
                return Result;
            }
            ENDCG
        }
    }
            FallBack "Specular"
}

Help is greatly appreciated! :smile:

Modified code:

Shader "FlagShader"
{
    Properties
    {
        _Color("color", Color) = (1,1,1,1)
        _MainTex("Albedo (RGB)", 2D) = "white" {}
        _Speed("Speed", Range(0, 5.0)) = 1
        _Frequency("Frequency", Range(0, 1.3)) = 1
        _Amplitude("Amplitude", Range(0, 5.0)) = 1
        _CutOff("Cut off", float) = 0.1
        [Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull", Float) = 1
    }
    SubShader
    {
        Tags { "RenderType" = "Opaque" }
        Cull [_Cull]
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            sampler2D _MainTex;
            float4 _MainTex_ST;
            uniform float _CutOff;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
                float3 color : COLOR;
            };
           
            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 color : COLOR;
            };
           
            float _Speed;
            float _Frequency;
            float _Amplitude;
            float3 _Color;
            v2f vert(appdata v)
            {
                v2f o;
                v.vertex.y += cos((v.vertex.x + _Time.y * _Speed) * _Frequency) * _Amplitude * (v.vertex.x - 5);
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                o.color = v.color;
                return o;
            }
           
            float4 frag(v2f i) : SV_Target
            {
                float4 Result = tex2D(_MainTex,  i.uv);
                float3 col = _Color;
                //Result.rgb = Result.rgb*col;
                Result.rgb = i.color.rgb;
                if(Result.a < _CutOff) discard;
                return Result;
            }
            ENDCG
        }
    }
    FallBack "Specular"
}

Script to test (set mesh vertex colors to blue):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FlagShader : MonoBehaviour
{
    void Start()
    {
        Mesh mesh = GetComponent<MeshFilter>().mesh;
        Vector3[] vertices = mesh.vertices;
        Color[] colors = new Color[vertices.Length];
        for (int i = 0; i < vertices.Length; i++)
            colors[i] = Color.blue;
        mesh.colors = colors;
    }
}

Expected result:

1 Like

Thank you so much! It works now. :smile:
I’m going to look into the changes to compare and learn from this.

The flagpole looked fine in Death Mountains. Unfortunately, a new problem started showing when I use fog in the Haunted Wastelands…


When I set the render queue to transparent, it looks correct but doesn’t have fog. And when I set it to opaque, it has that odd looking white geometry clipping inside it. Weird thing is, when I disable the fog, the white geometry is gone but still apparent. Anyone know what’s the cause of this?

Shader "FlagShader"
{
    Properties
    {
        _Color("Color", Color) = (1,1,1,1)
        _AmbientPow ("Ambient Power", Range(0,1)) = 0.5
        _MainTex("Albedo (RGB)", 2D) = "white" {}
        _Speed("Speed", Range(0, 5.0)) = 1
        _Frequency("Frequency", Range(0, 1.3)) = 1
        _Amplitude("Amplitude", Range(0, 5.0)) = 1
        _CutOff("Cut off", float) = 0.5
        [Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull", Float) = 1
    }
    SubShader
    {
        Cull [_Cull]
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            sampler2D _MainTex;
            float4 _MainTex_ST;
            uniform float _CutOff;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
                float4 color : COLOR;
            };
         
            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
                float4 color : COLOR;
            };
         
            float _Speed;
            float _Frequency;
            float _Amplitude;
            float4 _Color;
            half _AmbientPow;

            v2f vert(appdata v)
            {
                v2f o;
                v.vertex.y += cos((v.vertex.x + _Time.y * _Speed) * _Frequency) * _Amplitude * (v.vertex.x - 5);
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                o.color = v.color;
                return o;
            }
         
            float4 frag(v2f i) : SV_Target
            {
                float4 Result = tex2D(_MainTex,  i.uv);
                if(Result.a < _CutOff) discard;
                float4 col = _Color;
                Result.rgb = Result.rgb*col;
                Result.rgb *= i.color.rgba*2;
                Result.rgb*=(UNITY_LIGHTMODEL_AMBIENT)*_AmbientPow;  
                return Result;
            }
            ENDCG
        }
    }
    FallBack "Specular"
}

@Alvarezmd901 How is this fog issue related to vertex color? Might be a good idea to start a new thread.

You probably have to apply the fog color. See the default Unlit shader you can create from menus how to do that, basically you just add a few macros to your shader. But I didn’t have time to properly read your code, but saw that those lines are missing. So, I’m not sure if that’s the fix but there’s no fog data used.

1 Like