您的位置:首页 > 移动开发 > Unity3D

unity 中使用HSV 颜色模型进行颜色的随机变化

2018-02-27 18:25 351 查看
经常能看到一些游戏中背景或是场景颜色的变换,每次进入游戏都能看到不一样的效果,像我之前介绍的游戏Polyforge一样:



实现一个这样的效果,可以直接使用rgb颜色来随机,因为平时我们接触到的大部分都是rgb颜色,但是这样的话带来的效果就是有时候亮有时候暗,甚至有纯白纯黑。而我们想要的是鲜艳一些的,有没有办法只获取色系中的彩色部分呢?这时候HSV颜色模型就派上用场了!
关于颜色模型有很多种,这里我就不多说了,我了解的也就是rgb和hsv,有兴趣的同学可以自己去百度。
看一下HSV模型的样子:



图片来自百度百科
这个模型中颜色的参数分别是:色调(H),饱和度(S),明度(V)。

很明显,我们只要确定了S和V,随机H值就可以得到任意的颜色了。
在unity中的应用很简单,c#中的Color类已经给我们封装好了方法: Color.HSVToRGB();
Color.RGBToHSV();在shader中的转换网上有很多,我找了一个比较简洁的,已经测试可以直接使用: CGINCLUDE
float3 RGB2HSV(float3 c)
{
float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g));
float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r));

float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

float3 HSV2RGB(float3 c)
{
float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);
}

ENDCG代码来自:MrASL的博客


这里我在C#中写了一个测试代码:public class ColorSystemTest : MonoBehaviour {

Material m ;
float H;
public float S;
public float V;

// Use this for initialization
void Start () {
m = transform.GetComponent<Renderer>().material;
H = Random.Range(0f, 1f);
}

// Update is called once per frame
void Update () {
H += Time.deltaTime*0.1f ;
H = H - (int)H;
Color target = Color.HSVToRGB(H, S, V);
m.SetVector("_Color", target);
}
}就是在update中不断的修改H值,让H从0-1不断循环,看下效果:



shader中的使用方法也顺便贴出来:Shader "Custom/HSVColor" {
Properties {
_Rate("rotate rate", Range(0,1)) = 0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200

CGINCLUDE
float3 RGB2HSV(float3 c)
{
float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g));
float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r));

float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

float3 HSV2RGB(float3 c)
{
float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);
}

ENDCG

Pass{
CGPROGRAM

#include "UnityCG.cginc"
#pragma vertex vert_img
#pragma fragment frag

fixed _Rate;

float4 frag( v2f_img o ) : COLOR
{
float3 c = float3(0.0f,0.5f,0.5f);
c.x = c.x + _Rate;
c = HSV2RGB(c);
return float4(c,1.0f);
}
ENDCG
}
}
FallBack "Diffuse"
}此shader需要在c#中传入_Rate,即H的值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  unity shader HSV
相关文章推荐