关于颜色

388 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情

第六章就是颜色了。首先来看一下颜色的数据类型。

shader里的向量

颜色是四维向量vec4 我们就直接拿四维向量来说明。

四维向量有四个分量,如果每个分量都是float ,如果你用一个含有int的数据去和它计算就会出错,这是我们写js习惯了很容易犯的错误,从语法上看,有小数点的就是。

如果你把向量看做是一个对象,那么一个四维向量是有xyzw四个属性的,分别就对应其分量。 这四个属性可以自由读写,同时这四个属性还有别名,分别就是 rgba ,0123,  stpq。

更方便的是, 可以直接连续写xy, xyz 就能表示对应的二 、三维向量

同维向量之间可以直接进行四则运算,其运算法则就是对应分量进行运算, 结果仍是向量

数字和向量之间可以直接进行四则运算,其运算法则就是对应分量分别进行运算,结果仍是向量

至于我们熟悉的向量点乘和叉乘,由内置函数实现

vec4 color = vec4(1.0,2.0,3.0,1.);
vec4 color2 = vec4(vec3(1,2,3),1.);
vec4 color3 = vec4(color.rgb,1.);

color *= .1 // vec4(.1,.2,.3,.1)
color /= color2 // vec4(1/1,2/2,3/3,1/1)

向量的值域

虽然,webgl里没有限制,但是具有实际意义的最终数据基本上都是01之间。

裁剪空间里的坐标值域和颜色的值域都是01之间,颜色的值如果小于0 会按0处理。

如果要把css颜色和webgl颜色对应起来那就是256, css颜色经常使用六位16进制来表示一个色值,实际上就是rgb每个分量各两位,16的两次就是256。

比如 颜色 #000000 ,实际上就是 (00,00,00 )看上去没啥区别,那是因为16进制的0也是零啊, 我们再看白色 #ffffff 就是(15 15,15 15,15 15) ==》(255,255,255)。

rgb是符合可见光的颜色空间,0就是没有,没光就是暗,暗就是黑,#000000就是黑色

f就是最大,满光,全都亮了就是白光,白光包含了我们全部的可见光。

01之间的巧妙之处在于,01之间的乘法运算结果也是01之间, 至于加法就需要控制系数之和不超过1,还是01 。

颜色混合

其实就是mix函数的应用,其实上篇已经用过了。再来梳理一下。 先看函数的用法。 说得是,获取两个值之间的某个值。

mix(x,y,a) = a*x + y * (1-a) ;

x y 必须同类型, a可以是同类型或者数值。

image.png

这个函数还是挺有用的,章节示例中的渐变和mix其实一毛钱关系都没有, 渐变就是按照某种函数曲线让这个混合系数从 0 到 1 ,从1 到 0也行。这就是渐变。

简单一点渐变只要把颜色和某个本来就存在的变量关联在一起就可以实现。 比如,线性渐变就是把颜色和某个方向上的线性变化关联起来了

下面就随手写了一个例子,效果我也不知道会是啥样。

vec3 color =vec3(0) 

color.r= st.x // x方向上的关联
color.g = length(st.xy) // 把颜色和到点00的距离关联起来
color.b = sin(u_time /10.) // 随时间正弦变化 。

运行结果如下,这个截图体现不出时间的变化,可以自行运行,如果你们运行发现报错,那是因为没有加分号。

image.png

色彩空间

色彩空间说的是表示颜色的一种方式,并且是运算封闭的,就是同一种色彩空间的颜色相互混合,其结果仍然是属于这个色彩空间。

我们一直在用的rgba是可见光,对应光的三原色 红绿蓝。

与之对应的就有cmyk是颜料,刚好是用吸收光来论的,我们知道如果我们看见一个不发光的物体是绿色的话,这说明它反射绿色的光,但是其他颜色的光呢,自然是被它吸收了,黑色吸收全部光,白色反射全部的光。 这个我们估计不常用,除非有具体业务场景。

HSB

这个我们就常用了。说起光谱大家都知道 赤橙黄绿蓝靛紫 ,但是如果用rbga来表示,似乎无从下手。所以有了hsb这种色彩空间。

h 表示色相 即 是什么颜色

s 代表饱和度 即 颜色的深浅浓淡

l 代表亮度 即 颜色的明暗 越亮就越接近白色,越暗就越接近黑色。

image.png

image.png

今日份水文就到这里,下次继续。