Appearance
水下视觉系统
系统概览
水下视觉系统(场景雾 + 焦散投影)。解决"水下视角直接看到地面"和"水底没有白蓝交替泳池光斑"两个体验问题。入水时给地面材质注入焦散 emissive(不依赖光照,天然附加水底光斑)并启用 scene.fog(LINEAR 蓝色),出水时按缓存还原。用户明确"不搞入水动画":所有切换即时无渐变。
核心职责
env-underwater-fog.ts— 水面穿越检测、地面材质焦散注入/还原、场景雾开关、雾色随天空色混合。
对外 API(节选)
underwaterFogController.setWaterLevel(level)— 通知水面 Y(env-impl 在state.waterLevel变化时调用)。underwaterFogController.install(mat)— 给地面材质注册水下修饰(幂等:同一 mat 只存一次,缓存原emissiveTexture/emissiveColor)。underwaterFogController.uninstall(mat)— 材质销毁前摘除注册条目(与install成对;applyTerrainMaterial/ 地面重建路径调用),避免update对已 dispose 材质写 emissive。underwaterFogController.update(dt, scene)— 每帧按相机 Y 与水面关系切换雾 + 焦散;受waterEnabled && underwaterEnabled门控,状态未变直接返回。underwaterFogController.reset(scene?)— 还原 emissive、关闭 fog、清空注册表。
注:
computeUnderwaterFogColor()为模块私有辅助函数(env-underwater-fog.ts:43无export),仅update内部调用,不列入对外 API。
与其他子系统关系
- 消费
env-caustics.ts(共享焦散纹理系统):getTexture注入地面emissiveTexture,并按envState.groundSize * CAUSTIC_WORLD_SCALE派生地面uScale/vScale(旧版写死常量 8 不随 groundSize 变,已改为世界空间锚定,与水面焦散同尺度)。 - 联动
env-water.ts(水面系统):setUnderwaterFog手动注入水面 ShaderMaterial(水面不参与 Babylonscene.fog)。 - 读取
envState.skyColorBot计算雾色。 - 被
env-impl.ts驱动:setWaterLevel+ 每帧update。
不变量
- 边界驱动:仅
isUnderwater翻转那一刻改材质/fogMode,绝不每帧赋值(否则 Babylon 因脏标记每帧重编译着色器)。 - 焦散动感来源:由
causticsController.update(dt)推进纹理uOffset(改 offset 不触发重编译),故update本身不推进动画。 - fogMode 语义:使用
FOGMODE_LINEAR,fogStart=40unit(4m)无雾阈值、fogEnd=500unit(50m)满雾阈值(坐标用 babymmd unit,1 unit=0.1m,见 AGENTS.md)。 - 还原安全:
reset/update出水分支按origEmissiveTex/origEmissiveColor还原,避免焦散 emissive 永久残留。