ShaderToy学习笔记 01.基础知识

ShaderToy学习笔记

先欣赏一下用ShaderToy画出来的效果


上图代码在 https://www.shadertoy.com/view/Ms2SD1

本系列是ShaderToy的入门学习笔记,主要记录学习心得及一些学习过程中遇到的问题和解决方案。
学习资源:

  1. https://shadertoy.peakcoder.com/
  2. https://inspirnathan.com/posts/47-shadertoy-tutorial-part-1
  3. https://www.zhihu.com/column/c_1591440349909774336

参考资料:

  1. https://www.shadertoy.com/
  2. Learn to Paint with Mathematics
  3. Shadertoy Unofficial
  4. https://blog.csdn.net/sunboylife/article/details/139815032
  5. ShaderToy入门手册
  6. ShaderToy教程
  7. Ray Marching for Dummies!
  8. Seascape
  9. https://raytracing.github.io/books/RayTracingInOneWeekend.html
  10. 《用两天学习光线追踪》1.项目介绍和ppm图片输出_用光线追踪画图-CSDN博客
  11. GitHub - maijiaquan/ray-tracing-with-imgui: 本项目参考自教程《Ray Tracing in One Weekend》,使用CPU多线程加速,结合ImGUI显示渲染结果。
  12. https://inspirnathan.com/posts/47-shadertoy-tutorial-part-1
  13. Desmos | Beautiful free math.

1. 基础知识

1.1. 环境搭建

shadertoy 有以下几种方式来运行:

  1. 浏览器 https://www.shadertoy.com/new
  2. vscode 中运行

此处讲解第二种方式,需要安装以下插件:

  1. glsl 插件
  2. shader toy

ShaderToy学习笔记 01.基础知识_第1张图片
ShaderToy学习笔记 01.基础知识_第2张图片

1.2. 第一个shader

新建一个test1.glsl文件,输入以下内容:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Time varying pixel color
    vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));

    // Output to screen
    fragColor = vec4(col,1.0);
}

点击vscode 菜单“查看” 、“命令面板”,选择“Shader Toy: Show GLSL Preview",即可运行。
ShaderToy学习笔记 01.基础知识_第3张图片

1.3. 坐标系

ShaderToy学习笔记 01.基础知识_第4张图片
注意: (0,0) 在左下角

1.4. 变量

1.4.1. Resolution

vec3 iResolution: 其中前两个分量分别存储了视窗的宽度和高度(以像素为单位),即x分量是窗口宽度,y分量是窗口高度

1.4.2. Time

变量名 类型 中文说明
iTime float 着色器运行时间(秒),从程序启动开始计时
iTimeDelta float 帧间隔时间(秒)
iFrame int 当前帧编号
iMouse vec4 鼠标坐标/状态,xy=当前位置,zw=点击位置
iDate vec4 系统日期(年,月,日,秒)
iSampleRate float 音频采样率
fragCoord vec2 当前像素坐标(原点在左下角)
fragColor vec4 输出颜色(RGBA格式)

1.5. 坐标归一化

1.5.1. 坐标归一化到[0,1]

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;
    //...
}

归一化后,uv的范围是[0,1],即左下角是(0,0),右上角是(1,1)

1.5.2. 坐标归一化到[-1,1]

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = (fragCoord/iResolution.xy - 0.5)*2.0;
    //...
}

注意:归一化后,uv的范围是[-1,1],即左下角是(-1,-1),右上角是(1,1)
但这样会有一个问题,就是当窗口的宽高比不等于1时,会出现变形。
比如 宽高比是2:1,则归一化后x轴从[-1,1],y轴从[-1,1] ,意味着 x轴2个像素对应y轴1个像素

1.5.3. 坐标归一化,短边归一化到[-1,1],长边保持宽高比

vec2 uv = (2.0*fragCoord-iResolution.xy)/min(iResolution.x,iResolution.y);

短边归一化到[-1,1],长边保持宽高比,会取最小值作为基准进行缩放
软件中通常采用这种方式来进行归一化,这样可以保证无论窗口的宽高比如何,都可以保持正确的比例。

1.6. 常用函数

1.6.1. 基础数学函数

函数 说明 示例
abs(x) 返回x的绝对值 abs(-2.0) = 2.0
floor(x) 返回小于等于x的最大整数 floor(3.7) = 3.0
ceil(x) 返回大于等于x的最小整数 ceil(3.2) = 4.0
fract(x) 返回x的小数部分 fract(3.7) = 0.7
mod(x,y) 返回x对y的取模 mod(7.0, 3.0) = 1.0
min(x,y) 返回x和y中的较小值 min(2.0, 3.0) = 2.0
max(x,y) 返回x和y中的较大值 max(2.0, 3.0) = 3.0
clamp(x,min,max) 将x限制在[min,max]范围内 clamp(2.5, 1.0, 2.0) = 2.0

1.6.2. 三角函数

函数 说明 示例
sin(x) 正弦函数 sin(3.14159/2.0) = 1.0
cos(x) 余弦函数 cos(0.0) = 1.0
tan(x) 正切函数 tan(0.0) = 0.0
asin(x) 反正弦函数 asin(1.0) = 1.5708
acos(x) 反余弦函数 acos(1.0) = 0.0
atan(x) 反正切函数 atan(1.0) = 0.7854
atan(y,x) 二参数反正切函数 atan(1.0, 1.0) = 0.7854

1.6.3. 插值和平滑函数

函数 说明 数学公式 示例
mix(x,y,a) 在x和y之间按a进行线性插值。a的范围在[0,1]之间,当a=0时返回x,当a=1时返回y f(x,y,a) = x * (1-a) + y * a mix(0.0, 1.0, 0.5) = 0.5
step(edge,x) 阶跃函数,创建一个突变的边界。如果x < edge返回0.0,否则返回1.0 f(edge,x) = { 0.0, x < edge
{ 1.0, x ≥ edge
step(0.5, 0.7) = 1.0
smoothstep(edge0,edge1,x) 在edge0和edge1之间创建平滑的Hermite插值。x值小于edge0时返回0.0,大于edge1时返回1.0 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0)
f(edge0,edge1,x) = t * t * (3 - 2 * t)
smoothstep(0.0, 1.0, 0.5) = 0.5

1.6.4. 向量操作函数

函数 说明 示例
length(v) 返回向量的长度 length(vec2(3.0, 4.0)) = 5.0
distance(p0,p1) 返回两点之间的距离 distance(vec2(0.0), vec2(3.0, 4.0)) = 5.0
dot(x,y) 返回两个向量的点积 dot(vec2(1.0), vec2(1.0)) = 1.0
cross(x,y) 返回两个向量的叉积 cross(vec3(1,0,0), vec3(0,1,0)) = vec3(0,0,1)
normalize(x) 返回向量的单位向量 normalize(vec2(3.0, 4.0)) = vec2(0.6, 0.8)
reflect(I,N) 返回入射向量I关于法线N的反射向量 reflect(vec3(1.0), vec3(0.0, 1.0, 0.0))
refract(I,N,eta) 返回入射向量I关于法线N的折射向量 refract(I, N, 1.0/1.5)

1.6.5. 矩阵操作函数

函数 说明 示例
matrixCompMult(x,y) 矩阵分量相乘 matrixCompMult(mat2(2.0), mat2(3.0))
inverse(m) 返回矩阵的逆 inverse(mat3(1.0))
transpose(m) 返回矩阵的转置 transpose(mat4(1.0))

1.6.6. 纹理采样函数

函数 说明 示例
texture2D(sampler,uv) 2D纹理采样 texture2D(iChannel0, uv)
textureCube(sampler,xyz) 立方体纹理采样 textureCube(iChannel0, vec3(1.0))
texture2DLod(sampler,uv,lod) 指定LOD级别的2D纹理采样 texture2DLod(iChannel0, uv, 1.0)

1.6.7. 常用工具函数

函数 说明 示例
pow(x,y) x的y次方 pow(2.0, 3.0) = 8.0
exp(x) e的x次方 exp(1.0) = 2.7183
exp2(x) 2的x次方 exp2(3.0) = 8.0
log(x) x的自然对数 log(2.7183) = 1.0
log2(x) x的以2为底的对数 log2(8.0) = 3.0
sqrt(x) x的平方根 sqrt(9.0) = 3.0
inversesqrt(x) x的平方根的倒数 inversesqrt(16.0) = 0.25

1.6.8. 常用内置变量

变量 说明 示例值
iResolution 渲染目标的分辨率 vec3(1920, 1080, 1.0)
iTime 着色器运行的时间(秒) 10.0
iTimeDelta 上一帧到当前帧的时间差 0.0167
iFrame 当前帧号 100
iMouse 鼠标坐标 vec4(x, y, click_x, click_y)
iDate 日期 vec4(year, month, day, time)
iChanneln 输入通道n (n=0,1,2,3) sampler2D

1.7. 参考资料

  1. https://blog.csdn.net/sunboylife/article/details/139815032

你可能感兴趣的:(ShaderToy学习笔记,学习,笔记,3d)