shadertoy上手指南

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xufeng0991/article/details/78076824

一 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的默认代码如下:

扫描二维码关注公众号,回复: 3170479 查看本文章
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表示程序运行的时间,对其求正玄值得到的结果可能为负值,因此还需要对这个值求绝对值。

参考:

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

猜你喜欢

转载自blog.csdn.net/xufeng0991/article/details/78076824