Unity Shader 使用枚举切换整体色调
发表于2019-01-16
本篇给大家分享下Shader使用枚举切换整体色调的实现。

效果图:

知识点:
- 两种方式在shader中使用枚举
- 脚本修改shader中的变量
- 两种方式遍历枚举对象
- 使用协程执行定时逻辑
代码
一、颜色变化的枚举类型,其值是byte类型的
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum ColorType : byte{
First = 1,
Second = 2,
Third = 3,
Fourth = 4,
Fifth = 5,
Sixth = 6,
}
二、循环遍历控制逻辑
- 这里将切换逻辑写在协程里,而不是Update中,这样有利于程序的模块化
- 有两种方式实现遍历,一种是通过数组和索引,另一种则是迭代器
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class AutoChangeColor : MonoBehaviour {
/// <summary>
/// 改变颜色的时间间隔
/// </summary>
public int changeInterval = 1;
public Material mat;
// Use this for initialization
void Start() {
StartCoroutine(ChangeColor2());
}
// Update is called once per frame
void Update() {
}
private IEnumerator ChangeColor1()
{
Byte[] colorTypes = (Byte[])Enum.GetValues(typeof(ColorType));
byte index = 0;
while (true)
{
mat.SetInt("_ColorType", colorTypes[index]);
yield return new WaitForSeconds(changeInterval);
index++;
if(index == colorTypes.Length)
{
index = 0;
}
}
}
private IEnumerator ChangeColor2()
{
Array colorTypeArray = Enum.GetValues(typeof(ColorType));
IEnumerator it = colorTypeArray.GetEnumerator();
while(true) {
if (it.MoveNext()) {
print("name = " + it.Current + ", value = " + (byte)it.Current);
mat.SetInt("_ColorType", (byte)it.Current);
yield return new WaitForSeconds(changeInterval);
} else
{
it.Reset();
}
}
}
}
三、UnlitShader 无光着色器
在shader中有两种方式可以定义枚举类型:
- 键值对的数组形式
- 引用C#中定义的包名加类型的方式

Shader "Custom/UnlitColorChangeShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
[Enum(First,1,Second,2,Third,3,Fourth,4,Fifth,5,Sixth,6)] _ColorType ("Color Type", Int) = 1
//[Enum(ColorType)] _ColorType ("Color Type", Int) = 1
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _ColorType;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
//return 1 - col;
fixed4 newCol;
switch(_ColorType) {
case 2:
newCol = fixed4(col.x, col.z, col.y, col.w);
break;
case 3:
newCol = fixed4(col.y, col.x, col.z, col.w);
break;
case 4:
newCol = fixed4(col.y, col.z, col.x, col.w);
break;
case 5:
newCol = fixed4(col.z, col.x, col.y, col.w);
break;
case 6:
newCol = fixed4(col.z, col.y, col.x, col.w);
break;
default:
newCol = fixed4(col.x, col.y, col.z, col.w);
break;
}
return newCol;
}
ENDCG
}
}
}
