How to import vertex colour animation?

I have animated vertex colours using Blender which give the effect of dimming lights. How can I import this animation into Unity?

As an alternative approach, is it possible to create an iOS friendly shader that would achieve the following:

  • Red channel of vertex colour is used for one set of lighting
  • Blue channel of vertex colour is used for second set of lighting
  • Shader has 2 properties (lightAmount1 and lightAmount2) floating point 0 to 1
  • Calculate emission colour (RGB) from:

    min(1.0, lightAmount1 * vertexcolor.red + lightAmount2 * vertexcolor.blue)

If this is possible, then I could animate those two properties.

Many thanks to Jessy for helping with this question.

Vertex colours can be animated using a shader by introducing two properties. One for each simulated light source. The red colour component of a vertex colour can be used to illuminate one light source whilst the blue for another. It is easily possible to have 4 simulated light sources (R, G, B, A).

I have called these properties Emission A and Emission B and a value of 0 indicates that the vertex colour component should not contribute to lighting whereas 1 indicates full contribution.

These properties can be easily animated using the animation editor in Unity. Alternatively it is also possible to script the animation if need be.

I want to use these values to simulate two light sources smoothly dimming, but I suspect that there are many other applications of this technique.

I am aiming for iOS platforms and so have created two alternative implementations to compare performance. I do not at this time know which of the two variants performs more efficiently.

EDIT: The first approach seems to perform more efficiently than the second. The first approach does not include vertex lighting. I will add that to the answer if I can figure it out.

Cg Vertex and Fragment shader as follows:

Shader "Custom/Animated Vertex Emission" {
Properties {
	_MainTex ("Texture", 2D) = "white" {}
	_EmissionA ("Emission A", Range(0, 1)) = 1
	_EmissionB ("Emission B", Range(0, 1)) = 0
}

	Pass {
	CGPROGRAM
		#pragma vertex vert
		
		#pragma fragment frag
		#pragma fragmentoption ARB_fog_exp2
		#pragma fragmentoption ARB_precision_hint_fastest
		
		#include "UnityCG.cginc"
		
		struct appdata {
			float4 vertex	: POSITION;
			float4 texcoord	: TEXCOORD0;
			float4 color	: COLOR;
		};
		
		struct v2f {
			float4 pos		: SV_POSITION;
			float2 uv		: TEXCOORD0;
			fixed4 color	: COLOR;
		};
		
		sampler2D _MainTex;
		float _EmissionA;
		float _EmissionB;
		
		float4 _MainTex_ST;
		
		v2f vert(appdata v) {
			v2f o;
			o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
			
			float c = min(1, _EmissionA * v.color.r + _EmissionB * v.color.b);
			o.color = float4(c, c, c, 1);
			o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
			
			return o;
		}
		
		half4 frag(v2f i) : COLOR {
			half4 outColor = tex2D(_MainTex, i.uv);
			return outColor * i.color;
		}
	ENDCG
	}

}

Fallback "Custom/Unlit"

}

Unity Surface Shader:

Shader "Custom/Animated Vertex Emission" {
Properties {
	_MainTex ("Texture", 2D) = "white" {}
	_EmissionA ("Emission A", Range(0, 1)) = 1
	_EmissionB ("Emission B", Range(0, 1)) = 0
}

SubShader {
	Tags { "RenderType"="Opaque" }

	CGPROGRAM
		#pragma surface surf Lambert

		struct Input {
			float2 uv_MainTex;
			float3 color		: COLOR;
		};

		sampler2D _MainTex;

		float _EmissionA;
		float _EmissionB;

		void surf(Input IN, inout SurfaceOutput o) {
			float3 temp = tex2D(_MainTex, IN.uv_MainTex).rgb;

			float c = min(1, _EmissionA * IN.color.r + _EmissionB * IN.color.b);
			o.Albedo = half3(c * temp.r, c * temp.g, c * temp.b);
		}
	ENDCG
}

Fallback "Custom/Unlit"

}