客户端视图渲染管线(CViewRender)
本页解释 client.dll 如何把“一帧画面”拆成若干个子视图(3D 天空盒、主世界、水面反射/折射、阴影深度、监视器等),每个视图内部按什么顺序绘制世界、不透明实体、半透明物体和视图模型,以及之后的后处理与 CS:GO 特有的全屏效果(烟雾、闪光、描边)。它是 渲染管线总览 中 View_Render → CViewRender::RenderView 一步的展开;引擎侧如何遍历 BSP、绘制世界表面见 引擎世界渲染。
相关页面:渲染管线总览 · 引擎世界渲染 · 材质系统与 Shader API · 模型、动画与粒子 · HUD 与 Scaleform UI · 投掷物与 C4
相关源码文件#
- 视图管线:
game/client/viewrender.cpp、game/client/viewrender.h - CS:GO 派生视图:
game/client/cstrike15/cs_view_scene.cpp - 后处理:
game/client/viewpostprocess.cpp、game/client/colorcorrectionmgr.cpp - 阴影:
game/client/c_env_cascade_light.cpp、game/client/clientshadowmgr.cpp - 不透明模型快速路径:
game/client/modelrendersystem.cpp - 描边与烟雾叠加:
game/client/glow_outline_effect.cpp、game/client/smoke_fog_overlay.cpp、game/client/cstrike15/clientmode_csnormal.cpp - 渲染目标:
game/client/baseclientrendertargets.cpp
1. 入口与“视图对象”模型#
哪一个 CViewRender:CS:GO 客户端的工程定义了 CSTRIKE_DLL(game/client/client_cstrike15.vpc:39),因此通用的 static CViewRender g_ViewRender 被条件编译排除(game/client/viewrender.cpp:1346-1352),GetViewRenderInstance() 返回 cs_view_scene.cpp 中的 CCSViewRender 单例(game/client/cstrike15/cs_view_scene.cpp:55-59)。CCSViewRender 只重写少数钩子(夜视、闪光、烟雾、2D 前后效果、玩家精灵),主流程仍是基类的 CViewRender::RenderView。
视图对象:每个子视图是一个 CRendering3dView 派生对象。AddViewToScene 把它交给 CSimpleRenderExecutor::AddView,后者立刻调用 pView->Draw(),并在前后 PushBuildView/PopBuildView(game/client/viewrender.h:625、game/client/viewrender.cpp:1332-1343)。也就是说,“添加视图”就是“同步绘制视图”,视图之间的先后顺序就是 AddViewToScene 的调用顺序;嵌套视图(例如水面视图内部的反射视图)在父视图 Draw() 中再次调用 AddViewToScene。
| 视图类 | 用途 | 创建位置 |
|---|---|---|
CSkyboxView | 3D 天空盒:参数取自本地玩家网络同步的 m_Local.m_skybox3d(area == 255 或 r_3dsky 0 时不画) | game/client/viewrender.cpp:3012-3017、game/client/viewrender.cpp:6946-6972、game/client/viewrender.cpp:6758-6778 |
CSimpleWorldView | 无昂贵水面时的主世界视图 | game/client/viewrender.cpp:3902-3904、game/client/viewrender.cpp:8201-8247 |
CAboveWaterView / CUnderWaterView | 能看到需要反射/折射的水时的主世界视图 | game/client/viewrender.cpp:3922-3934 |
CAboveWaterView::CReflectionView / CRefractionView / CIntersectionView | 水面反射、折射、视平面穿过水面时的补画 | game/client/viewrender.cpp:8384-8439 |
CReflectiveGlassView / CRefractiveGlassView | 视野中有反射玻璃时(仅 cheap water 分支) | game/client/viewrender.cpp:3890-3900 |
CShadowDepthView | 级联阴影 / 投影光的深度图 | game/client/viewrender.cpp:1929-1947 |
CFreezeFrameView | 冻结帧(死亡回放等)期间直接显示截图 | game/client/viewrender.cpp:2958-2966 |
2. RenderView 主流程#
证据(按图中顺序):
- 函数开头:DX 支持级别低于 95(非主机/非 OSX/非 GL)时打印“需要 SM3.0 与级联阴影”并直接返回:
game/client/viewrender.cpp:2921-2934;非 PS3 时初始化g_viewBuilder并ComputeAllBounds:game/client/viewrender.cpp:2945-2952。 - 冻结帧分支:
game/client/viewrender.cpp:2958-2966;否则绘制监视器(USE_MONITORS且cl_drawmonitors):game/client/viewrender.cpp:2971-2977。 SceneBegin、色彩校正、色调映射标量、SetupMain3DView(HDR 浮点时切到 HDR 后缓冲)、天空盒视图:game/client/viewrender.cpp:2981-3019、game/client/viewrender.cpp:2765-2783;视点位于CONTENTS_SOLID内时强制清颜色:game/client/viewrender.cpp:3021-3029。- 主场景
ViewDrawScene(..., VIEW_MAIN, ...)(PC 两遍或单遍,见第 4.4 节):game/client/viewrender.cpp:3114-3173;g_pIntroData存在时走ViewDrawScene_Intro:game/client/viewrender.cpp:3175-3185。 SceneEnd、DrawLights、RenderPlayerSprites:game/client/viewrender.cpp:3190-3202。- 景深、运动模糊(不在
building_cubemaps,且冻结帧截图时不做运动模糊):game/client/viewrender.cpp:3226-3250。 - 视图模型夹在两次烟雾叠加之间,然后水下叠加:
game/client/viewrender.cpp:3273-3277。 - 淡入淡出参数、烟雾雾叠加、屏幕叠加材质:
game/client/viewrender.cpp:3289-3301。 IRONSIGHT瞄准镜遮罩(CS:GO 在cs_shareddefs.h中定义该宏,game/shared/cstrike15/cs_shareddefs.h:47):game/client/viewrender.cpp:3325-3334。DoEnginePostProcessing(需m_bDoBloomAndToneMapping):game/client/viewrender.cpp:3336-3363;PC 上抓取色彩校正前的帧、屏幕空间效果、DoPostScreenSpaceEffects:game/client/viewrender.cpp:3383-3400。- 2D 阶段:
Push2DView、Render2DEffectsPreHUD、VGui 绘制、GetHud().LateThink()、Scaleform 槽位渲染、Render2DEffectsPostHUD:game/client/viewrender.cpp:3526-3597。 - 最后用
dev/clearalpha清 alpha 通道:game/client/viewrender.cpp:3599-3609,然后清理g_WorldListCache与g_viewBuilder:game/client/viewrender.cpp:3613-3614。
dev/clearalpha处的注释说明其目的:防止注入 Present 链的软件读取带 alpha 的缓冲区,从而推断烟雾中或烟雾后的玩家位置(game/client/viewrender.cpp:3599-3605)。这是注释陈述的设计意图,本 Wiki 未验证其效果。
3. 主场景:ViewDrawScene 与 DrawWorldAndEntities#
3.1 ViewDrawScene#
- 构建阶段调用
g_CascadeLightManager.PreRender()与g_pClientShadowMgr->PreRender();仅VIEW_MAIN且非法线缓冲时,先渲染级联阴影深度图与投影光深度图:game/client/viewrender.cpp:1981-1998。 - 烟雾全遮挡提前退出:若
m_flSmokeOverlayAmount >= 1,解锁阴影深度纹理后直接返回,不再绘制世界与实体:game/client/viewrender.cpp:2002-2015。该值由本帧稍后的RenderSmokeOverlay(true)更新(见第 7 节),因此这里读到的是上一帧的结果(推断,依据调用顺序game/client/viewrender.cpp:3071、game/client/viewrender.cpp:3273)。 SetupCurrentView、IGameSystem::PreRenderAllSystems、SetupVis(调用引擎ViewSetupVisEx,可见性计算见 引擎世界渲染 第 3 节):game/client/viewrender.cpp:2017-2029、game/client/viewrender.cpp:2583-2597。- 未画 3D 天空盒但径向可见性裁掉远平面时,用雾色清屏;有 3D 天空盒或天空不可见时不画 2D 天空盒:
game/client/viewrender.cpp:2031-2056。 DrawWorldAndEntities,之后关闭雾:game/client/viewrender.cpp:2063-2067。- 绘制阶段:
CGlowOverlay::DrawOverlays(光源光晕,例如太阳方向光,game/client/glow_overlay.h:49-59;与第 8 节的玩家描边无关)、像素可见性查询、降水、投影光体积雾、clienteffects->DrawEffects(注释说明这些效果“不与帧内其他内容排序”)、PostRenderAllSystems:game/client/viewrender.cpp:2070-2116。 - 收尾解锁阴影深度纹理、恢复剔除方向:
game/client/viewrender.cpp:2119-2139。
3.2 水面类型决定选择哪种世界视图#
DrawWorldAndEntities 先向引擎查询眼睛所在的可见雾体积(GetVisibleFogVolume),再由 DetermineWaterRenderInfo 决定水的代价等级:game/client/viewrender.cpp:3864-3883。
| 条件 | 结果 | 证据 |
|---|---|---|
| 无可见水体积或无水材质 | cheap water(默认),CSimpleWorldView | game/client/viewrender.cpp:3653-3668 |
mat_drawwater 0 | 不画水面 | game/client/viewrender.cpp:3671-3677 |
PC:未强制昂贵水(r_waterforceexpensive 默认 0 且材质无 $forceexpensive)或 r_WaterDrawReflection 0 | 不做局部反射 | game/client/viewrender.cpp:3735-3749、game/client/viewrender.cpp:210 |
距离超过 m_flCheapWaterEndDistance 且无局部反射,或 $forcecheap | 保持 cheap | game/client/viewrender.cpp:3767-3770 |
材质有 $refracttexture 且 r_WaterDrawRefraction | 折射 | game/client/viewrender.cpp:3773-3787 |
| 最终 | m_bCheapWater = !reflect && !refract | game/client/viewrender.cpp:3837 |
- cheap water:可能先加入反射/折射玻璃视图,再加入
CSimpleWorldView:game/client/viewrender.cpp:3885-3909。 - 否则按眼睛是否在水体积内选择
CAboveWaterView或CUnderWaterView:game/client/viewrender.cpp:3921-3934。CAboveWaterView::Draw先加入反射视图、再加入折射视图,然后绘制自身世界,最后视需要补画水面交叉视图:game/client/viewrender.cpp:8375-8440。反射视图期间会调用g_CascadeLightManager.BeginReflectionView/EndReflectionView:game/client/viewrender.cpp:8500、game/client/viewrender.cpp:8532。 - 反射/折射渲染目标
_rt_WaterReflection、_rt_WaterRefraction由客户端在渲染目标分配阶段创建(分配时机见 材质系统 第 6 节):game/client/baseclientrendertargets.cpp:41-47、game/client/baseclientrendertargets.cpp:72-79。
4. 单个世界视图内的绘制顺序#
所有世界视图都继承 CBaseWorldView,用 DrawSetup 构建列表、DrawExecute 绘制。例如 CSimpleWorldView::Draw 就是 DrawSetup → 设置雾 → DrawExecute:game/client/viewrender.cpp:8201-8237。
4.1 DrawSetup:构建列表#
非“简化世界模型”时:render->BeginUpdateLightmaps() → BuildWorldRenderLists(调用引擎 CreateWorldList / BuildWorldLists,可命中 g_WorldListCache)→ PruneWorldListInfo → 需要实体时 BuildRenderableRenderLists → render->EndUpdateLightmaps():game/client/viewrender.cpp:7837-7864、game/client/viewrender.cpp:4842-4928。实体列表由 SetupRenderablesListJob 调用 ClientLeafSystem()->BuildRenderablesList 收集(按可见叶子归集可渲染物):game/client/viewrender.cpp:4751-4755、game/client/viewrender.cpp:4757-4823。简化世界模型分支若不是“绘制实体 + 快速实体渲染”组合,会直接 Error:game/client/viewrender.cpp:7865-7881。
4.2 DrawExecute:绘制顺序#
| 顺序 | 操作 | 证据 |
|---|---|---|
| 0 | 可选 SSAO 深度预通道(mat_resolveFullFrameDepth == 2) | game/client/viewrender.cpp:7903-7909 |
| 1 | 等待世界列表作业完成;RTT 阴影纹理更新(ComputeShadowTextures,RTT 未激活时直接返回,CS:GO 即如此) | game/client/viewrender.cpp:7911-7921、game/client/clientshadowmgr.cpp:5898-5899 |
| 2 | 世界不透明几何(DF_SKIP_WORLD_DECALS_AND_OVERLAYS,即先不画贴花) | game/client/viewrender.cpp:7954-7955 |
| 3 | 等待可渲染物列表作业;不透明可渲染物 | game/client/viewrender.cpp:7958-7971 |
| 4 | 伪半透明水面(仅水面 sort group) | game/client/viewrender.cpp:7984-8004 |
| 5 | 世界贴花与覆盖层(DF_SKIP_WORLD,只画贴花/覆盖层/阴影) | game/client/viewrender.cpp:8006-8014 |
| 6 | 延迟的快速裁剪不透明物 → 半透明可渲染物 → 无 Z 缓冲半透明物;不画实体时只画半透明世界 | game/client/viewrender.cpp:8016-8032 |
| 7 | 子视图的像素可见性查询 | game/client/viewrender.cpp:8034-8038 |
第 2、5 步的区别由 BuildEngineDrawWorldListFlags 把客户端 DF_* 标志翻译成引擎 DRAWWORLDLISTS_* 标志实现:DF_SKIP_WORLD 去掉 DRAW_WORLD_GEOMETRY,DF_SKIP_WORLD_DECALS_AND_OVERLAYS 去掉 DRAW_DECALS_AND_OVERLAYS:game/client/viewrender.cpp:1054-1066。注释给出的理由是早期 Z 剔除收益以及避免主机 Z 预通道中动态顶点缓冲溢出:game/client/viewrender.cpp:8006-8008。DrawWorld 最终调用 render->DrawWorldLists;CSM 视图在“极低”质量下跳过位移面:game/client/viewrender.cpp:5181-5199。
4.3 不透明与半透明可渲染物#
DrawOpaqueRenderables 把不透明列表按模型类型分桶,然后依次:
- 画刷实体(非半透明组):
game/client/viewrender.cpp:5853-5867。 cl_modelfastpath(默认 1)开启时,把有IClientModelRenderable的实体与静态道具交给CModelRenderSystem::DrawModels批量绘制:game/client/viewrender.cpp:5878-5966、game/client/viewrender.cpp:5736-5753。快速路径内部的分桶、LOD、骨骼、flex、光照见 模型、动画与粒子 第 3 节。- 其余实体(慢速路径)、剩余静态道具(
staticpropmgr->DrawStaticProps)、NPC:game/client/viewrender.cpp:5980-5986、game/client/viewrender.cpp:5662-5694。 - 绳索与粒子渲染缓存(CSM 视图可按 ConVar 跳过绳索):
game/client/viewrender.cpp:5996-6018。
文档漂移:
cl_modelfastpath上方注释称该快速路径“在 css15 上不工作”、应在调查后再默认开启,但 ConVar 默认值为"1"(game/client/viewrender.cpp:5730-5733)。本 Wiki 以代码默认值为准,未验证运行效果。
半透明阶段:主视图在画半透明物之前把深度缓冲抓到全屏深度纹理(“不透明物写深度、半透明物通常不写”):game/client/viewrender.cpp:6366-6387。随后按世界列表的叶子从后往前交替绘制该叶子之前的半透明世界表面/细节道具和该叶子中的半透明实体:game/client/viewrender.cpp:6476-6500;需要帧缓冲拷贝的实体在水面 RT 中被跳过,否则先更新所需 RT:game/client/viewrender.cpp:6561-6568。
4.4 两遍构建/绘制与线程化#
- PC 默认
r_2PassBuildDraw 1:同一个ViewDrawScene调用树先以PASS_BUILDLISTS跑一遍(只执行BEGIN_2PASS_BUILD_BLOCK中的列表构建),刷新可渲染物作业,再以PASS_DRAWLISTS跑一遍绘制:game/client/viewrender.cpp:3126-3158、game/client/viewrender.cpp:367、game/client/viewrender.cpp:379-381。关闭时单遍同时构建和绘制:game/client/viewrender.cpp:3159-3170。 - 世界列表作业:
r_threaded_buildWRlist开启且处于线程化构建时,作业被串成SequentialJobs,在FlushBuildWorldListJob时投递线程池;否则当场Execute():game/client/viewrender.cpp:9674-9721。绘制阶段的SYNC_BUILDWORLD_JOB/SYNC_BUILDRENDERABLES_JOB宏等待作业完成并执行 epilogue:game/client/viewrender.cpp:387-409。 - PS3 有独立的 SPU 两遍路径,注释称其“仍在测试,不支持全部渲染路径(折射、正确的反射等)”:
game/client/viewrender.cpp:3044-3112。
设计含义(推断):两遍结构让 BSP 遍历与可渲染物归集在工作线程上与主线程的其他构建工作并行,绘制遍再按视图顺序同步取回结果。
5. 视图模型(手臂与武器)#
DrawViewModels 使用独立的近/远平面与 FOV(zNearViewmodel、zFarViewmodel、fovViewmodel)推入 3D 视图,并把深度范围压到 [0, 0.1] 以免武器穿墙:game/client/viewrender.cpp:1552-1581。列表由 ClientLeafSystem()->CollateViewModelRenderables 收集;不是 C_BaseViewModel 的可渲染物移到“普通 FOV”列表;IRONSIGHT 下视图模型可切换瞄准镜模板遮罩模式:game/client/viewrender.cpp:1583-1626。绘制期间调用 g_CascadeLightManager.BeginViewModelRendering/EndViewModelRendering:game/client/viewrender.cpp:1661、game/client/viewrender.cpp:1709。
6. 阴影:级联阴影为主,RTT 阴影被关闭#
| 机制 | 在 CS:GO 中的状态 | 证据 |
|---|---|---|
级联阴影(CSM,CCascadeLightManager) | 主要的动态阴影。硬件不支持 CSM/阴影深度纹理或 cl_csm_enabled 0 时自动关闭;质量模式变化时重建 RT;每帧更新主级联与视图模型级联状态,BeginGeneratingCSMs 后渲染各级联,最后把阴影状态交给材质系统 | game/client/c_env_cascade_light.cpp:1514-1557、game/client/c_env_cascade_light.cpp:1608-1613、game/client/c_env_cascade_light.cpp:1627-1654 |
| CSM 级联渲染 | 每级联一个子矩形视口,设置深度偏移、关闭剔除,m_bCSMView = true,通过 UpdateShadowDepthTexture 生成 CShadowDepthView | game/client/c_env_cascade_light.cpp:1321-1330、game/client/c_env_cascade_light.cpp:1394-1399、game/client/c_env_cascade_light.cpp:1457、game/client/viewrender.cpp:7281-7325 |
| 最大阴影距离 | 取 cl_csm_max_shadow_dist 或光源实体值;PC 高质量下乘 1.4;最终夹在 1–10000 | game/client/c_env_cascade_light.cpp:1573-1607 |
| 渲染到纹理(RTT)阴影 | #ifdef CSTRIKE15 下 bRenderToTextureActive 被强制为 false(注释:每张图都有 CSM) | game/client/clientshadowmgr.cpp:4336-4343 |
| 斑点(blobby)阴影更新 | r_disable_update_shadow 在 CS:GO 默认 1 | game/client/clientshadowmgr.cpp:114-119 |
| 投影光(flashlight)深度阴影 | 机制保留:ComputeShadowDepthTextures 为活跃投影光锁定深度纹理并渲染;纹理不足时告警并不绑定深度 | game/client/clientshadowmgr.cpp:5725-5788 |
引擎侧把 RTT 阴影/投影光投到世界表面的 shadowmgr 见 引擎世界渲染 第 9 节。
7. 后处理与屏幕效果链#
| 阶段 | 实现要点 | 证据 |
|---|---|---|
| 色彩校正权重 | 每帧重置权重 → 客户端模式与 color_correction 实体/体积写入权重 → 提交到渲染上下文(非独占权重乘 1 - 独占权重) | game/client/colorcorrectionmgr.cpp:198-216、game/client/colorcorrectionmgr.cpp:136-159 |
| 色调映射标量下发 | HDR 关闭时下发 1.0;mat_force_tonemap_scale 或覆盖值优先 | game/client/viewpostprocess.cpp:1317-1365 |
| 景深 / 运动模糊 | 在视图模型之前执行 | game/client/viewrender.cpp:3226-3250 |
DoEnginePostProcessing | r_queued_post_processing 时整段排入调用队列;先 DoTonemapping;mat_postprocess_enable 0 时到此为止 | game/client/viewpostprocess.cpp:2485-2549 |
| 动态色调映射 | 以 dev/lumcompare 材质 + 遮挡查询统计亮度直方图桶,计算目标标量并夹在自动曝光范围内 | game/client/viewpostprocess.cpp:2371-2392、game/client/viewpostprocess.cpp:568-600 |
| Bloom + 软件 AA + 色彩校正 | 合并为一次 dev/engine_post(分屏用 engine_post_splitscreen)全屏绘制;需要时先生成 8 位 bloom 纹理 | game/client/viewpostprocess.cpp:2603-2629、game/client/viewpostprocess.cpp:2693-2695、game/client/viewpostprocess.cpp:2769-2781 |
| 屏幕空间效果 | g_pScreenSpaceEffects->RenderEffects;Hammer 运行时跳过 | game/client/viewrender.cpp:1737-1746 |
| 后屏幕空间效果 | CS:GO 客户端模式在此渲染描边 | game/client/cstrike15/clientmode_csnormal.cpp:3537-3540 |
8. CS:GO 特有渲染#
烟雾遮罩(CCSViewRender::RenderSmokeOverlay):在 bPreViewModel 调用中,找离眼睛最近、且在阈值距离内的烟雾弹,用“带帽圆环体”内外阈值做线性插值得到目标不透明度,夹到 0–1:game/client/cstrike15/cs_view_scene.cpp:349-470。不透明度可以瞬间升高,但只能按 cl_smoke_lower_speed 匀速下降:game/client/cstrike15/cs_view_scene.cpp:482-487。绘制用 effects/overlaysmoke,视图模型前 alpha 为 amount*255,视图模型后为 amount*128:game/client/cstrike15/cs_view_scene.cpp:491-503。烟雾弹句柄列表由 AddSmokeGrenadeHandle 维护:game/client/cstrike15/c_cs_player.cpp:291-302。当不透明度达到 1 时主场景被整体跳过(第 3.1 节)。另有通用的 DrawSmokeFogOverlay(按全局 g_SmokeFogOverlayAlpha 画正交全屏四边形):game/client/smoke_fog_overlay.cpp:54-90。
闪光致盲(PerformFlashbangEffect,在 HUD 之后绘制,因此会盖住 HUD):观察者模式下使用被观察者的闪光状态并按模式降低 alpha(0.6 或 0.2):game/client/cstrike15/cs_view_scene.cpp:127-169。首次触发时把整个帧缓冲拷贝到 _rt_FullFrameFB1 作为“残影”截图,之后以 effects/flashbang 叠加 4 次,再叠加纯白 effects/flashbang_white:game/client/cstrike15/cs_view_scene.cpp:190-253。调用位置:game/client/cstrike15/cs_view_scene.cpp:520-522。
夜视在 HUD 之前绘制(注释:否则会冲淡 HUD):game/client/cstrike15/cs_view_scene.cpp:511-514。HLTV 回放在 HUD 后用 dev/replay 像素着色器或 dev/replay_bars 淡入淡出:game/client/cstrike15/cs_view_scene.cpp:524-576。
玩家描边(glow):C_CSPlayer::UpdateGlows 依优先级尝试 GlowEffectHLTVReplay、GlowEffectSensorGrenade(感应手雷)、GlowEffectGunGameLeader、GlowEffectSpectator,第一个命中的决定是否渲染、颜色与样式:game/client/cstrike15/c_cs_player.cpp:3521-3555。渲染在 DoPostScreenSpaceEffects 中由 CGlowObjectManager::RenderGlowEffects 完成(glow_outline_effect_enable 控制):game/client/glow_outline_effect.cpp:34-46;先用 dev/glow_color 覆盖材质把对象画成纯色到全帧 RT,再模糊并叠加回帧缓冲(注释):game/client/glow_outline_effect.cpp:106-139。
9. 监视器 / RT 相机#
USE_MONITORS 在 CSTRIKE_DLL 下启用(game/client/viewrender.cpp:67-69)。DrawMonitors 遍历活跃、非休眠的 C_PointCamera,逐个 DrawOneMonitor 渲染到 _rt_Camera:game/client/viewrender.cpp:4535-4566。_rt_Camera 在 CS:GO 的 PS3 构建中不分配:game/client/baseclientrendertargets.cpp:120-127、game/client/baseclientrendertargets.cpp:83-93。
约束与边界#
- 不变量:
AddViewToScene同步绘制,视图顺序即调用顺序(game/client/viewrender.cpp:1332-1343);阴影深度纹理在主视图结束时必须解锁,烟雾提前退出路径也会解锁(game/client/viewrender.cpp:2005-2014、game/client/viewrender.cpp:2122-2129)。 - 失败路径:DX 级别 < 95 的 PC 不渲染 3D(
game/client/viewrender.cpp:2921-2934);投影光深度纹理不足时该光源无阴影(game/client/clientshadowmgr.cpp:5769-5788);简化世界模型配置不匹配时Error(game/client/viewrender.cpp:7879)。 - 条件编译:
_PS3SPU 两遍路径、_X360GPR 分配与 EDRAM 清除、PORTAL门户递归、IRONSIGHT、USE_MONITORS、INCLUDE_SCALEFORM均改变流程;本页以 PC Windows 的CSTRIKE15/CSTRIKE_DLL配置为主线。 - 未展开:景深与运动模糊着色器细节、
ViewDrawScene_Intro、CFreezeFrameView内部、细节道具系统(DetailObjectSystem)、ClientLeafSystem的叶子归集与渲染距离淡出、CDebugViewRender调试视图、SFM 法线缓冲路径(m_bDrawWorldNormal)、各 Shader 的具体实现。 - 本页所有顺序结论来自静态阅读;未在运行中抓帧验证。