您需要 登录 才可以下载或查看,没有账号?注册
x
教程不是源码,不是只上源码,涵盖作者的分析思路 。
首先,我认真分析了它颜色的分布规则,发现了一个很有趣的规律 :
作者手稿,勿喷:
这样的分配,大概每一部就是RGB三色其中的一个在变化,而且变化规律也就像右边写的。
那么这样就总结出一个规律,我画了一张图:
大概按刚刚那样的分组,一次加减为一组,一共分了三组。横坐标就是UV的x值了
纵坐标看起来有点矮,其实应该都是从 0 到 1 的 。
那么,我们就想道了,分别实现一个变化曲线,来控制RGB三个颜色的变化:
拿绿色的举例:
在 1/6 处上升为 1 , 并保持 到 3/6 ,然后再减到 1 此时是 4/6 。
其他的同理啦,就是一个平移变化嘛 。
第二步,构造这个函数图像的表达式 :
打开一个在线网页,就是来画函数图像的:
好,那怎么构造呢 ?
首先我们想要一个锯齿装的图像,基本思路就是 取模和取绝对值混用。
我为了得到1/6这个点 , 那就取6的倍数了:
y = mod(6x , 6 )
= 6*x % 6 :
得到图像:
显然还不够,我想把他做成那种左右对称的锯齿状,如果现在直接abs的化,是没有效果的,所以之前要先向下平移3个单位:
y = mod(6x , 6 ) - 3
= 6*x % 6 - 3 :
然后对他abs:
大概效果已经差不多了,但是取值范围这些还没有确定,我们还得修改:
如果我们放大一下图像就会看到:
在 0 - 1 的范围内是这样的,而我们之前的想法是 在1/6 到 3/6 保持不变的,那么也就是 1/3的范围 , 我们怎么找这样一个范围 ?
看到这个图像我想到了,直接向下平移一些距离,使得 x1 + 1/3 = x2
那么我们就解这个方程:
设 x1, x2
且 x1 + 1/3 = x2
且 f(x1 ) = f(x2)
f(x) = 6*x % 6 - 3
最后解得:y = 1
那么我们就让 y 减去 1 就行了:
y = abs( 6 * x % 6 - 3 ) -1
有了这个,我们其余得部分就不要了,用 clamp 函数把 0 , 1 之外的减去,
y = clamp(abs( 6 * x % 6 - 3 ) -1,0,1)
OK , 基本快完成了 , 然后 G 要平移一下,我们把 4/6 点直接平移到坐标原点就行了。
clamp(abs( 6 * (x+4/6) % 6 - 3 ) -1,0,1)
这就是RGB中,G随 UV.x 的变化曲线 .
那么现在,就可以来写shader 了,
为了方便阅读,我把他么分成了几个函数来 :
第一步,计算偏移量:
float computeOffset(float x , float off )
{
return (x + off /6);
}
第二步,计算 模
float computeMod(float x ,float offset )
{
return 6 * computeOffset(x,offset) % 6 - 3 ;
}
第三步,计算 绝对值
float computeABS( float x ,float offset )
{
return abs(computeMod(x,offset))-1 ;
}
最后一步直接写道代码里把:
float R = clamp(computeABS(c.x,0),0,1);
float G = clamp(computeABS(c.x,4),0,1);
float B = clamp(computeABS(c.x,2),0,1);
vec3 rgb = vec3(R,G,B);
此时,效果就是这样了:
看到颜色似乎过度太明显了,我们修正一下:
我直接用图形学基本公式了:
-2 * pow(x,3 ) + 3 * pow( x , 2 )
它的曲线张这样:
经常会使用到的平滑曲线,然后得到平滑后的图像:
最后一步就是,我们还要增加他的亮度变化,直接用uv.y 进行叠加就OK:
rgb = uv.y * rgb
最后还有一个饱和度的叠加,我们要引入第三个变量了
saturation ("radies", Range(0.0,1.0)) = 1.0
rgb = uv.y * mix( fixed3(1.0,1.0,1.0), rgb, saturation );
最后就可以用 saturation 调节饱和度了:
源码:收100意思一下啦~~
价格:100元素币 (或10余额)
包含源代码
销售总额:200元素币 购买人数:2
|