• 渲染管线(Rendering Pipeline): 是一套具体的执行流程和数据流向(比如:顶点输入 顶点着色器 光栅化 片元着色器 混合输出)。它是硬件(GPU)和图形 API 规定好的流水线。

  • 渲染核心模块(图中你记录的 8 个点): 是游戏引擎或渲染器在软件架构上的子系统和功能划分。它们负责组织数据、优化裁剪,最终把准备好的数据喂给渲染管线去执行。

如果用汽车制造厂来打比方:

  • 渲染管线是厂里的自动化装配流水线(车架进来 装发动机 喷漆 质检 成车出厂)。

  • 渲染核心模块是厂里的各个核心管理部门(如:物流部负责资源流送、规划部负责场景组织、涂装设计部负责材质系统)。这些部门通力合作,就是为了让流水线(管线)能高效运转起来。

一、 光栅化具体是怎么做的?

传统的光栅化(Rasterization)是目前绝大多数游戏引擎(UE、Unity、Babylon.js)的核心渲染方式。它的核心任务是:把 3D 的几何模型(三角形)变成 2D 屏幕上的像素点。

具体步骤可以分为以下四个核心阶段:

[3D模型顶点] -> (1.顶点着色器) -> [2D屏幕空间三角形] -> (2.光栅化阶段/找像素) -> [片元/像素候选点] -> (3.片元着色器/算颜色) -> [最终屏幕画面]

1. 顶点着色器(Vertex Shader)

  • 输入:3D 软件(如 Blender/3ds Max)导出的模型顶点数据(位置、UV、法线)。

  • 操作:通过矩阵变换,把这些 3D 空间里的顶点投影到 2D 的屏幕裁剪空间上。

2. 光栅化阶段(Rasterization Stage - 硬件自动化)

  • 显卡芯片会看屏幕上有哪些像素的中心点掉进了刚才投射下来的 2D 三角形里面。

  • 插值(Interpolation):如果三角形的三个顶点有不同的颜色或法线,光栅化芯片会自动根据像素距离三个顶点的远近,通过重心坐标算法给夹在中间的每个像素计算出平滑过渡的法线和 UV 坐标。这些准备好的像素点在图形学里叫片元(Fragment)

3. 片元着色器(Fragment Shader)

  • 针对每个被三角形覆盖的像素点,执行一次片元着色器代码。

  • 读取纹理贴图、计算光照公式,最终输出一个 RGB 颜色值。

4. 输出合并(Output Merging)

  • 进行深度测试(Depth Test)。如果这个像素前面有更近的物体挡着,就把当前算的颜色丢弃;如果没有,就写入屏幕缓冲区。

一、 什么是片元着色器(Fragment Shader)?

渲染管线就是一个“从三维模型到二维像素”的流水线。

  1. 什么是片元(Fragment): 模型在经过顶点处理后,会被投影到二维屏幕上。GPU 会把这些几何图形(通常是三角形)切散成一个个紧密排列的小方格,准备映射到屏幕的像素上。这一个个小方格在通过“深度测试”、“剪裁”等考核、最终变成真正的屏幕“像素”之前,就叫做片元

  2. 片元着色器的任务: 它的唯一核心任务就是“算颜色”。GPU 会对屏幕上准备显示的每一个片元,并行执行一次片元着色器程序。输入的是这个位置的坐标、纹理 UV、光照方向等,输出的则是这个位置的 RGBA 颜色值

形象的比喻: 顶点着色器是“画素描线稿的”,决定物体的骨架和形状在哪里; 片元着色器是**“上色的填色工”,决定每一个格子里该涂什么颜色、怎么画出高光、阴影和质感。

二、 顶点着色器的作用是什么?

当导入一个 FBX、OBJ 模型时,这个模型本质上是由成千上万个顶点(Vertex)数据组成的集合(包含每个点的 3D 坐标、法线、UV 坐标等)。

  • 运行机制: 顶点着色器(Vertex Shader)是流水线的第一步,每个顶点都会跑一次这个程序

  • 它的作用: 把模型在 3D 世界空间里的坐标,乘以各种矩阵,最终转换成在 2D 屏幕上的屏幕坐标。如果你在顶点着色器里对坐标加上噪声或者正弦波,模型就会发生形变(比如做旗帜飘动、草地随风摆动的效果)。

  • 传统游戏/材质包逻辑(FBX 骨架 + 材质): 用 FBX 模型提供山脉和河流的几何形状,Shader 只需要负责贴图和光照。

  • Shadertoy 逻辑(无模型,纯数学): 屏幕上其实只有一张由两个三角形组成的扁平正方形(Quad)。网页里看到的所有高山、峡谷、水流起伏,全都是在片元着色器里用数学公式(Raymarching 算法)凭空算出来的立体视觉错觉

Buffer

Buffer A / B / C / D(渲染缓存通道): * 这是多通道渲染(Multi-pass)的核心。常规的 Image 通道每帧画完就扔了。而如果你把 Buffer A 绑定到 iChannel0,就意味着 Image 通道可以读取上一帧 Buffer A 渲染出来的画面

  • 这在写需要“状态记忆”的特效(如流体模拟、烟雾扩散、动态模糊、全屏后处理面光源)时必不可少。

三、 什么是 Raymarching(光线步进)?

传统的渲染(如 Unreal Engine 或 Unity 的常规渲染)采用的是光栅化(Rasterization):把 3D 模型的三角形网格投射到 2D 屏幕上,然后对每个像素进行着色。

Raymarching 属于光线追踪(Ray Tracing)大家族的一种变体。它的核心思想是:对屏幕上的每一个像素,从摄像机发射出一条射线(Ray),这条射线不是通过复杂的数学公式直接去求交点(Classic Ray Tracing 的做法),而是像写代码走循环一样,沿着射线方向一步一步(Step by Step)向前走

根据步进方式的不同,它主要分为两种:

  1. 固定步长步进(Fixed Step):每走固定距离(比如 0.1 米)就采样一次。常用于渲染雾、云、烟等没有明确边界的体渲染(Volumetric Rendering)

  2. 球体追踪(Sphere Tracing / SDF Raymarching):利用符号距离函数(SDF, Signed Distance Function)。SDF 可以告诉你当前位置距离场景中最近的物体表面有多远。射线每次可以直接向前跨越这个“安全距离”,直到距离小于一个极小的阈值(比如 0.001),就判定为“命中”表面。

水体渲染实现方案对比(纯 Raymarching vs 传统光栅化管线)

渲染特性 / 维度Shadertoy (纯 Raymarching / 像素步进) 的做法传统光栅化 (如 Babylon.js / 工业引擎管线) 的做法
几何形状生成



(Geometry)
隐式数学表达 (Implicit Function)



无需显式 3D 模型。在 Fragment Shader 内通过数学公式(如多层正弦波、FFT 或噪声)定义高度场,通过射线循环步进计算出水面的高低起伏。
显式网格 + 纹理扰动 (Explicit Mesh)



场景中放置实际的平面网格(Grid Mesh)。通过 Vertex Shader 进行顶点位移(如 Gerstner 波),或在片元阶段使用法线贴图 (Normal Map) 扰动来表现波浪微细节。
交点/命中检测



(Intersection)
Shader 内手动求解 (Manual Traversal)



在片元着色器内运行 for/while 循环(如 Sphere Tracing),手动沿着视线方向推进,直到射线与水面函数的距离小于设定阈值。
硬件自动化处理 (Hardware Rasterized)



显卡固定管线自动进行三角形遍历、插值。在执行 Fragment Shader 之前,硬件已经确定了当前像素属于水面网格的哪一个位置。
折射与水深颜色



(Refraction & Absorption)
二次光线追踪 (Secondary Ray March)



命中水面后,根据斯涅尔定律(Snell’s Law)计算折射方向,射线继续向下 Marching 寻找与河床的交点。通过两点间的绝对距离,利用比尔-朗伯定律 (Beer-Lambert Law) 计算光线衰减与吸收。
全屏缓冲区抓取 (Buffer Sampling)



通过前置 Pass 渲染不透明物体,在水面 Shader 中读取场景深度图 (Depth Texture)不透明背景抓取纹理 (Opaque/Grab Texture)。利用 (SceneDepth - SurfaceDepth) 算出垂直水深,再套用吸光公式进行颜色混合。
反射与菲涅尔



(Reflection & Fresnel)
追踪虚拟天空 (Virtual Ray Tracing)



根据法线计算反射射线方向。由于没有其他物体模型,通常直接将该射线代入程序化天空光数学模型(或采样 Sky CubeMap),计算虚拟撞击点的天空颜色。



菲涅尔计算公式与光栅化完全一致。
多方案混合反射 (Multi-source Reflection)



直接采样预渲染的环境立方体贴图 (Cube Map)屏幕空间反射 (SSR) 或针对平坦水面的平面反射 (Planar Reflection)



利用菲涅尔公式(如 Schlick 近似法)动态插值反射色与折射色。
抗锯齿处理



(Anti-aliasing)
超采样抗锯齿 (SSAA)



由于纯数学边界极易产生噪点和锯齿,通常在 Shader 内部将单个像素拆分为多个子像素坐标(如 2x2 或 4x4 偏移),将整套 Raymarching 流程重复运行数遍后求平均值,计算开销极高。
管线级/后处理抗锯齿 (MSAA / TAA / FXAA)



依赖显卡硬件自带的多采样抗锯齿(MSAA)或引擎管线后处理阶段的临时抗锯齿(TAA)。水面片元着色器本身无需承担抗锯齿的循环计算开销。
性能特征与瓶颈



(Performance)
GPU ALU 密集型 (算力瓶颈)



完全不依赖显卡带宽和几何顶点,但对 GPU 的数学计算单元(ALU)消耗极大。当水面占据全屏或计算分支变多时,帧率会因密集循环而断崖式下跌。
带宽与材质填充瓶颈 (Pixel Fillrate)



计算开销相对平稳。主要瓶颈在于多 Pass 渲染时的显存带宽占用(读写深度图、抓取全屏纹理等),整体对各类硬件(包括移动端核显)的兼容性极好。