一。余弦函数
在第二个练习项目中,我们最后实现了在一个白色的画布上画了一个蓝色的圆。现在我们利用全局_Time变量让圆随着时间来改变颜色。首先看一下余弦(cos)函数,它是一个周期函数,函数值在-1和1之间。用GeoGebra可视化这个函数如下:
由于颜色值的范围在【0,1】,所以我们需要将cos(x)的函数值调整到【0,1】的范围中。我们对cos(x)做这样的处理,在用GeoGebra可视化如下:
我们还继续对cos进行变形,其中a是一个变量,类似我们的全局时间iTime变量,如下:
二。应用余弦函数到Shader代码
首先我们在第二个shader练习中生成一个圆,我们继续在那个代码上做修改,代码如下:
Shader "Unlit/TestShader" { Properties { } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } float3 Circle(float2 uv, float r) { float x = uv.x; float y = uv.y; float d = length(float2(x, y)) - r; if(d > 0) { return float3(0.0, 0.0, 0.0); } else { return float3(0.0, 0.0, 1.0); } } fixed4 frag (v2f i) : SV_Target { float2 uv = i.uv; uv -= float2(0.5, 0.5); float aspect = _ScreenParams.x / _ScreenParams.y; uv.x *= aspect; float3 col = Circle(uv, 0.1); return fixed4(col, 1.0); } ENDCG } } }
我们修改Circle函数,当d<=0时,返回的颜色根据_Time变化,而不是固定的蓝色。代码如下:
float3 Circle(float2 uv, float r) { float x = uv.x; float y = uv.y; float d = length(float2(x, y)) - r; if(d > 0) { return float3(1.0, 1.0, 1.0); } else { return 0.5 + 0.5 * cos(_Time.y + float3(x, y, x) + float3(0.0, 2.0, 4.0)); } }
在其中float3(x, y, x)目的是增加颜色随uv的坐标位置发生变化,float3(0.0, 2.0, 4.0)相当于给余弦函数增加一个相位,使RGB三个变量有差异。在unity的效果如下(把背景色改成黑色,更明显一些):
完整的项目地址放在github上,可以自行下载(https://github.com/evazhuang/Shader.git)。
到这里,我们用Shader丰富圆的颜色的练习就结束了,感谢观看,预告下一次将练习如何用Shader让这个圆动起来,敬请期待!