OpenGL & Metal Shader 编程系列来了,要不要上车?

2023-09-04 17:54:06 浏览数 (2)

前面发了一些关于 Shader 编程的文章,有读者反馈太碎片化了,希望这里能整理出来一个系列,方便系统的学习一下 Shader 编程。

这不就来了,从这一篇就开启 Shader 编程系列文章的更新,当然中间也会穿插一些音视频、OpenGL 相关文章的更新。

OpenGL ES 和 Metal

本文讲的 Shader 编程主要针对移动端设备,经常要到的图形接口是 OpenGL ES 和 Metal 。

Metal 是由苹果公司所开发的 GPU 编程接口,兼顾图形与计算功能,面向底层、低开销的硬件加速,用于代替 OpenGL ES ,OpenGL ES 在 iOS 12 已经被标记为 deprecated 状态。

Metal 比 OpenGL ES 的优点:

  • Metal Api 更加 人性化,相比于 OpenGL 使用句柄的操作以及 C 语言的 Api,Metal 是面向对象的;
  • Metal 的多线程支持,相比于 OpenGL 的上下文与线程的绑定,Metal 是 线程安全 的;
  • Metal 的性能优于 OpenGL
  • Metal 支持 Compute shaders,能让我们使用 GPU 来做一些更加复杂的 并行计算 任务,如机器学习等,而 OpenGL 几乎只能支持与图形图像相关的。

Metal 比 OpenGL ES 的缺点:

  • Metal 仅支持 Apple 平台,而 OpenGL 是跨平台的;
  • Metal 对旧设备与系统支持不友好,而由于 OpenGL “出生” 较早,因此对旧的支持更好;

需要注意的是, OpenGL ES 在非苹果的移动端设备图形编程中依然保有很大的占有率,这一点从面试的时候,面试官主要问 OpenGL 相关知识可以看出来。

Shader 是什么

Shader 翻译过来叫做着色器,本质上也是一种程序,这种程序主要用于处理图像信息。Shader 代码并不运行在 CPU 上,而是运行在GPU(图形处理器)上。

使用Shader程序,开发者可以充分发挥GPU的并行计算能力,提高图形渲染的效率和质量。它们也为游戏开发、计算机视觉、科学可视化等领域提供了强大的工具,让开发者能够创造出更逼真、更吸引人的图形效果。

根据运行在渲染管线的不同阶段,Shader 主要分为三类:

  • Vertex Shader 顶点着色器
  • Fragment Shader 片段着色器
  • Geometry Shader 几何着色器

对渲染管线不熟悉的同学可以回顾文章:建议收藏:OpenGL 渲染管线 (pipeline)

其中最常用的是片段着色器,而我们后面讲的 Shader 编程主要涉及片段着色器, 片段着色器的作用就是产生颜色。

Shader 编程语言 GLSL & MSL

OpenGL Shader 的编程语言是 GLSL - OpenGL Shading Language ,是一个以C语言为基础的高阶着色语言,之前有文章详细介绍过,可以查阅:

Metal Shader 的编程语言是 MSL ,MSL 基于C 11.0 语言设计的,在 C 基础上多了一些扩展和限制,使用 Clang 和LLVM 进行编译处理,编译器对于在GPU上的代码执行效率有更好的控制。

MSL 和 GLSL 差别很小,有着相同的内置函数,所以将 GLSL 转换为 MSL 代码时改动不大,这里列出来几处差别,大致了解下。

代码语言:javascript复制
//GLSL
vec4 outColor = vec4(1.0);

outColor = texture2D(texture, uv);

//MSL
float4 outColor = float4(1.0);

outColor = texture.sample(sampler, uv);

由于主流的 Shader 编程网站,如 ShaderToy, gl-transitions 都是基于 GLSL 开发 Shader ,加上 MSL 和 GLSL 语法上差别不大,后面系列文章将以 GLSL 为主来介绍 Shader 编程。

Shader 编程环境

Shader 编程比较常用的是 ShaderToy 官网或者安装 VSCode ShaderToy 插件。

ShaderToy 官网,Shader 界的 Github ,里面的代码都是开源的,特效五花八门、应有尽有: https://www.shadertoy.com/new

VSCode ShaderToy 插件:

VSCode ShaderToy 插件使用可以参考之前的文章。

Hello World

编写第一个 Shader ,https://www.shadertoy.com/new ShaderToy 网站打开就是一个 Hello World 程序。

fragColor 表示输出颜色的向量,由 r,g,b,a 四个通道组成,fragCoord 表示像素坐标,也可以理解为纹理坐标,像素坐标原点位于左下角(你可以做实验试试),iResolution 表示开辟视口的分辨率(视口大小)。

我们直接修改它,根据每个像素所在位置的不同来生成不同的颜色,用纹理坐标分别替换 g、b 通道,然后点击左下角的编译按钮,Shader 就会直接运行起来了。

后续安排

后面 OpenGL & Metal Shader 编程系列文章大致安排:

  1. ShaderToy 内置全局变量
  2. 重要的内置函数
  3. 基本图形
  4. 距离场
  5. 噪声函数
  6. 基础特效…
  7. 转场特效…
  8. 高阶特效…

0 人点赞