楼主:
meowyih (meowyih)
2021-09-27 13:32:25前二天在这篇文章
文章代码(AID): #1XJQL9jP (GameDesign)
才知道有 https://www.shadertoy.com/ 这个方便测试 WebGL 的网站,
就称趁机写了三篇非常入门的 shader language 教学,
帮想从零开始学 shader language (GLSL)
的网友省点时间
UV 座标
讲 shader 一定要先提的是 UV 座标。
UV其实就是一个长方形的XY轴座标,
差别是UV的座标值是在 [0,1] 之间,
所以UV(0.5,0.5)就是平面的正中央。
举例,
一个画布长宽 (600,400),
某个点 a1 位置 (300, 100),
其 uv 是
(300/600, 100/400) = (0.5, 0.25)。
UV这名字的由来,
就只是因为这二个字母是在三维的(X,Y,Z)前,
没别的意义。
UV 的原点,
在 WebGL 是在左下角,
在 Godot 是在左上角,
并不一定。
颜色
shader用 RGB 加上一个透明度的四个值代表颜色。
四个值都在[0,1]之间,
大于1都算1,小于0就是0。
白色就是(1,1,1,1),黑色就是(0,0,0,1)。
因为UV座标和颜色的值都是[0,1]之间,
所以马上可以写一个简单的程式测试圆点在哪。
使用 ShaderToy 网站
开启 https://www.shadertoy.com/ ,
点右上的 New,
在右边编辑框内打入下面程式,
按下面 compile 的三角形执行按钮。
code
https://i.imgur.com/VrybqHX.jpg
img
https://i.imgur.com/LeBQYwD.png
说明
每次要画一个 pixel,
都会呼叫一次 mainImage()。
vec4 fragColor 是 pixel 的颜色,
fragCoord 是 pixel 座标 (非UV)。
iResolution 是 ShaderToy 内建的参数,
代表了画面的长宽最大值。
Godot 要怎么写?
在 Godot 中要写 shader,
最快的方法是建立一个 ColorRect Node,
填入 Rect 的长宽 (size),
颜色 (color)。
再到右边 Inspector 的
CanvasItem -> Materil ->
ShaderMaterial -> New Shader
就可以在 Shader Editor 里开始写了。
在 Godot 中,同样的 function 是这样写的。
code
https://i.imgur.com/Kw0d526.jpg
UV 是 global variable 不用计算,
COLOR 也是类似的 variable。
因为都算是 GLSL,
长的都差不多。
比较 ShaderToy 和 Godot 的执行画面,
ShaderToy 的黑色区域在左下角,
Godot 在左上角,
代表二者的原点位置不同。
椭圆弧形变正圆弧形
因为画面不是正方形,
而是长方形,
所以看的出来画出的渐层并非正圆弧,
而是椭圆形弧形的。
要解决 uv 的二个值最大都是 1,
代表的真实长度却不同的问题,
我们可以重新计算 x 或 y 值。
一般来说 resolution.y 比较短 (横向画面),
所以当作 1,照比例调整 uv.x。
code
https://i.imgur.com/QlLz5yE.jpg
image
https://i.imgur.com/3jhrLbm.png
在 Godot 里,
语法也差不多。
差别是多了个可以从外部更改的 resolution 的 uniform 变量,
取得作画范围的像素长宽值。
code
https://i.imgur.com/UyGE880.jpg
转换了 uv.x 后,
画出来的阴影就是个圆弧形,
而非椭圆弧形的了。
将原点改成画面中心处
如果我们想把原点放在中央,
而非左上或左下,
只要加一行座标转换就可以了。
code
https://i.imgur.com/opVlKK9.jpg
这样圆心就在中间了。
image
https://i.imgur.com/XntdZ4F.png
Godot version
https://i.imgur.com/NNApsmn.jpg
下一篇,
要将这个渐层的圆形,
变成单色的圆形。