渲染组织、材质与着色器
范围:renderer/、shaders/、shader_source/。分析游戏侧渲染策略;图形设备后端属于 RAGE。总入口:Summary。
1. 架构主线#
GTA 的游戏渲染层把世界扫描结果转为按 pass/bucket 分类的绘制列表,再通过不同 RenderPhase 组织主视图、阴影、反射、水面、雷达和效果。Deferred/GBuffer、DeferredLighting 与 forward/alpha 路径并存,构成混合渲染组织。
不能把它简单描述为“所有物体都走 deferred”。RenderListBuilder 明确有 opaque、decal、alpha、mirror alpha、displacement alpha、water 等 pass 表;材质、透明性和特殊效果决定去向。某个平台或设置下启用哪些阶段,需要沿 viewport/phase 构造和宏判断。
2. 从世界到 GPU 的职责链#
这是逻辑数据依赖,不是固定 GPU pass 顺序。实际阴影、反射及后处理的安排以 RenderPhase 实现为准,可能有平台专用优化。
CApp 在渲染线程 Synchronise 之后调用 CGame::Render,调用点说明其主要构建 draw lists 与 contexts。游戏线程准备、渲染线程执行与 GPU 完成存在阶段差,不能在构建列表之后立即释放列表引用的资源。
3. 扫描、可见性与列表构建#
GameScan 构造可见性参数并提前启动 jobs,PostScan 消费 PVS;renderer 内还有 occlusion、OcclusionQueries、SortPVSAsync 和异步灯光可见性处理。PVS 是候选/处理数据的一部分,具体遮挡、LOD 和 pass 筛选还会进一步决定最终绘制。
RenderListBuilder 的表中同时指定 render pass、bucket、允许 draw modes、filter、exclusion filter 和 render mode mapping。这是用数据表统一组织材质分类的方式:新增材质模式时,不只要写 shader,还要保证它被正确分派到所需 pass。
对象“不见了”应依次核查实体可见性、资源、LOD、扫描/遮挡、bucket/filter、shader 和目标缓冲,而不是直接修改 shader 输出。错误的 pass 分派也可能让物体只在反射或阴影中出现。
4. Deferred、目标缓冲与辅助视图#
GBuffer 封装多个颜色目标和深度目标,提供 lock、depth copy/restore,以及特定平台的 alternate/tiled target 逻辑。图形资源并不只是一组固定纹理指针;平台、MSAA 和阶段可能改变访问形式。
CRenderTargetMgr 负责创建与按名称管理 render target,释放接口包含 owner tag,表明命名目标有使用者归属。界面、脚本和世界中的屏幕可以共享目标管理设施,但不能因为名字相同就任意释放其他使用者的资源。
RenderPhase 目录独立实现 cascaded shadows、paraboloid shadows、mirror reflection、water reflection、radar、height map、ped damage 等。每个辅助视图可能有不同的裁剪、LOD、分辨率与对象筛选,增加效果质量也会增加额外世界扫描和绘制成本。
5. CPU 材质适配与 GPU 源码#
shaders/ 是 C++ 的 ShaderLib 和 CustomShaderEffect 系列,负责 Ped、Vehicle、Weapon、Grass、Tree、Interior、Mirror 等游戏材质的运行时接入;shader_source/ 则包含 .fx/.fxh 源码与其工程描述。二者不是重复目录。
shader 源码包括水面、天空、tiled lighting 等专用部分;C++ 负责向它们提供纹理、常量和对象特定状态。改变 shader 参数布局时,需要同步核对 CPU 绑定与平台变体,不能只修改一份 .fx。
当前可确认有 tiled lighting 相关源文件,但仅凭文件存在不能断言所有硬件与配置都采用同一 tiled/compute 路径,也不能将当前目录推断为某一现代 API 的 render graph 系统。
6. 后处理与大量细节系统#
PostProcessFX、AdaptiveDOF、SSAO、MLAA、LensArtefacts、Water、PlantsMgr、PlantsGrassRenderer、TreeImposters 分别承载屏幕效果、水和植被相关策略。低成本远景表示、异步更新和专用渲染路径让巨大场景可控,但资源与质量设置必须协调。
TimeCycle 和摄像机提供环境、曝光/外观及镜头相关参数。相同材质在不同时刻、区域、镜头与后处理下表现不同,分析颜色问题应先区分材质输入与最终合成结果。
部分旧平台文件使用 SPU、fragment/job 形式;代码中还保留多代硬件分支。它们是历史与平台实现证据,不能解释成所有平台同时执行这些工作。
7. 性能分析应拆成四层#
| 层次 | 主要观察量 |
|---|---|
| 世界准备 | 扫描对象数、LOD、遮挡、PreRender 和异步等待 |
| CPU 提交 | 列表构建、排序、bucket 数、材质状态变化、同步点 |
| GPU | 各视图/阶段耗时、几何与像素成本、透明 overdraw、阴影/反射 |
| 资源 | render target 占用、纹理/几何 streaming、跨帧生命周期 |
源码中的 profiler 预算不是实测值。本报告没有执行 shader 编译、图形捕获或基准测试,不给出未经测量的帧率与瓶颈排名。
8. 源码依据#
| 源码 | 重点 |
|---|---|
| Renderer.cpp | 总体初始化与各渲染组件 |
| RenderListBuilder.cpp | pass/bucket/filter 表 |
| RenderPhaseStd.cpp | 标准场景阶段与命令组织 |
| GBuffer.h | 缓冲与平台访问差异 |
| RenderTargetMgr.h | 命名目标、owner tag、释放 |
| RenderThread.h | 游戏侧渲染线程接口 |
| ShaderLib.h | C++ shader 管理入口 |