12.2 透视校正插值
顶点上的 UV 直接线性插值到像素是错的:透视投影下屏幕坐标是 x/w,属性在屏幕空间不再线性。正确做法是插值 u/w 与 1/w 再相除。本节在一块近远端 w 相差 2.57 倍的后仰四边形上把两条路径都跑一遍,量出 1923 个像素不同、最大通道偏差 180,再让 WebGL2 用同一份场景复现。
category
顶点上的 UV 直接线性插值到像素是错的:透视投影下屏幕坐标是 x/w,属性在屏幕空间不再线性。正确做法是插值 u/w 与 1/w 再相除。本节在一块近远端 w 相差 2.57 倍的后仰四边形上把两条路径都跑一遍,量出 1923 个像素不同、最大通道偏差 180,再让 WebGL2 用同一份场景复现。
纹理在显存里是一张二维表,UV 就是把这张表贴到三角形上的那套坐标。本节把 uv 也做成 Q16.16 定点数,用整数移位把连续坐标落到具体 texel,并实现 repeat / clamp / mirror 三种寻址——它们分别是位与、钳位与向下取整的模。纹理不引入任何第三方素材,由整数棋盘与渐变程序化生成。
MSAA 只在覆盖上多采样、着色一次。本节用 8 片带深度的叶片,把每像素 4 个子样本各自做覆盖与深度测试再按覆盖平均的 CPU 实现写出来,并让浏览器 WebGL2 用 4 遍平移渲染做同一件事,按 MAE/PSNR/覆盖归属三条容差判据对上,且负例必被拒绝。
把像素切成 N×N 个小格,覆盖率就是落在三角形内的子样本数——0 到 N² 的整数计数。本节用一个斜边三角形,把 2×2 与 4×4 超采样的覆盖率、整数颜色混合与误差随 N 的下降全部写成可断言整数,并与 TypeScript 逐字节对齐。
渲染的本质是把连续场景采样成离散像素。本节用 256×256 的整数波带片与周期 3 斜条纹,把「点采样把高频折回低频」的走样复现出来,再用整数方差把摩尔纹量成可断言的数字;Nyquist 边界上周期 2 的条纹会塌成一个常数,判据在 Python 与 TypeScript 间逐字节复现。
深度缓冲内部只有 65537 个刻度,一个刻度值多少世界距离却随距离按 D² 增长。本节从 5.3 的相机量程视角切回缓冲内部,量化 Q16.16 的最小可分辨深度差、塌陷距离与误差传播,再看逐像素定点插值的截断误差如何沿距离放大,并让 Python 与 TypeScript 两份实现逐字节对齐。
1.1 的脚本能用,但四步糊在一个 main 里。本节把它重构成规格、几何、屏幕坐标、像素四段,每段一个有名字、可单独调用的函数,再串起来渲染《烛影山谷》的第一帧并逐段计时;同时说明 S 层与 P 层如何共用同一份规格,做到像素缓冲逐字节相同。
config/scene_spec.json 有 31 个必填字段,分布在渲染参数、相机、两盏光源、地形与球体五组里。本节逐组讲清每个字段的量纲与取值范围,给出纯 Python 的 schema 校验脚本,断言所有数值字段都是整数、Q16.16 落在安全区间内,并用一份被污染的规格证明这套判据会拒绝它。
渲染一帧到底发生了什么?本节把整条链路压成顶点变换、三角形组装、光栅化、逐像素着色四步,用一份 config/scene_spec.json 跑出 487 顶点、896 三角形、43731 个覆盖像素并落盘一张 PNG;每一步都只用整数与定点,为后面三种宿主消费同一份规格打下地基。
《计算机图形学》卷一《几何、变换与光栅化》目录:16 章 48 节,把渲染从 API 调用还原成可算的整数——Q16.16 定点顶点变换、整数边函数覆盖判定、定点重心插值、深度缓冲、裁剪、抗锯齿与纹理映射全部定点实现,让 Python 与 TypeScript 产出逐字节相同的 PNG。本页给出与站内既有内容的分工、六档可运行性口径、《烛影山谷》场景总览与全书 16 章 48 节完整清单。
移动 GPU 与桌面 GPU 的架构差异巨大:TBDR 把屏幕分块、用片上内存完成像素处理,使得「带宽」而非「算力」成为第一瓶颈,同时散热与电池又给持续性能套上枷锁。本文从 TBDR 架构讲起,剖析带宽拆解与纹理压缩、Overdraw 与 Early-Z、动态分辨率与可变速率着色,并给出功耗与热节流的治理策略和一份可执行的优化清单。
符号距离场(SDF)用「到最近表面的有符号距离」隐式地描述几何体,天然支持光滑布尔运算、无网格变形与解析求交。本文从 SDF 的定义与组合运算讲起,剖析 Raymarching 球体追踪求交、网格到 SDF 的烘焙算法与存储格式,并覆盖它在字体渲染、软阴影、全局光照与碰撞检测中的落地,最后给出性能与精度权衡。
当场景有上百个动态光源时,传统前向渲染要为每个物体遍历全部光源,延迟渲染又受限于 G-Buffer 带宽与透明度处理。集群前向渲染(Clustered Forward / Forward+)把视锥切成三维簇,为每个簇预计算光源列表,让着色时只遍历真正影响该片元的光源。本文讲解 Tiled 分桶、Clustered 三维切分、光源分配数据结构与着色阶段查找,并给出性能取舍。
着色器不是直接丢给 GPU 执行的源码,而要经过预处理、解析、语义分析、优化、生成中间表示、再翻译成各平台后端代码的完整链路。本文拆解 SPIR-V 中间表示的结构与反汇编方法,讲解 glslang/DXC/glslc 离线编译工具、SPIRV-Cross 跨后端翻译、运行时管线缓存与变体管理,以及 WebGPU 通过 Naga 走 WGSL 的另一条路径。
渲染性能优化不能靠猜:必须先用工具定位是 CPU 瓶颈还是 GPU 瓶颈,再细分到填充率、带宽、占用率还是延迟。本文梳理 GPU 剖析与调试的完整工具链,覆盖 RenderDoc/PIX/Nsight 帧捕获、硬件计数器与带宽计算、时间线与异步队列分析、校验层与着色器调试,以及如何在引擎里内置可剖析的 GPU 计时与统计 HUD。
渲染图(Render Graph)把一帧的渲染流程抽象成 Pass 与资源的依赖图,由框架自动推导屏障、管理瞬态资源生命周期、做内存别名复用并调度异步计算队列。本文从手工管线的痛点讲起,剖析资源抽象、依赖推导、屏障生成、瞬态内存别名与帧调度机制,并对比 Unreal RDG、Unity SRP 与 Frostbite FrameGraph 的落地差异。
物理与渲染是两条频率、精度、目标都不同的时间线,把它们正确缝合是游戏引擎的核心难题。本文讲解刚体动力学与碰撞检测的两阶段流程、固定步长累加器与渲染插值/外推、角色控制器的扫掠与滑动处理、布料与绳索的 PBD/XPBD 约束求解、确定性与网络回滚同步,以及物理与渲染解耦的 ECS 架构设计,给出避免抖动、穿透与回滚错位的完整工程方案。
色彩管线决定了画面「看起来对不对」。本文讲解 sRGB 传输函数与 Gamma 的由来、线性工作流的必要性、HDR 渲染与色调映射(Reinhard/Filmic/ACES)、宽色域与 Display P3 的落地、曝光与自动曝光系统,以及色彩管线在游戏引擎中的组织方式与常见踩坑,给出端到端可落地的色彩管理方案。
渲染性能的第一性原理是「不画看不见的东西」。本文系统讲解可见性剔除体系:视锥剔除的六平面测试与包围体、BVH/Octree 空间加速结构的构建与遍历、Hi-Z 遮挡剔除的层次深度金字塔与两阶段剔除、GPU Driven 剔除的计算着色器实现与原子压缩、实例化与间接绘制,以及剔除与 LOD 的协同与滞后策略,并给出完整的工程落地方案。
粒子特效是游戏中最常见也最吃性能的效果之一。本文对比 CPU 与 GPU 粒子的适用场景,讲解计算着色器模拟、Transform Feedback 与顶点着色器方案、粒子数据的 SoA/AoS 内存布局、半透明排序与混合策略,剖析 UE Niagara 与 Unity VFX Graph 的架构思路,并给出十万级粒子的性能优化清单与间接绘制方案。