Rerun 2D 图层叠放控制指南:DrawOrder 组件的语义、编码与渲染原理 Rerun 2D 图层叠放控制指南DrawOrder 组件的语义、编码与渲染原理【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun导读在 Rerun 的二维视图中如Spatial2DView多个实体常常会互相遮挡标注框要盖在图像上、点云要浮在底图上、分割结果要与原图叠加。DrawOrder组件就是 Rerun 为这类 2D 场景提供的层叠顺序控制机制——值越大绘制得越靠上。本文以 Rerun 官方类型文档 draw_order.md 为主体结合仓库中的类型定义、渲染上下文系统与测试用例系统讲解该组件的语义约定、数据编码、三语言 SDK 用法以及从DrawOrder到最终深度偏移DepthOffset的底层实现原理帮助你精确编排 2D 可视化中的图层关系。核心语义数值越大越靠上层DrawOrder的官方定义非常明确2D 元素的绘制顺序。值越高的元素绘制在值越低的元素之上Draw order of 2D elements. Higher values are drawn on top of lower values.在 crates/build/re_type_definitions/rerun/components/draw_order.def.rs 的类型定义文件中这一段语义被原样保留并额外标注了三条重要的使用约束一个实体只能有一个 draw order 组件An entity can have only a single draw order component实体内部即同一实体内多个可视化层之间的绘制顺序由组件顺序决定Within an entity draw order is governed by the order of the components拥有相同 draw order 值的实体之间先后顺序一般是未定义的Draw order for entities with the same draw order is generally undefined。这三点意味着DrawOrder适合用来做实体之间不同 Entity Path 之间的明确分层如果希望精确控制同层实体的遮挡关系需要为它们分配不同的数值而不能依赖相等值时的内部顺序。类型定义与数据编码Rerun 编码Float32DrawOrder在 Rerun 侧的数据编码为单精度 32 位 IEEE 754 浮点数Float32即一个普通的f32标量。在 Arrow 序列化层面其 datatype 同样直接映射为Float32三语言绑定同一份定义三种生成产物该组件不是手写代码而是由re_types_builder从draw_order.def.rs这一个类型定义源自动生成 Rust、Python 与 C 三套绑定def 文件头部注释明确说明It is parsed byre_types_builderto generate the Rust, Python and C bindings。Rust在 crates/store/re_sdk_types/src/components/draw_order.rs 中DrawOrder被实现为一个#[repr(transparent)]的元组结构体pub struct DrawOrder(pub crate::encodings::Float32)组件类型名为rerun.components.DrawOrder。它实现了Deref/DerefMut可直接当作Float32使用以及FromT: IntoFloat32因此可以用任意可转换为Float32的值直接构造。Python在 rerun_py/rerun_sdk/rerun/components/draw_order.py 中DrawOrder直接继承自encodings.Float32并组合ComponentMixin类型定义中的#[python(aliases float)]与#[python(array_aliases float | npt.NDArray[np.float32])]注解见 draw_order.def.rs意味着 Python 侧既可以传普通float也可以传numpy的float32数组。C同样由该 def 文件生成rerun::components::DrawOrder用法与 Rust 侧一致通过构造器传入一个浮点值。另外def 文件中标注了#[rerun(state stable)]说明DrawOrder属于稳定 API可以放心在长期项目中依赖。支持 DrawOrder 的 2D 原型Archetype全览根据原文档的 Used by 列表共有 13 个 archetype 支持DrawOrder在各自文档中均作为可选字段draw_order出现例如 Image、Points2D、Boxes2DArchetype说明典型叠加场景Image单色/彩色图像作为底图值最小EncodedImage压缩图像JPEG/PNG作为底图或覆盖层DepthImage/EncodedDepthImage深度图像与其他 2D 标注叠加SegmentationImage分割图像半透明叠加在底图上GridMap栅格地图数据地图与路径/点位叠加Points2D2D 点云标注点盖在图像之上Boxes2D2D 矩形框检测框盖在图像/点上LineStrips2D2D 折线轨迹线覆盖底图Ellipses2D2D 椭圆高亮/区域标注Arrows2D2D 箭头方向标注如光流VideoFrameReference/VideoStream视频帧引用与视频流视频画面上叠加标注需要注意的是DrawOrder只对2D 元素生效文档措辞为 Draw order of 2D elements。虽然在Spatial3DView中这些 2D archetype 若挂载在投影projection下也可以显示见各 archetype 文档的 Can be shown in但层叠优先级主要由DepthOffset机制换算处理详见下文。实战在 SDK 中设置 draw_orderPython 示例在 Python SDK 中draw_order是各 archetype 构造器的关键字参数。以 Points2DExt 为例其参数文档明确写着An optional floating point value that specifies the 2D drawing order. Objects with higher values are drawn on top of those with lower values.可选的浮点值用于指定 2D 绘制顺序值越高的对象绘制在值越低的对象之上。import rerun as rr rr.init(draw_order_demo, spawnTrue) # 1) 底层一张底图draw_order 0.0 rr.log(scene/background, rr.Image(..., draw_order0.0)) # 2) 中层检测框draw_order 10.0盖在底图之上 rr.log( scene/detections, rr.Boxes2D( centers[(320.0, 240.0), (100.0, 100.0)], half_sizes[(120.0, 60.0), (40.0, 40.0)], draw_order10.0, # 比底图大即可 ), ) # 3) 顶层关键点draw_order 20.0盖在框之上 rr.log( scene/keypoints, rr.Points2D( positions[(320.0, 240.0)], colors[(255, 0, 0)], draw_order20.0, ), )由于DrawOrder是Float32浮点标量取值可以任意正负、小数均可只要相互之间有大小区分即可为便于维护建议按 10 的倍数预留档位方便日后插入新图层。Rust 示例Rust 侧使用.with_draw_order(...)构造器方法这与仓库中的官方测试写法完全一致见下文测试章节。例如use re_sdk_types::archetypes::Image; let image Image::from_color_model_and_tensor( re_sdk_types::encodings::ColorModel::RGB, tensor_data, )?; // 指定该实体绘制在 draw_order 更大的实体之下 let image image.with_draw_order(0.0);渲染原理从 DrawOrder 到 DepthOffsetDrawOrder并不会直接作为渲染参数而是由空间视图re_view_spatial中的视图上下文系统EntityDepthOffsets换算为渲染器可用的深度偏移re_renderer::DepthOffset。其核心实现在 crates/views/re_view_spatial/src/contexts/depth_offsets.rs收集collect_draw_order_per_visualizer遍历所有处理 draw order 的可视化器visualizers_processing_draw_order()对每个实体的可视化指令执行latest_at查询读取DrawOrder组件若实体未显式设置则通过typed_fallback_for惰性计算一个默认值determine_default_draworder位于同文件。排序所有(可视化器, 实体路径哈希)对按DrawOrder值放入BTreeMap天然按值升序每个值对应一个BTreeSet的实体集合。换算为保证深度偏移尽量紧贴 0起始偏移被设为-(实体总数 / 2)然后为每个实体分配一个连续递增的DepthOffset。源码中有两处值得注意的实现细节可直接从 depth_offsets.rs 确认相同 DrawOrder 也会被拆开注释明确写道 We give objects with the sameDrawOrderstill a different depth offset in order to avoid z-fighting artifacts when rendering in 3D. (for pure 2D this isnt necessary)——即为了避免 3D 渲染下的 z-fighting深度冲突伪影相同DrawOrder的实体仍会被分配不同但相邻的深度偏移。这与文档中相同 draw order 的实体顺序一般未定义的语义并不冲突偏移不同是为了消除伪影而非承诺绘制先后。默认值兜底未设置draw_order的实体也会走同一套机制获得默认层级因此新旧数据混用时不会出现层级断裂。官方测试用例一份可复现的分层示范仓库在 crates/views/re_view_spatial/tests/draw_order.rs 中提供了test_draw_order集成测试用 8 个实体直观演示了完整的层叠效果每个实体都在2d_layering前缀下实体路径Archetypedraw_order视觉效果2d_layering/backgroundImage512×256 灰色0.0最底层背景2d_layering/middle_gradientImage256×256 渐变1.0中间层2d_layering/middle_blueImage192×192 蓝色1.1略高于渐变层2d_layering/arrow2d_betweenArrows2D1.12夹在中间层之间2d_layering/lines_behind_rectLineStrips2D1.25在矩形之下2d_layering/rect_between_top_and_middleBoxes2D1.5中上层2d_layering/points_between_top_and_middlePoints2D1.51紧贴矩形之上2d_layering/topImage128×128 白色2.0最顶层该测试通过TestContext将上述实体依次写入SpatialView2D并生成名为draw_order的渲染快照。它同时印证了两点一是with_draw_order是 Rust API 的标准链式方法各 archetype 均可用二是小数粒度完全受支持如1.1、1.12、1.51可以在相邻图层之间精确插入新层这正是Float32编码带来的灵活性。注意事项与最佳实践综合原文档语义与源码实现在实际使用DrawOrder时建议遵循以下规则跨实体分层靠 DrawOrder实体内分层靠组件顺序一个实体只能携带一个DrawOrder值若需要在一个实体路径下表达多层应通过组件排列顺序控制或拆分为多个实体。避免依赖相等值相同DrawOrder的实体之间先后顺序一般未定义虽然在 3D 投影场景下渲染器会为它们分配不同的深度偏移以避免 z-fighting但这不能作为可靠的分层依据。需要明确遮挡关系时请使用不同的值。数值只论大小、不论绝对值任意浮点值均可正、负、小数系统内部会自动将收集到的值映射为紧贴 0 的连续深度偏移因此无需刻意从 0 开始计数。未设置时自动兜底未显式指定draw_order的实体会获得默认层级由typed_fallback_for提供与显式设置的值混用是安全的。仅作用于 2D 元素DrawOrder的语义限定在 2D 元素图像、点、框、线、箭头等的叠放三维物体的遮挡由常规深度测试决定不受该组件控制。延伸阅读组件类型定义draw_order.def.rsRust 生成绑定crates/store/re_sdk_types/src/components/draw_order.rsPython 生成绑定rerun_py/rerun_sdk/rerun/components/draw_order.py渲染换算实现depth_offsets.rs层叠效果集成测试tests/draw_order.rs编码类型说明Float32相关 archetype以 Points2D、Boxes2D、Image 为代表其余见上文表格。【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考