timzaak / blog

8 stars 1 forks source link

GPU / 动画 基础资料收集 #117

Closed timzaak closed 4 months ago

timzaak commented 4 months ago

教程

wgpu 中文教程 tour of wgsl WGSL (Web GPU Shading Language) 教程,未完善 your first webgpu app 谷歌出品的Javascript webGPU教程,简单易懂。 webgpufundamentals 看完谷歌的下一个完整教程

Three.js

带你入门three.js——从0到1实现一个3d可视化地图 里面有 Three.js 基本概念介绍,和一个完整的地图绘制Demo,是很棒的入门教程。

基本概念

BufferGeometry 基础讲解(position、normal、color、index)

相机

ArrayCamera 包含着一组子摄像机,常用于多人同屏的渲染,更好地提升VR场景的渲染性能 StereoCamera 双透视摄像机(立体相机),常用于创建 3D 立体影像,比如 3D 电影之类或 VR CubeCamera 有6个渲染,分别是 立方体的6个面,常用于渲染环境、反光等 OrthographicCamera 正交相机,在这种投影模式下,无论物体距离相机距离远或者近,在最终渲染的图片中物体的大小都保持不变。这对于渲染2D场景或者UI元素是非常有用的。 PerspectiveCamera 透视相机,这一投影模式被用来模拟人眼所看到的景象,它是3D场景的渲染中使用得最普遍的投影模式。

灯光

Threejs系列--5灯光_小猴子喝牛奶的博客-CSDN博客_threejs 灯光

材质

Three 之 three.js (webgl)涉及的各种材质简单说明(常用材质配有效果图) three.js材质(一)

Shader/着色器

THREE.js Shader 默认参数 WebGL 教程 | MDN WebGLShader 基础讲解 OpenGL中的坐标系

实用教程

Drawing lines is hard

timzaak commented 4 months ago

常见底层库

OpenGL、WebGL 图形渲染,Vulkan 想做 OpenGL 的下一代。

SDL2 较为底层的跨平台多媒体框架,可用来播放视频(ffplayer用了它)。 https://wiki.libsdl.org/SDL3/Introduction

wgpu rust 实现的 webGPU 标准,底层是依据平台分别是 meta、openGL、directx,webgpu。

Apple 出品了 Metal 硬件加速图形。 微软 出品了 Direct3D 硬件加速图形。

timzaak commented 4 months ago

动画(轻量级, web、移动应用常用)

SVGA: https://www.svgator.com Lottie: https://lottiefiles.com, or 基于 Adobe Effect 插件 BodyMovin 制作。 Lottie 有免费资源,但需要插件播放,SVGA 不需要插件。

timzaak commented 4 months ago

GUI 库(Rust)

floem

基于 wgpu 编写的GPU框架。

  1. 窗口基于 winit 封装。
  2. 编写组件语法设计牛逼,尽可能让用户少些模版代码,感觉和 Flutter 差不多 ❗️(就是闭包有点多)。
  3. 鼠标、键盘、windows resize 事件处理入口在 app_handle.handle_window_event。
  4. layout library 使用的是 Taffy, 支持 Flex、CSS Grid, postion absolute,但z-index不支持。 z-index 事件触发影响通过此 Patch 解决:https://github.com/lapce/floem/commit/f921212204b0c85c5571e3e95d0d057c0faba5b5 , 简单讲:扩大父元素的触发范围。
  5. 渲染基于2D GPU renderer vger-rs fork or tiny-skia, 支持 z-index。 vger-rs 基于 wgpu,port vger;字体渲染: swash;SVG渲染: resvg 不清楚在 2D GPU render 支持 字体、SVG 渲染情况下,为何还是要引入上述两个。 吐槽一句:SVG 规范要尼玛900页。
  6. 采用 Signal 概念,来解决Reactive UI状态管理问题。 Signal 概念 要席卷整个 GUI 世界了。

iced

粗糙看来,底层和 floem 相同,都是 wgpu、tiny-skia。stateManger 不同, 具体要细看。

  1. 布局采用的 Druid 的 Flex 实现。不过有 iced-taffy 库。
  2. 和GPUI 大致相同的 hitbox 实现。

GPUI

事件遮盖问题,没有彻底解决(mouse move 会触发遮盖住的view 事件)。一般情况,可以基于组件的特殊性+触发顺序+向后传播,来满足绝大部分需求,iced 也是如此。

GUI 布局

布局分为:保留模式 / 及时模式,具体参看 iced 的 讲解

facebook/yoga React Native 的布局引擎。

timzaak commented 4 months ago

字体渲染

Text Rendering Hates You vger-rs 里有不少资料。

timzaak commented 4 months ago

device.createCommandEncoder 创建渲染通道 device.createRenderPipeline 创建管线, 需要着色器 vertex 、fragment、Buffer 的布局 encoder.beginRenderPass, 一般都是挂下背景色。 pass.end

device.createComputePipeline encoder.beginComputePass encoder.setPipeline computePass.dispatchWorkgroups 色器执行 32x32 次以覆盖整个网格,工作组大小为 8x8,则需要分派 4x4 个工作组 (4 * 8 = 32) computePass.end

device.queue.submit([encoder.finsh, commandEncoder.finish])

在渲染通道之前执行计算通道,因为这可以让渲染通道立即使用计算通道中的最新结果

device.queue.writeBuffer 写Buffer 数据。

device.createShaderModule 载入着色器。

device.createBuffer 创建 Buffer,并指定使用周期, 类型: uniform、storage、vertex 在着色器中声明 uniform 不会将其与缓冲区连接。需要创建并设置一个 bind 组 device.createBindGroup,layout 从createRenderPipeline 获取("auto"),对于多条管线,要device.createBindGroupLayout, 标明 bind 在不同阶段的可见性

timzaak commented 2 months ago

浏览器一个 Tab 页面最大支持使用2G内存,GPU 也受此限制。 Electron 可解开。 目前 WebGPU Rust 版本已被用于做游戏引擎渲染底层。

Processing,可以基于代码实现动画效果。 工业界,还是基于 Adobe Effect 之类的实现动效,导出 or 代码实现。

https://www.shadertoy.com/ 里面有很多神奇 shader 实现。

timzaak commented 2 months ago

基础数学

  1. 柏林噪声

    Shader 教程

    https://clauswilke.com/art/post/shaders https://thebookofshaders.com/?lan=ch