恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

大场景视距裁剪与 Hi-Z 遮挡剔除在移动端的实操与优化

  • 首页
  • 资讯中心
  • /
  • 大场景视距裁剪与 Hi-Z 遮挡剔除在移动端的实操与优化

相关资讯

Onivim 2 按键绑定(Key Bindings)配置完全指南:keybindings.json 格式、when 条件上下文与命令参考 2026/9/27 8:24:07
NoneBot2 跨插件访问与依赖声明:深入理解 require 机制与插件加载时序 2026/9/27 8:24:07
如何攻击Wordpress站点常见报错与解决 2026/9/27 8:24:07

最新资讯

基于 Ubuntu 18.04 LTS 嵌入式 Linux 系统部署指南
哈尔滨做网站多少钱?避开性能优化坑,这5步省钱又省心
vercel-optimize - scoring
3步搞定wordpress自动视频播放器,源码下载避坑全攻略
怎么自己做H5网站不踩坑,附最佳实践全流程
一键开关机芯片选型指南:从闩锁逻辑到静态功耗

今日推荐

从像素到笔画:srt-whiteboard-animation骨架笔迹追踪实现(Zhang-Suen细化+8邻接追踪)
网站建设的英语怎么说?别只背单词,看完这套安全完整流程才敢上线
新手入门看这篇:建设网站加盟避坑指南与SEO实操

本周热门

从像素到笔画:srt-whiteboard-animation骨架笔迹追踪实现(Zhang-Suen细化+8邻接追踪)
网站建设的英语怎么说?别只背单词,看完这套安全完整流程才敢上线
新手入门看这篇:建设网站加盟避坑指南与SEO实操

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

大场景视距裁剪与 Hi-Z 遮挡剔除在移动端的实操与优化

发布时间:2026/9/27 8:29:08
大场景视距裁剪与 Hi-Z 遮挡剔除在移动端的实操与优化 大场景视距裁剪与 Hi-Z 遮挡剔除在移动端的实操与优化在开放世界大场景游戏中仅靠视锥体裁剪Frustum Culling已无法遏制渲染几何负载的膨胀。当玩家站在山谷或城镇街道中央时视野前方虽然包含了数万个建筑、植被和道具但其中超过 70% 的物体实际上完全被前方的大山或临街城墙遮挡。如果将这些完全不可见的物体依然送入渲染管线会产生巨量的顶点吞吐浪费与无效的 Early-Z 深度测试开销。层次深度缓冲Hierarchical Z-Buffer, Hi-Z遮挡剔除利用上一帧生成的深度金字塔Depth Pyramid在 GPU Compute Shader 中对候选包围盒AABB进行快速保守可见性测试结合 GPU Driven 渲染架构的间接绘制DrawMeshInstancedIndirect可以在移动端将 Draw Call 与顶点处理压力削减 60% 以上。Hi-Z 遮挡剔除工作流与原理解析Hi-Z 的核心思想是构建一个类似 Mipmap 的深度纹理金字塔。在标准纹理采样中Mipmap 生成采用平均值Average Downsampling但在 Hi-Z 深度金字塔中每个降采样像素必须取其对应的 4 个子像素的最大深度值在 Reverse-Z 规范下为最小深度值代表最靠近相机的表面以确保遮挡判定的严格保守性Conservative Testing。[原始深度缓冲 (Depth Pre-Pass)] │ ▼ (Max/Min 降采样构建 Mipmap 链) [Hi-Z 深度金字塔 (1/2, 1/4, 1/8, 1/16, ...)] │ ▼ (在 Compute Shader 中输入候选包围盒 AABB) ┌──────────────────────────────────────────────┐ │ 1. 视锥体相交测试 (Frustum Test) │ │ 2. 计算 AABB 屏幕空间包围矩形与对应 Mip 级别 │ │ 3. 采样 Hi-Z 金字塔深度并与 AABB 最近深度比对 │ └──────────────────────────────────────────────┘ │ ▼ (通过测试的实例写入 Culled Instance Buffer) [DrawMeshInstancedIndirect 间接绘制命令触发]移动端 Hi-Z Compute Shader 核心实现以下是基于 HLSL 实现的 GPU 实例剔除着色器代码支持 Reverse-Z 模式#pragma kernel CSMain struct InstanceData { float4x4 objectToWorld; float3 boundsCenter; float3 boundsExtents; }; StructuredBufferInstanceData _InstanceBuffer; AppendStructuredBufferuint _VisibleInstanceArgsBuffer; Texture2Dfloat _HiZDepthTexture; SamplerState sampler_HiZDepthTexture; float4x4 _ViewProjectionMatrix; float4 _CameraPositionWS; float4 _HiZTextureSize; // (Width, Height, 1/Width, 1/Height) float _MaxDrawDistance; // 判断 AABB 是否在视锥体外部 bool IsOutsideFrustum(float3 center, float3 extents) { // 标准 6 个视锥平面的快速点积判别 // 此处省略 6 平面判别循环返回 true 表示在视野外 return false; } [numthreads(64, 1, 1)] void CSMain(uint3 id : SV_DispatchThreadID) { uint instanceIndex id.x; InstanceData inst _InstanceBuffer[instanceIndex]; float3 centerWS mul(inst.objectToWorld, float4(inst.boundsCenter, 1.0)).xyz; float distToCamera distance(_CameraPositionWS.xyz, centerWS); // 1. 距离裁剪 if (distToCamera _MaxDrawDistance) return; // 2. 视锥体裁剪 if (IsOutsideFrustum(centerWS, inst.boundsExtents)) return; // 3. 计算 AABB 在屏幕空间的投影像素范围 float3 minWS centerWS - inst.boundsExtents; float3 maxWS centerWS inst.boundsExtents; float3 boxCorners[8] { float3(minWS.x, minWS.y, minWS.z), float3(maxWS.x, minWS.y, minWS.z), float3(minWS.x, maxWS.y, minWS.z), float3(maxWS.x, maxWS.y, minWS.z), float3(minWS.x, minWS.y, maxWS.z), float3(maxWS.x, minWS.y, maxWS.z), float3(minWS.x, maxWS.y, maxWS.z), float3(maxWS.x, maxWS.y, maxWS.z) }; float2 minScreen float2(1.0, 1.0); float2 maxScreen float2(-1.0, -1.0); float nearestDepth 0.0; // Reverse-Z: 1.0 为近平面, 0.0 为远平面 [unroll] for (int i 0; i 8; i) { float4 clipPos mul(_ViewProjectionMatrix, float4(boxCorners[i], 1.0)); float3 ndc clipPos.xyz / clipPos.w; minScreen min(minScreen, ndc.xy); maxScreen max(maxScreen, ndc.xy); nearestDepth max(nearestDepth, ndc.z); // 找到离相机最近的深度 } // 映射到 [0, 1] 纹理坐标空间 float2 minUV saturate(minScreen * 0.5 0.5); float2 maxUV saturate(maxScreen * 0.5 0.5); float2 uvSize (maxUV - minUV) * _HiZTextureSize.xy; // 根据包围盒像素占位计算最佳采样 Mip 级别 float maxDim max(uvSize.x, uvSize.y); float mipLevel ceil(log2(max(maxDim, 1.0))); // 采样 Hi-Z 金字塔的 4 个脚点深度 float4 depthSamples; depthSamples.x _HiZDepthTexture.SampleLevel(sampler_HiZDepthTexture, minUV, mipLevel).r; depthSamples.y _HiZDepthTexture.SampleLevel(sampler_HiZDepthTexture, maxUV, mipLevel).r; depthSamples.z _HiZDepthTexture.SampleLevel(sampler_HiZDepthTexture, float2(minUV.x, maxUV.y), mipLevel).r; depthSamples.w _HiZDepthTexture.SampleLevel(sampler_HiZDepthTexture, float2(maxUV.x, minUV.y), mipLevel).r; // 在 Reverse-Z 下如果 Hi-Z 记录的最小深度大于等于物体的最近深度说明被完全挡住 float maxOccluderDepth min(min(depthSamples.x, depthSamples.y), min(depthSamples.z, depthSamples.w)); if (nearestDepth maxOccluderDepth) { // 可见压入间接绘制索引缓冲 _VisibleInstanceArgsBuffer.Append(instanceIndex); } }移动端TBDR工程落地的关键避坑上一帧深度缓冲的滞后性Temporal Reprojection直接使用上一帧生成的 Hi-Z 进行当前帧裁剪时快速转动视角会导致视野边缘物体出现 1 帧的“闪烁空洞”。必须使用上一帧的 ViewProjection 矩阵逆变换重新投影 AABB或者对画面边缘区域的包围盒适当外扩Padding。TBDR 深度解析开销Depth Resolve在移动端 Mali / Adreno 架构上将 On-Chip Tile Memory 中的 Depth Buffer 拷贝到系统内存Resolve会消耗显存带宽。建议将 Hi-Z 金字塔的生成放在不透明物体渲染之后的低分辨率拷贝 Pass 中限制金字塔尺寸为 512x256既能保证剔除精度又极大节省下采样带宽。两阶段剔除Two-Phase Culling对于动态移动的物体第一阶段使用上一帧 Hi-Z 进行保守裁剪并绘制已知可见物体第二阶段在完成主要遮挡物绘制后对第一阶段被剔除的疑似可见物体进行二次测试彻底杜绝闪烁。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号