Shadertoy因其类似玩具的特性而被称为“TOY”。它基本上是一款谜题游戏。给定一个函数,该函数的输入是当前像素位置,编写一个生成图像的函数。
该网站设置WebGL以绘制单个四边形,然后让您提供一个函数,该函数将当前正在渲染的像素作为fragCoord
传递。接着您可以使用该函数计算一些颜色。
例如,如果您这样做:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec4 red = vec4(1, 0, 0, 1);
vec4 green = vec4(0, 1, 0, 1);
fragColor = mix(red, green, sin(fragCoord.x / 10.0) * 0.5 + 0.5);
}
如果您这样做,则会得到红色和绿色条纹
https://www.shadertoy.com/view/3l2cRz
Shadertoy提供了一些其他的输入。最常见的是正在渲染的分辨率,即iResolution
。 如果将fragCoord
除以iResolution
,则可以获得跨越画布从0到1的值,因此您可以轻松地使您的功能与分辨率无关。
这样我们就可以在中心绘制一个椭圆,如下所示:
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
vec2 uv = fragCoord / iResolution.xy;
vec4 red = vec4(1, 0, 0, 1);
vec4 green = vec4(0, 1, 0, 1);
float distanceFromCenter = distance(uv, vec2(0.5));
fragColor = mix(red, green, step(0.25, distanceFromCenter));
}
这个工具可以生成如下的图像:
第二个最常见的输入是iTime
,以秒为单位,您可以在函数中使用animate参数随时间变化。
因此,如果您应用足够的数学知识,就可以生成像这个shadertoy着色器生成的这个图像那样令人惊叹的图像
很惊人,有人找出了只给出上述输入就能生成该图像所需的数学方法。
许多最惊人的shadertoy着色器使用一种称为ray marching的技术和一些称为“signed distance fields”的数学方法,您可以在这里阅读相关信息。
但是,我认为值得指出的是,尽管从shadertoy着色器中可以学习到许多酷炫的内容,但其中许多只适用于“如何使用一个仅由像素位置作为输入、单个颜色作为输出的函数创建美丽图像”的“难题”中。它们并不能回答“我应该如何为高性能应用程序编写着色器”的问题。
将以上的海豚shader与这个speedboat游戏进行比较
https://www.youtube.com/watch?v=7v9gZK9HqqI
当全屏时,海豚shadertoy着色器在我的NVidia GeForce GT 750上以大约2帧每秒的速度运行,而速度艇游戏则以60fps的速度运行。游戏运行快的原因是它使用更传统的技术,在投影三角形时绘制形状。即使是NVidia 1060 GTX也只能以大约10帧每秒的速度运行该海豚shader。