shadertoy上手指南

来源:互联网 发布:淘宝滑动验证码 编辑:程序博客网 时间:2024/05/17 23:32

一 shadertoy是什么

下面是维基百科上的定义:

Shadertoy.com is a cross-browser online community and tool for creating and sharing shaders through WebGL, used both for learning and teaching 3D computer graphics in a web browser

翻译成中文即shadertoy是一个在浏览器中教学3D图形学的在线社区和通过WebGL创建分享shader程序的工具。

从定义中可以看出,首先,shadertoy是一个在线社区,指的是shadertoy这个网站;其次,shadertoy是一个工具,这个工具是用来创建和分享shader程序的。

shadertoy 按字面意直接翻译过来就是着色器玩具。

二 怎么玩

既然shadertoy就是一玩具,那么要怎么玩呢?

首先,要明白的是shadertoy上我们编程的程序是pixel shader或者fragment shader,这个shader是用来计算屏幕上每个像素点的颜色的,以RGBA的形式输出给屏幕显示。

shadertoy社区上给了一个howto,对shadertoy中的函数接口和输入变量做了简单的介绍,此处只看图像着色器。

/** * fragColor 计算出的像素颜色 * fragCoord 像素坐标 */void mainImage( out vec4 fragColor, in vec2 fragCoord );// 计算每个像素的颜色/** *常量定义 */uniform vec3 iResolution;           // 窗口分辨率,单位像素uniform float iTime;                // 程序运行的时间,单位秒uniform float iTimeDelta;           // 渲染时间,单位秒uniform float iFrame;               // 帧率uniform vec4 iMouse;                // 鼠标位置uniform vec4 iDate;                 // 日期(年,月,日,时)...

新建一个shader,界面内容如下:

这里写图片描述

shader的默认代码如下:

void mainImage( out vec4 fragColor, in vec2 fragCoord ){    vec2 uv = fragCoord.xy / iResolution.xy;// 将坐标转换到0-1之间    fragColor = vec4(uv,0.5+0.5*sin(iTime),1.0);// r,g位置绝对,b随时间变化。}

可以看到,屏幕上的颜色,随着时间再不断变化。

修改代码如下:

void mainImage( out vec4 fragColor, in vec2 fragCoord ){    fragColor = vec4(1.0, 0.0, 0.0, 0.0);// 将输出颜色设置为红色}

运行可见,屏幕都变成了红色,fragColor表示最终每个像素的颜色,其每个颜色分量rgba分别对用vec4的每个值。

再次修改代码,如下:

void mainImage( out vec4 fragColor, in vec2 fragCoord ){    fragColor = vec4(0.0, 0.0, 0.0, 1.0);// 将默认颜色设置为黑色    // x坐标大于300的像素颜色设置为红色    if (fragCoord.x > 300.0) {        fragColor.r = 1.0;    }}

可以看到,一边红色一边黑色,点击全屏会发现,黑色的区域的宽度还是300,有时候这并不是我们想要的,我们希望黑色部分宽度的比例不变,修改代码如下:

void mainImage( out vec4 fragColor, in vec2 fragCoord ){    vec2 uv = fragCoord.xy/iResolution.xy;// 将坐标转换到0-1之间    fragColor = vec4(0.0, 0.0, 0.0, 1.0);// 将默认颜色设置为黑色    // x坐标大于0.3的像素颜色设置为红色    if (uv.x > 0.3) {        fragColor.r = 1.0;    }}

再次运行,不管是否全屏,黑色区域所占的比例还是这么多。

上面只是简单的修改了每个像素的颜色,就要使用图片来映射每个像素的颜色,通过channel随便选择一个张图,修改代码如下:

void mainImage( out vec4 fragColor, in vec2 fragCoord ){    vec2 uv = fragCoord.xy/iResolution.xy;// 将像素位置映射到0-1    fragColor = texture(iChannel0, uv);// 获取纹理在uv出的像素颜色}

纹理坐标的原点在左下角,取值范围是0-1,需要对坐标也做一次映射,可以看到图片就显示出来了。但是上面的全是静态的,如果我们想让画面有点变化,就需要用到iTime。修改代码如下:

void mainImage( out vec4 fragColor, in vec2 fragCoord ){    vec2 uv = fragCoord.xy/iResolution.xy;// 将像素位置映射到0-1    vec4 fragColor = texture(iChannel0, uv);// 获取纹理在uv出的像素颜色    fragColor.r = abs(sin(iTime));// 让红色分量的值随时间改变。}

iTime表示程序运行的时间,对其求正玄值得到的结果可能为负值,因此还需要对这个值求绝对值。

参考:

珠玉在前,在学习的过程中下面这两篇文章对入门帮助很大,推荐一下:

  • 【ShaderToy】开篇——来自shader女神冯乐乐

  • A Beginner’s Guide to Coding Graphics Shaders——国外兄弟

原创粉丝点击