前兩天討論了畫圖的部分,今天討論加減乘除與遮罩
為了方便處理加減乘除,先整理前幾天的程式碼:
float Circle(vec2 uv, vec2 p , float r, float blur){
float d = length(uv-p);
float c = smoothstep(r, r-blur, d);
return c;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord/iResolution.xy;
uv -= .5;
uv.x *= iResolution.x / iResolution.y;
float c1 = Circle(uv, vec2(-.2, 0.), .4, .2);
vec3 col = vec3(c1);
fragColor = vec4(col,1.0);
}
float Circle(vec2 uv, vec2 p , float r, float blur){
float d = length(uv-p);
float c = smoothstep(r, r-blur, d);
return c;
}
float c1 = Circle(uv, vec2(-.2, 0.), .4, .2);
vec3 col = vec3(c1);
用同樣的方法,畫上另一個圓
float c2 = Circle(uv, vec2(.2, 0.), .4, .2);
vec3 col = vec3(c2);
兩個圈只有命名與位置不同:
c1: 位置在中間偏左,uv.x -.2
的位置
c2: 位置在中間偏右,uv.x +.2
的位置
取了兩個圓圈之後,用這兩個圓圈來做運算
想象中這兩個圓的相加
黑色+黑色 = 黑色 (0. + 0. 還是 0.)
白色+白色 = 白色 (1. + 1. 大於 1., 顯示白色)
毛邊+毛邊...應該是平平順順的結果吧
(想像畫面,用 Photoshop 來試做的話,也許像是濾色 Screen) 的結果
實際上取相加的結果:
float c1 = Circle(uv, vec2(-.2, 0.), .4, .2);
float c2 = Circle(uv, vec2( .2, 0.), .4, .2);
vec3 col = vec3(c1+c2);
紅框內的形狀有些意外,
因為相加...所以結果是這樣
同樣的,雖然知道運算邏輯,但相減的結果還是令人驚訝
vec3 col = vec3(c1-c2);
vec3 col = vec3(c1*c2);
覺得是加減乘除運算中最特別的一個
結果是兩個圖像的交集、兩個圖像共有的畫面,
也可當作 遮罩 使用
vec3 col = vec3(c1/c2);
相除,同樣滿特別的
將 Photoshop 各種混合模式對應到這兩個圈時,很多結果很特別
由於是公式結果,一個個列出來的用意不大
有機會可以試試
取自Photoshop 教學 - Make your first layer mask:
Photoshop 裡的遮罩功能
在製作遮罩的時候,會有一個白色畫面,
白色畫面會留著,黑色的會被遮掉
實際上用 Shader 運算遮罩效果的時候,將原圖
乘上遮罩圖像
即可
Shadertoy 有內建素材可以使用:
點選下方 iChannel0,選擇 Textures > Abstract 1:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord/iResolution.xy;
vec4 texture_pic = texture(iChannel0, uv);
fragColor = vec4(texture_pic);
}
結果:
texture() 方法:
vec4 texture(sampler2D sampler, vec2 coord)
會回傳 vec4,因此可直接使用 fragColor 輸出
先畫一個圓,放在畫面中間:
float c1 = Circle(uv, vec2(0., 0.), .4, .2);
fragColor = vec4(vec3(c1), 1.);
將圓與圖片相乘,取得遮罩結果:
vec4 texture_pic = texture(iChannel0, fragCoord/iResolution.xy);
fragColor = texture_pic * c1;
本篇完整程式碼 (使用時需設定 iChannel0 的素材):
float Circle(vec2 uv, vec2 p , float r, float blur){
float d = length(uv-p);
float c = smoothstep(r, r-blur, d);
return c;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord/iResolution.xy;
uv -= .5;
uv.x *= iResolution.x / iResolution.y;
float c1 = Circle(uv, vec2(0., 0.), .4, .2);
vec4 texture_pic = texture(iChannel0, fragCoord/iResolution.xy);
fragColor = texture_pic * c1;
}
與數學公式相關的部分會先到這篇,
接著會介紹一些 Shader 的特性