当前位置: 首页 > news >正文

【论文阅读】-- Attribute-Aware RBFs:使用 RT Core 范围查询交互式可视化时间序列颗粒体积

在这里插入图片描述

Attribute-Aware RBFs: Interactive Visualization of Time Series Particle Volumes Using RT Core Range Queries

    • 摘要
    • 1 引言
    • 2 相关工作
      • 2.1 粒子体渲染
      • 2.2 RT核心方法
    • 3 渲染彩色时间序列粒子体积
      • 3.1 场重构
        • 3.1.1 密度场 Φ
        • 3.1.2 属性字段 θ
        • 3.1.3 优化场重建
      • 3.2 树结构构建与调整
        • 3.2.1 与时间交互
        • 3.2.2 与粒子半径的交互
        • 3.2.3 通过集群减少内存消耗
      • 3.3 直接体绘制
        • 3.3.1 发射和吸收
        • 3.3.2 随机体积阴影
        • 3.3.3 用蓝噪声减少图像方差
    • 4 实验结果
      • 4.1 数据集
      • 4.2 评估
        • 4.2.1 增加粒子半径
        • 4.2.2 粒子聚类
        • 4.2.3 硬件加速的影响
        • 4.2.4 时空蓝噪声的影响
        • 4.2.5 方法比较
    • 5 结论
    • 参考文献


在这里插入图片描述

摘要

平滑粒子流体动力学 (SPH) 是一种无网格方法,用于模拟流体、天体物理学和固体力学中的体积介质。可视化这些模拟是有问题的,因为这些数据集通常包含数百万甚至数十亿个带有物理属性并随时间移动的粒子。使用径向基函数(RBF)对粒子进行建模,并对重叠粒子进行插值以重建高质量的体积场;然而,这种插值过程成本高昂,并且使得交互式可视化变得困难。现有的 RBF 插值方案不考虑颜色映射属性,而是仅限于可视化密度场。为了应对这些挑战,我们利用现代 GPU 架构中的光线追踪核心来加速标量场重建。我们使用新颖的 RBF 插值方案来集成每个粒子的颜色和密度,并利用 GPU 并行树构建和重新拟合,随着模拟动画随着时间的推移或当用户操纵粒子半径时快速更新树。我们还提出了一种希尔伯特重新排序方案,将粒子聚集在树的叶子上,以减少树的内存消耗。最后,我们通过采用时空蓝噪声采样方案来降低体积阴影的噪声。与传统方法相比,我们的方法可以提供这些大型体积时间序列粒子数据集更详细和交互式的视图,从而对这些物理模拟产生新的见解。

1 引言

在高性能模拟中,体积粒子表示的使用非常广泛。它们的记忆表示相对紧凑,因为粒子只需要位置和半径。粒子还可以携带相应的标量属性,例如速度或温度。与有限元网格类似,粒子的优点是它们可以放置在计算域中的任何位置并适应数据的基本频率。然而,与有限元不同,这些粒子不需要内存密集型连接信息。相反,可以使用自然组合和混合在一起的径向基函数对它们进行建模。这样做的另一个好处是允许粒子在空间中自由移动,而无需担心重新划分网格。由于表达方便,粒子表示通常适用于无网格模拟方法,例如平滑粒子流体动力学 (SPH) [6, 21]。

然而,这种灵活性给交互式可视化工具带来了挑战,因为这些工具通常需要先验或即时构建数据。近似方法将粒子喷射到屏幕上或结构化网格中,从而导致过度绘制问题或原子争用。当粒子具有颜色属性时,后插值网格(其中单元格在颜色映射之前平均粒子属性)会产生错误的分类数据结果,而预插值网格(其中单元格平均预颜色映射属性)会消耗大量内存,并且两者都无法精细捕获细节;而 splats 需要从前到后对粒子进行排序才能合成,当粒子重叠时就会失败。

随着各种方法被提出来可视化这些粒子体积,GPU 架构本身也发生了巨大的发展。如今,许多 GPU 供应商都包含光线追踪核心,也称为“RT 核心”,其中通过加速结构的光线遍历是在 GPU 本身的芯片中实现的。 GPU 光线追踪框架还包括高性能树构建例程,可减少预处理时间和实现复杂性。

Knoll 等人最近的工作利用这些 RT 核心。 [15]以与先前方法非常不同的方式可视化体积粒子。他们的方法使射线从前到后穿过体积,并且当射线与粒子无序相交时,这些粒子被存储在射线有效负载堆栈中。然后,每个射线段在将这些粒子合成在一起之前从前到后对这堆粒子进行排序。

这种方法非常有吸引力,因为它不需要在相机操作期间在 CPU 上对粒子进行排序。相反,只需要对一小部分相交的粒子子集进行排序。然后,当像素的不透明度达到饱和时,行进过程可以返回,而无需进一步处理被遮挡的粒子。关于可视化质量,该方法可以直接合成粒子,而不需要体素化。由于这种方法与 RT 核心框架兼容,可视化工具可以将 GPU 光线追踪的技术复杂性转移给驱动程序,并利用附带的快速树构建例程来避免较长的预处理时间。

不幸的是,这种方法也有一些妥协。一个问题是粒子被解释为视图对齐的圆盘,这阻止了它们在体积上重叠和混合。相反,当相机移动时,这些圆盘会离散地弹出到彼此的上方或下方。另一个挑战是,根据当前的 GPU 架构,光线有效负载堆栈的大小是固定的。如果堆栈太小,当许多粒子与射线段重叠时,堆栈就会溢出,导致粒子丢失或丢弃。如果太大,寄存器会溢出到全局内存,从而妨碍交互性。对于更平滑混合的大半径,这个问题尤其明显,因为粒子更有可能与射线相交。然后,尽管光线相交得到了硬件加速,但许多粒子相交仍然会导致类似过度绘制的问题,从而使合成成为瓶颈。尽管如此,如果这些问题能够得到解决,那么很有可能使用 RT 核心来实现真正的交互式粒子体积可视化,而几乎不需要预处理时间或视觉妥协。

因此,我们从最近关注可视化质量的 SPH 粒子渲染 [14,25,40] 的工作中汲取灵感,探索了一种更强大的 RT 核心加速粒子体积渲染解决方案。我们用无堆栈半径范围查询代替基于堆栈的粒子相交,收集和插值查询点周围的粒子以重建底层标量场。然后,为了支持每粒子属性,我们描述了一种新颖的径向基函数(RBF)积分方案,该方案除了局部粒子密度之外还计算加权颜色平均值。这些混合颜色可以与 RBF 密度图相结合,以深入了解粒子重叠的位置、它们代表的内容以及它们对最终结果的贡献。

从这里开始,我们探索 RT 核心框架的另一个关键优势,即 GPU 并行树结构,以实现交互式时间序列渲染。我们利用加速结构改造来实现对粒子重叠程度的交互式控制。然后,为了减少内存消耗,我们从最近的方法 [7, 25] 中汲取灵感,并将粒子聚集在叶子上。

最后,我们探索随机体积阴影,以通过改进的深度感知来实现更高保真度的可视化。体积路径追踪产生的噪声会使跟踪粒子随时间的运动变得困难。为了解决这个问题,我们使用蓝噪声随机射线行进方法实现单散射模型[41]。这改善了每像素单样本图像中产生的噪声的结构,从而更容易跟踪粒子运动。

更具体地说,我们提出以下贡献:

  • 一种“属性感知 RBF”插值方案,
  • 应用 RT 核心范围查询来加速粒子场重建,
  • 探索 GPU 并行树构建和重新拟合以实现用户驱动每粒子半径和时间序列数据,
  • 应用希尔伯特簇来减小这些树的大小,从而实现较大粒子体积的可视化,
  • 最后,利用蓝噪声进行随机体积阴影以改进时间序列可视化分析的策略。

2 相关工作

2.1 粒子体渲染

可视化粒子的一类方法是将它们光栅化为屏幕上的椭圆高斯“斑点”[9],使用加法合成来确定通过像素的粒子密度 [5, 34]。但是,当粒子具有与温度或速度等属性相关的颜色映射属性时,它们必须从前到后排序,然后一一合成[8]。这种合成是一种近似解决方案,因为它无法处理彩色粒子重叠并在体积上混合在一起的情况。随着这些体积的增长,这种方式会减慢可视化的非交互式帧速率。

另一种常见的策略是将粒子光栅化为结构化网格[2,4,29],然后使用射线行进[22]或零碰撞方法[18,42]等方法可视化这些网格,其算法复杂性与数据大小无关。然而,这种粒子到网格光栅化预处理的成本很高,尤其是当许多粒子影响公共体素并且原子争用串行执行时。在某些方法中,这种网格泼溅过程必须在每一帧中发生[4]。低分辨率网格可能会对数据进行欠采样,从而无法在可视化过程中区分粒子,特别是当它们具有分类属性(例如电子、质子、中子)时。分辨率太高可能会因空体素而导致内存使用过多;由于模拟的不同部分具有不同的粒子密度,这两个问题经常同时出现。

其他作品直接通过径向基函数 (RBF) 场重建来可视化体积粒子,使用 BSP 树 [12]、八叉树 [32]、包围体层次结构 [16] 和结构化网格 [33, 35] 中的线性索引粒子来降低算法复杂性40]。这些方法在光线行进或跟踪期间遍历这些数据结构以获得高质量图像。然而,构建这些数据结构是一项艰巨的任务,并且通常会阻止用户与粒子半径或模拟的时间维度进行交互。这些数据结构可能会消耗大量内存,并且在 GPU 架构上遍历这些数据结构会引入负载平衡问题或线程发散,从而序列化执行、降低 GPU 利用率并降低可视化交互性。
在这里插入图片描述

2.2 RT核心方法

在科学可视化中,光线追踪核心已成功用于可视化 GPU 架构上原本具有挑战性的数据模式。沃尔德等人的早期作品。 [28,37,38] 和 Morrical 等人。 [27, 28] 使用光线追踪核心,通过用基于点的遍历代替光线遍历来加速有限元网格的点定位。 Wald 等人后来的工作。 [39] 和 Zellmann 等人。 [47] 探索了数据转换,使这些光线追踪核心能够在自适应网格细化(AMR)可视化的背景下插入相邻的同级单元区域。泽尔曼等人。构建后一项工作并描述使用光线追踪核心渲染时间序列 AMR 数据 [45] 和 AMR 流可视化 [44] 的系统。

Zellmann 等人与我们的工作密切相关。 [46]演示了点位置查询和范围查询之间的连接,并使用此连接来实现快速物理驱动的图形布局器。他们的工作展示了相对于基于软件的遍历策略的显着性能改进,并利用 GPU 并行树结构来允许图形逐步变化。 Evangelou 等人后来的工作。 [3] 扩展这个想法来实现截断的 K 最近邻查询。这些概念已被赵等人成功使用。 [48]加速基于粒子的模拟。

与我们的工作密切相关的是 Knoll 等人的方法。 [15],如前所述,它使用 RT 核心来加速粒子体积飞溅。格拉尔卡等人。 [7] 观察到在粒子上构建硬件加速树会消耗大量内存。他们的工作提出了一种混合策略,将粒子聚集成内存高效的 PKD 小树,然后将其存储在硬件兼容树的叶子中。这减少了内存消耗,同时保持了硬件加速的优势。 Morrical 等人的最新工作。 [25]在有限元的背景下提出了一种更简单、更快的希尔伯特聚类策略。

3 渲染彩色时间序列粒子体积

受到这些先前工作的启发,我们在这里描述了使用 RT 核心在现代 GPU 架构上交互式渲染颜色映射时间序列粒子体积的方法。

在 3.1 节中,我们解释了如何在空间中插值点来重建体积场。除了粒子密度之外,这里我们还描述了如何使用径向基积分方案来插值颜色属性粒子。然后,我们展示如何使用光线追踪核心来加速这个重建过程。

在第 3.2 节中,我们描述了如何利用 GPU 并行树构建例程来实现粒子随时间的交互式探索。我们还利用树结构的一种变体,称为“树改装”,允许用户通过相应的标量属性来操纵粒子半径。然后,我们调整这些构建例程以减少内存消耗并缩短构建时间。

在第 3.3 节中,我们描述了如何使用这种加速场重建来进行直接体渲染。在那里,我们介绍了如何实现随机体积阴影以改善深度感知,以及如何减少这些阴影区域中的噪声以随着时间的推移改善数据感知。

3.1 场重构

数学点本身没有体积,仅定义空间中的位置。但出于可视化目的,我们希望这些点代表它们周围体积场的采样。因此,我们需要澄清将粒子云转换为连续值场时我们期望的行为。我们将这种转换过程称为场重建。

随着该场的采样距离粒子越来越近,该粒子对采样位置的影响也会越来越大;当这个场的采样距离更远时,该粒子的影响应该随着距离的增加而减弱。相邻的粒子应该结合在一起以实现平滑的场;为了进行探索,我们希望重新映射该字段以隐藏某些值并揭示其他值。这也将使我们能够控制粒子如何混合在一起,因为我们可以选择仅显示多个粒子重叠的位置。

除了这些粒子在空间中的相对密度之外,我们还希望使用颜色图来可视化与每个粒子相关的属性。当粒子在附近时,我们的目标是在颜色映射属性之间进行自然混合。据我们所知,之前没有关于高质量颗粒采样的工作可以解释这一点。因此,在第 3.1.2 节中,我们重新思考基于 RBF 的粒子采样的想法,并修改这些 RBF 以驱动加权颜色平均。

3.1.1 密度场 Φ

为了可视化粒子密度,我们在径向基函数(RBF)上实现了积分方案。 RBF 是一个实值函数 φ,它以空间中的两个点(样本点 x 和中心点 ci)作为输入,并根据这两点之间的距离返回一个值。我们使用此 RBF 定义的截断高斯变体,其中如果这两点之间的距离超过给定半径 ri,则该值降至零。在实践中,我们选择此 RBF 为距平均值截断三个标准差的高斯分布,因为该值紧密束缚粒子,同时仍产生无伪影的体积场。最后,我们提供一个权重 w,用于启用或禁用粒子对场的影响,我们将其定义为来自每粒子属性 si 的用户驱动映射。
φ ^ ( d , r , w ) = w ∗ e − 1 2 ( 3 d r ) 2 ( 1 ) \hat{\boldsymbol{\varphi}}(d,r,w)=w*e^{-\frac12(\frac{3d}r)^2}\qquad(1) φ^(d,r,w)=we21(r3d)2(1)
φ i ( x , c i , r i , s i ) = { φ ^ ( ∣ ∣ x − c i ∣ ∣ , r i , w ( s i ) ) , i f ∣ ∣ x − c i ∣ ∣ ≤ r i 0 , i f ∣ ∣ x − c i ∣ ∣ > r i , ( 2 ) \varphi_i(x,c_i,r_i,s_i)=\begin{cases}\hat{\boldsymbol{\varphi}}(||x-c_i||,r_i,w(s_i)),&\mathrm{if~}||x-c_i||\leq r_i\\0,&\mathrm{if~}||x-c_i||>r_i&\end{cases},\qquad(2) φi(x,ci,ri,si)={φ^(∣∣xci∣∣,ri,w(si)),0,if ∣∣xci∣∣riif ∣∣xci∣∣>ri,(2)
使用这些密度 RBF,我们可以将标量密度场 Φ 定义为对空间中某个点有贡献的所有 RBF 的总和:
Φ ( x ) = ∑ i n φ i ( x , c i , r i , s i ) ( 3 ) \boldsymbol{\Phi}(x)=\sum_i^n\boldsymbol{\varphi}_i(x,c_i,r_i,s_i)\qquad(3) Φ(x)=inφi(x,ci,ri,si)(3)

然后,我们可以将此 RBF 密度场映射到光密度场,以指导最终的密度值构成可视化中的表面或体积,并且还可以直接对该 RBF 密度场进行颜色映射,以获得有关特定密度值出现位置的视觉洞察。

3.1.2 属性字段 θ

或者,我们可能希望使用颜色图来可视化每个粒子的属性。在定量的情况下——例如,与每个粒子相关的温度或质量——我们希望展示这些属性的直接空间混合;对于定性的粒子,例如将粒子枚举为“电子”、“中子”或“质子”——我们希望使用不同的颜色对空间中这些粒子的存在进行分类。这通常被称为插值前分类和插值后分类,最终我们希望支持这两种情况。

因此,我们不是直接可视化 RBF 密度场,而是使用这些基函数来插值每粒子属性。对于后分类,连续属性在空间中逐渐融合;对于预分类,不同类别的重叠粒子可以通过混合颜色的存在来识别,例如蓝色电子和红色质子场中的紫色,尽管需要仔细管理颜色图以避免歧义。

为了实现这一预期行为,我们可以扩展之前的 RBF 密度场。我们首先将单个粒子的属性定义为整个粒子半径 ri 内的均匀 ˆ θ,否则为零。该 ^ θ 定义为每粒子属性 si 或用户驱动的 si 颜色映射。

θ i ( x , c i , s i , r i ) = { θ ^ ( s i ) , if ∣ ∣ x − c i ∣ ∣ ≤ r i 0 , if ∣ ∣ x − c i ∣ ∣ > r i , ( 4 ) \theta_i(x,c_i,s_i,r_i)=\begin{cases}\hat{\boldsymbol{\theta}}(s_i),&\text{if}||x-c_i||\leq r_i\\0,&\text{if}||x-c_i||>r_i\end{cases},\quad(4) θi(x,ci,si,ri)={θ^(si),0,if∣∣xci∣∣riif∣∣xci∣∣>ri,(4)

使用这些属性 RBF,我们可以将属性场 θ 定义为影响空间中给定位置的所有粒子属性的加权平均值,其中每个属性的权重源自先前定义的该粒子在同一位置的密度 RBF φi。

Θ ( x ) = ∑ i n θ i ( x , c i , r i ) ∗ φ i ( x , c i , r i ) Φ ( x ) ( 5 ) \boldsymbol{\Theta}(x)=\frac{\sum_i^n\boldsymbol{\theta}_i(x,c_i,r_i)*\boldsymbol{\varphi}_i(x,c_i,r_i)}{\boldsymbol{\Phi}(x)}\quad(5) Θ(x)=Φ(x)inθi(x,ci,ri)φi(x,ci,ri)(5)

这种加权平均值会导致颜色映射属性的自然混合,同时在粒子不重叠时仍然保留均匀的颜色,并且其影响随着距离而减弱。

3.1.3 优化场重建

通过上面 Φ 和 θ 的定义,我们现在可以以体积方式可视化粒子数据。然而,为了交互式地可视化这些数据集,我们必须能够在几毫秒内对这个标量场每帧每个像素进行数百次采样。一种简单的方法是迭代数据中的所有粒子,总结每个粒子的密度并将所有贡献的颜色平均在一起;但随着粒子数量的增加,这很快就会成为瓶颈。然而,由于我们将粒子的影响截断到其周围的有限半径,因此只有一小部分粒子实际上会影响空间中任何给定点的场。因此,我们可以用这种穷举遍历来代替仅返回查询点范围内的粒子的搜索。

在计算几何中,这个问题也称为“半径范围查询”。传统上,这些查询是在 GPU 上实现的,或者使用规则网格中的线性索引粒子,或者使用包围体层次结构。不幸的是,这两种方案都有一定的缺点。对于网格,在粒子密度高度不均匀的情况下,负载平衡是一个问题,其中大多数粒子将落入选定的几个单元格中并导致近乎穷举的遍历。另一方面,单指令多数据 (SIMD) 单元上的树遍历会在 GPU 架构上引入线程分歧,从而串行化执行。

幸运的是,现代 GPU 架构支持硬件加速树遍历作为光线追踪协处理器的一部分。这些 RT 内核的行为更像是多指令多数据 (MIMD) 单元 [31],它们对发散树遍历更具弹性。正如 Zellmann 等人所证明的那样。 [46],我们可以(ab)使用这些单元来实现硬件加速范围查询。他们的工作在二维图上下文中使用范围查询来模拟附近节点之间的排斥力,但我们可以轻松扩展这个想法以支持我们的三维粒子 RBF 积分(参见方程 3 和 5)。

我们首先在数据中的每个粒子上构建一个半径为 ri 的边界框。然后,我们使用内置的树构造函数将这些边界框传递给光线追踪 API。通过以这种方式构建我们的树,我们将粒子的范围“烘焙”到树中。然后,当我们想要遍历给定位置范围内的所有粒子时,我们追踪一条原点设置为该查询位置的射线。我们将射线的tmin和tmax值设置为0,将射线查询变成点查询。由于这些 RT 核心的内部工作原理,我们必须将光线方向设置为非零长度,因此我们将方向设置为常数 (1, 1, 1)。最后,当这条射线与树的叶子处的盒子相交时,如果射线原点位于相应粒子的半径范围内,我们可以得出结论,粒子在范围内。此方法的说明如图 3 所示。
在这里插入图片描述
在这里插入图片描述

为了使用这些范围查询进行场重建,我们保留了几个光线有效负载寄存器,一个用于保存我们的密度场值 Φ,还有少量寄存器用于保存我们的属性字段值 θ。我们将这些值初始化为 0,然后调用适当的内部函数将光线遍历分派到 RT 核心。当光线与我们的范围框相交时,RT 核心返回进行相交测试。我们测试射线原点是否包含在相交粒子的半径内,如果是,我们报告潜在的相交,并将评估的粒子的距离 d、标量属性 s 和半径 r 作为“命中属性”传递。

从那里开始,固定功能光线追踪管道中的执行转向“任意命中”评估。我们使用给定粒子的标量属性 s 来确定该粒子的权重 w。对于后插值,我们直接使用属性 s 作为我们的 ˆ θ,但对于预插值,我们使用这个 s 来查找给定粒子的颜色,并将其分配给我们的 ˆ θ。然后我们使用给定的距离 d、半径 r 和权重 w 来评估粒子在查询位置的 RBF 密度 ˆ φ。一旦评估完毕,我们将粒子的贡献密度 ˆ φ 添加到射线有效负载中的总密度场值 Φ(x) 中。我们还通过 RBF 密度 ˆ φ 对 ˆ θ 进行加权,并将结果添加到光线有效负载中的总属性字段值 θ 中。最后,我们忽略这次命中,欺骗 RT 核心继续遍历范围内的下一个粒子。

当光线遍历完成时,存储在 θ 中的返回值在技术上仅代表加权平均值的分子。我们将此累积值除以返回的 Φ 密度值以求解真实的 θ 值。如果对属性字段进行预插值,则可以对该属性字段 θ 进行颜色映射;通过后插值,该属性场可以直接可视化。从这里,我们还可以使用用户驱动的密度图将积分密度场值 Φ 映射到光密度。如果用户希望直接可视化密度场,我们可以用返回的密度场值 Φ 的颜色映射替换之前返回的颜色值。

3.2 树结构构建与调整

通过利用硬件加速的光线追踪技术,我们同样能够从高性能的树结构构建中获益。先前的粒子体绘制方法是在CPU上离线构建层次结构[14];但一旦粒子移动或半径被编辑,这个层次结构就必须重新构建。因为我们不再受限于离线的树结构构建,我们现在有机会实时地移动和调整粒子大小,以支持更多的探索性操作。(另见表1)
在这里插入图片描述

3.2.1 与时间交互

为了处理时间步之间的粒子移动,我们提前分配一个轴对齐边界框的缓冲区,每个粒子一个框。然后,每当模拟进行或用户与数据的时间维度进行交互时,我们都会使用计算着色器在 GPU 上并行计算这些边界框。该计算着色器从当前原点添加和减去给定粒子的半径,将这两个极值存储到边界框缓冲区中。

随着模拟的进行,一些模拟代码还会引入新粒子或删除粒子。对于我们的应用程序,我们假设粒子的最大理论数量,以避免昂贵的边界框缓冲区重新分配。然后,如果一个框不包含点,可能是由于一个时间步的粒子少于另一个时间步,我们将最小和最大边界框坐标设置为浮点 NaN。这会禁止我们的光线追踪图形 API 在树构建期间考虑该框。最后,我们将此缓冲区直接传递到光线追踪框架的实时树构造例程,回收此树构造所需的现有临时内存,以避免缓冲区重新分配造成的停顿。

3.2.2 与粒子半径的交互

为了处理粒子半径操作,我们可以改装我们的树而不是重建它们。这种重新拟合过程比完整的树构建要快得多,并且允许更平滑的粒子半径操作,特别是对于非常大的粒子体积。这里,允许重新拟合,因为半径操作不会改变底层树拓扑。

在实践中,我们引入了另一种用户驱动的贴图,我们称之为“半径贴图”,它允许用户控制单个粒子的半径,并且可以用作隐藏粒子的更有效的手段。使用等式 1 中的 RBF 权重,接近零的加权粒子仍然与范围查询相交,并导致冗余计算。通过按半径隐藏粒子,用户可以减少树中的边界框重叠并避免这种不必要的计算,从而有效地实现空白空间跳跃。

为了启用每粒子 RBF 操作,我们修改边界框计算着色器以从半径图中读取当前粒子的标量属性 s 以设置唯一的粒子半径。为了方便起见,我们指定全局 RBF 粒子半径,然后让该半径图返回一个百分比,我们将其乘以全局 RBF 粒子半径来计算最终的粒子半径。然后,我们使用光线追踪框架提供的适当的重新拟合指令来解释这些更新的粒子边界。
在这里插入图片描述

3.2.3 通过集群减少内存消耗

最后,对于一些大型数据集,内存消耗可能是一个问题,尤其是对于内存资源有限的消费类 GPU 而言。目前,我们不仅需要考虑粒子本身,还需要考虑它们的边界框。然而,每个粒子上的边界框缓冲区将是粒子数据本身的两倍,因为每个轴对齐框必须使用两个附加点(最小角点和最大角点)来定义。为了减少内存消耗,我们可以通过将附近的粒子聚集到同一个框中来减少创建的边界框的数量。

为了进行这种聚类,我们遵循最近的工作 [7, 28] 的脚步,并沿着希尔伯特空间填充曲线对粒子重新排序。此重新排序操作可以在 CPU 上完成,也可以使用并行基数排序在 GPU 上完成。通过以这种方式重新排序粒子,空间中附近的粒子也将在内存中附近。然后,我们可以在内存中的 N 个相邻粒子集上构建“簇”边界框,而不是计算每个粒子上的单独边界框。第一个簇包含粒子 0 → N − 1,第二个簇包含粒子 N → 2N − 1 等等(见图 6)。
在这里插入图片描述

这将以轻微的场重建性能成本为代价,因为现在对于每个相交的簇,必须测试簇中的所有粒子是否与我们的查询点相交。然而,当相邻的粒子组可能已经与查询点重叠时,在内存相干线性过程中一起处理所有这些附近的粒子可能比通过同一组粒子进行更密集的深度优先搜索更有效。

3.3 直接体绘制

使用径向基函数,我们可以在空间中的任何点重建标量场,包括积分 RBF 密度场 Φ 以及颜色映射属性场 θ。由于硬件加速,我们还可以快速重建这个标量场。然后,我们可以使用 GPU 并行树构建来交互式地设置这些场的动画,并可以使用树重新拟合来操纵粒子半径。有了这个,我们就有了一个坚实的框架来实现时间序列粒子体积的直接体积渲染。

3.3.1 发射和吸收

直接体渲染的一种常见方法是使用发射和吸收照明模型。通过该模型,参与介质内的样本会发出观察者可以直接观察到的光。根据介质的光学厚度,该发射被体积呈指数吸收。我们以遮挡的形式看到这种吸收的影响,其中前面的不透明介质遮挡了后面的其他介质。

从相机原点开始,我们生成一组与视图对齐的光线,以测试与包含粒子数据的全局边界框的相交。然后,我们将这些光线从盒子中的入口点行进到出口,在每一步对标量场进行采样。我们使用 RBF 密度场 Φ 作为我们的光密度,并使用比尔-朗伯定律来计算沿光线的透射率,我们用它从前到后合成相应的 θ 颜色值,直到光线离开边界框或像素的不透明度达到饱和。为了避免常规步长产生“木纹”伪影,我们用随机数抖动每条光线,并随着时间的推移对这些结果进行平均。

3.3.2 随机体积阴影

发射和吸收照明模型的缺点是观看者可能会发现很难理解数据中的深度。这是因为我们经常依赖外部光源和阴影来塑造体积内的隐式几何形状 [20, 43]。因此,为了在可视化过程中更好地恢复深度信息,我们可以扩展此发射和吸收模型以包括体积阴影。这些阴影允许观察者通过光与体积内表面的相互作用来辨别裂缝和缝隙,从而更深入地了解体积。此外,这些表面投射的阴影可以提供额外的深度提示,特别是当用户能够操纵光的来源时。

为了实现体积阴影,我们可以从发射和吸收模型转移到单一散射模型。我们不是将采样的颜色解释为发射源,而是将这些颜色解释为介质的反照率(或反射率)。通过这一变化,我们的媒体的外观现在取决于空间中给定位置接收到的光量。这可以通过操纵光的位置或通过使介质的某些位置光学透明来控制。

不幸的是,使用 alpha 合成光线行进时,我们遇到了可扩展性问题,因为按原样,我们沿着观察光线有许多样本需要着色。为了给给定的样本点着色,我们必须将辅助阴影光线追踪到光源。这些阴影光线必须穿过介质——就像我们的主光线一样——以确定我们的体积传输了多少光。尽管我们的场重建速度很快,但如果每条主光线在每个采样点都跟踪次级阴影光线,我们将很快达到性能极限并失去可视化交互性。

相反,我们可以通过用光线行进代替零碰撞方法来减少阴影采样费用。这使用蒙特卡罗采样过程来对体积中的同等可能距离进行采样(称为“自由飞行距离”)。由于朗伯比尔定律产生给定距离的吸光度,因此我们可以反转该函数以在给定随机吸光度值的情况下生成自由飞行距离。在异质介质中,反转吸光度很困难,因为光学厚度随空间变化。零碰撞方法通过引入“零粒子”来解决这个问题,该“零粒子”使体积均匀化并能够在不改变体积外观的情况下反转吸光度。然后,使用拒绝采样过程来确定当前样本是零碰撞事件还是散射事件。为了更全面地详细解释零碰撞方法,我们推荐 Novak 等人的 SIGGRAPH 课程的距离采样部分。 [30]。

通过对自由飞行距离进行采样,我们可以将沿观察光线的阴影点数量从 N 减少到 1。因此,我们只需要跟踪该一个阴影点的一条阴影光线,这显着减少了每帧的采样费用。这种方法的妥协是引入了显着的噪声,类似于蒙特卡罗路径追踪,它必须随着时间的推移而收敛。

3.3.3 用蓝噪声减少图像方差

空碰撞方法非常适合可视化图像有时间收敛的静态数据集。然而,每像素单样本图像中存在的高度噪声使得难以理解随时间变化的动画数据。传统方法使用时间抗锯齿的一些变化来在存在运动的情况下收敛这些随机效应,但这些技术需要运动矢量,而由于数据的体积性质,我们无法轻松计算运动矢量。或者,我们可以增加每帧每像素采集的样本数量,但这会减慢我们的可视化到非交互式帧速率。

我们观察到,从零碰撞跟踪中理解单样本每像素图像的困难源于噪声中缺乏结构,特别是在我们赖以感知深度和形状的阴影区域中。同时,这种噪声是不可避免的,因为零碰撞跟踪器使用拒绝采样来处理沿光线的零散射事件。即使使用高质量的随机数生成器,这种拒绝采样过程也会破坏输入随机噪声和输出图像结构之间的任何相关性。

幸运的是,还有其他方法可以计算自由飞行距离。首先,我们可以将吸光度 F 描述为 t 的函数,其中 t 表示沿射线的距离:
F ( t ) = ξ = 1 − e − ∫ 0 t μ t ( s ) d s ( 6 ) F(t)=\xi=1-e^{-\int_0^t\boldsymbol{\mu}_t(s)ds}\quad(6) F(t)=ξ=1e0tμt(s)ds(6)

在上面的方程中,μt (s) 表示沿着我们的射线的一点处的体积消光。指数项代表比尔朗伯定律,该定律将光通过体积的透射率建模为指数衰减,具体取决于行进的距离和沿该距离的总体消光。

实际上,在给定自由飞行距离 t 的情况下,上面的方程产生介于 0 和 1 之间的吸光度 xi。我们的目标是反转上述函数,这样我们就可以提供 0 到 1 之间的单个随机吸光度值 Σ 来获得自由飞行距离 t。请注意,重要的是我们只需要一个这样的随机值 xi,以便我们可以在输入随机数和输出采样距离之间保持强相关性。

如果我们尝试反转上面的方程,我们会发现这个函数只能部分反转:

∫ 0 t μ t ( s ) d s = − l n ( 1 − ξ ) ( 7 ) \int_0^t\boldsymbol{\mu}_t(s)ds=-ln(1-\boldsymbol{\xi})\quad(7) 0tμt(s)ds=ln(1ξ)(7)

这是因为消光值 μ 是 t 的函数,我们同时想要求解它。幸运的是,我们可以通过将该积分转换为黎曼和来求解上述方程的近似值:

∑ i = 1 n μ t , i Δ = − l n ( 1 − ξ ) ( 8 ) \sum_{i=1}^n\mu_{t,i}\Delta=-ln(1-\xi)\quad(8) i=1nμt,iΔ=ln(1ξ)(8)

如果我们可以解析地求解右侧,那么我们对左侧进行线性搜索,直到找到该方程的解。因此,我们首先通过生成随机值 xi 来求解该方程的右侧。然后,我们使用光线行进过程以数值方式搜索该方程的解,计算沿光线采样的消光值 μ 的运行总和乘以步长,直到该总和超过右侧的解。左侧超过右侧的距离是自由飞行距离的近似解。

上述随机射线行进技术计算自由飞行距离的优点是我们不再需要使用拒绝采样,因为我们不再需要空粒子来均匀化体积以反转吸光度。使用这种替代的光线行进方法,进入体积的采样着色位置需要一个随机数,并且与输入随机数生成器具有高度相关性。因此,我们可以通过使用时空蓝噪声 (STBN) 纹理来改进体积噪声的结构,如 Wolfe 等人所述。 [41]。此转换的结果如图 7 所示。
在这里插入图片描述

4 实验结果

为了评估我们的方法,我们的渲染后端 [26] 使用 Vulkan 1.3 以及 VK_KHR_raytracing_pipeline 扩展来访问基于 Linux 的环境中 NVIDIA、AMD 和 Intel GPU 上的硬件加速光线追踪功能。除非另有说明,测量均使用 NVIDIA RTX 4090 和 Intel i9 12900K 处理器进行。对于图 10,我们还包括对 NVIDIA RTX 3060 Ti、Intel ARC A770 和 AMD RX 6750 XT 的评估。所有图像均以 1024 × 1024 的分辨率渲染,每像素最多 64 个样本,每帧一个样本。
在这里插入图片描述

4.1 数据集

使用该硬件,我们对不同大小的时间序列粒子体积的集合进行了一系列测试(参见图 8):
在这里插入图片描述

1) Nozzle代表用于模拟喷气燃料喷射的模拟[11]。该数据集由静态粒子制成的不透明圆柱形结构组成,用于集中射流。随着时间的推移,该模拟会向模拟中注入新物质,导致内存大小和密度变化不断增加,这对 RBF 粒子可视化提出了挑战。
2) Coal Boiler代表了煤颗粒被注入锅炉的真实模拟[1]。我们的数据副本由模拟开始时的 460 万个粒子到模拟完成时的 4150 万个粒子组成。该模拟是使用 Uintah 计算框架 [23] 进行的。
3) Cabana Dam Break 代表超过 138 个时间步长的自由表面水柱崩塌模拟,每个时间步长包含 768K 个粒子。粒子相互排斥,形成相对均匀的分布。该模拟是使用 Exascale 计算项目 [36] 的 Cabana 粒子工具包生成的。
4) Viscus Fingers 对通过有限点集方法获得的瞬态流体流动进行建模 [17]。一个圆筒装满纯水,然后将无限浓度的盐放在上面。在 120 个时间步长的过程中(每步大约有 550K 个粒子),高度浓缩的盐溶液沿着圆柱体下沉,形成“粘性手指”。该数据集来自2016年科学可视化大赛。
5) HACC 宇宙学是暗物质和重子粒子在 500 万年过程中的演化,通过 CRK-HACC 宇宙学模拟获得 [10]。该模拟研究活动星系核 (AGN) 对周围物质分布的影响。这种活动星系核来自于星系中心黑洞附近的物质堆积。该数据集来自2019年科学可视化大赛。

4.2 评估

通过这些数据集,我们测量各种数据集和属性的预处理时间、压缩有效性和渲染性能。对于“Nozzle”,我们配置了一个密度为 100% 的恒定 RBF 贴图,而其他所有贴图都使用线性增加的密度贴图。 “锅炉”包含较大的粒子半径以显示重叠,而“大坝破裂”和“内脏手指”则使用尖峰传递函数来演示体积和类表面行为的混合。最后,“宇宙学”展示了大领域中的小特征。

我们渲染图 8 中的代表性视点,左侧显示单个每像素样本图像,右侧显示聚合的每像素 64 个样本图像。在这里,我们还以 1024 × 1024 视口的帧/秒 (FPS) 和每帧毫秒 (ms) 为单位提供时序估计。由于我们的样本空间非常大,因此我们通常会观察到帧速率的较大变化。每步包含更多粒子、较大粒子重叠、更多半透明粒子的存在以及较大计算域内小而密集的粒子的数据集都会导致帧速率变慢,反之亦然。

我们方法的另一个重要方面是数据结构构建和更新性能。基于光线追踪的方法以其在输入图元数量方面的效率而闻名。然而,SPH 模拟的一个典型特征是随时间变化的粒子数据。虽然时间序列数据的交互对于基于光栅的泼溅来说是微不足道的,但对光线追踪方法的常见批评是,由于加速结构构建时间较长,它们传统上保留用于可视化静态数据集。幸运的是,我们可以交互地构建这些结构,并且不受这些先前假设的限制。我们在表中报告了加速结构构建时间(当时间步长变化时)和更新时间(当半径变化时)。 1. 请注意,这些时间以毫秒为单位。

最后,我们提出了探索特定参数(粒子半径、希尔伯特簇大小、硬件加速和时空蓝色噪声的影响)对渲染时间影响的基准,因为我们发现我们的方法对这些参数特别敏感。

4.2.1 增加粒子半径

使用基于范围查询采样的方法意味着我们的方法对粒子重叠特别敏感。在大量 RBF 重叠的密集区域中采集的样本成本较高,因为需要测试更多基元并为公式 3 和 5 的加权平均值做出贡献。对于较大的粒子簇,较小的半径也会因潜在的过多空白空间而产生潜在成本。

为了评估这一点,我们首先探讨不同粒子半径的影响。对于此评估,我们在代表典型探索性可视化会话的多个随机视点上可视化数据集,因为剔除有效性、空白空间去除等不仅取决于空间排列,还取决于相机参数。对多个相机位置进行平均也使我们能够报告性能包络而不是静态性能估计。

基于图 8 中的代表性观点,我们围绕给定数据集/时间步长的质心和 50 个不同位置的平均渲染时间进行轨道运行。然后,我们为五个数据集选择合理的半径范围(范围的下端允许查看大部分数据,而半径的上端导致显着重叠),并均匀地探测该范围间隔位置。我们在图 9 (a-e)(蓝色折线)中展示了簇大小为 1(实线)和 16(点线)的结果。
在这里插入图片描述

我们观察到渲染时间通常随着半径的增加而增加,这主要归因于每个样本相交的图元数量的增加。随着粒子半径的减小,我们观察到任何引入的空白空间都不会显着影响可视化性能。这可能是因为空区域中的查询与包含树中的内部节点很少相交,从而使得这些查询成本低廉。之前的工作也得出了非常相似的观察结果[27]。令我们惊讶的是,聚类实际上提高了测试的五个数据集中的三个的可视化性能。我们怀疑这种聚类在粒子本身高度聚类且重叠度高的情况下更有帮助,在这种情况下线性搜索比穷举树遍历更有效。

4.2.2 粒子聚类

接下来,我们评估希尔伯特簇大小及其对渲染时间和内存消耗的影响。我们通常发现,簇大小的合理选择是(离散)范围内的 2 的幂 [20, 24]。我们使用 50 个不同的相机轨道执行与之前相同的基准测试,现在改变该范围内的簇大小,同时保持 RBF 半径固定为之前测试中使用的中值粒子半径。这些结果报告在同一个图 9 中,并用红线标记。通过共享一个共同的数字,我们可以比较我们的方法对簇大小与粒子半径的相对灵敏度。对于相同离散范围的簇大小,我们将这些结果与表 2 中报告的加速结构大小的减少进行了对比。

有趣的是,我们观察到,与半径变量不同,渲染时间较少依赖于簇大小。例如,对于“Boiler”,增加簇大小时的效果实际上是正的,红色“簇大小”曲线通常低于蓝色实线“非簇”线。同时,增加簇大小时内存消耗的改善是一个数量级;簇和加速结构的大小表现出近乎完美的线性相关性。聚类还可以改善树的构建和更新时间(参见表 1),尽管这些时间已经相当短,因此我们怀疑聚类的主要优点在于内存消耗。

在这里插入图片描述

4.2.3 硬件加速的影响

通过我们的方法,我们利用光线追踪硬件来提高查询性能。这些光线追踪核心无法禁用,因此很难直接评估性能改进。相反,我们使用优化的线性包围体层次结构(LBVH)[19],将硬件加速遍历与同一 GPU 上基于软件的、堆栈促进的深度优先遍历进行比较,因为这些树可以并行构建在GPU 以交互速率 [13] 促进我们的时间序列粒子数据。

我们比较了图 10 中三种不同 RT 核心架构的相对性能改进:Intel ARC Alchemist、NVIDIA 的 Ampere 和 AMD 的 RDNA 2。NVIDIA 和 Intel RT 核心实现通过多指令、多数据 (MIMD) 协处理器加速全树遍历,而 AMD 的 RDNA 2 支持在其单指令、多数据 (SIMD) 计算单元上进行直接光线盒相交测试的内在函数。 (请注意,图 10 中较大的加速并不一定等于更快的渲染时间)。

通过此设置,我们评估了两个合成数据集和一个“真实世界”数据集(即“Cabana Dam Break”)的相对性能改进。 “均匀”数据集由使用泊松球采样过程生成的 60 K 粒子组成,而“随机”数据集通过大小等于泊松球半径的位移扰动这 60 K 均匀样本。

我们的研究结果表明,对于所有架构,通过使用通过 VK_KHR_raytracing_pipeline 提供的 RT 内核和内在函数,我们看到了性能改进;然而,对于 Intel 和 NVIDIA 架构来说,性能提升比 AMD 的 RDNA 2 显着得多。我们推测这是由于 MIMD 和 SIMD 加速结构遍历之间的差异造成的,因为实现全树遍历的 MIMD RT 核心理论上更能适应发散遍历流程。在比较随机粒子分布与均匀粒子分布时,在 Intel ARC 和 NVIDIA 上观察到的更大的加速进一步支持了这一假设。在这种情况下,AMD 的 SIMD 树遍历内在函数比纯基于软件的遍历产生较小的改进。

4.2.4 时空蓝噪声的影响

通过我们的方法,我们在探索时间维度上的粒子体积时使用时空蓝噪声来提高图像质量。令我们惊讶的是,这一变化对渲染时间产生了明显的积极影响。图 10 右侧显示了使用蓝噪声分布相对于白噪声分布的影响,其中我们看到了 1 − 2 倍的加速。我们怀疑这种积极影响是因为蓝噪声采样模式比相邻线程之间的白噪声更适合 GPU 缓存机制。

4.2.5 方法比较

最后,我们针对预插值体素网格渲染器和 Knoll 等人提出的方法评估了我们的方法的性能。 [15]。对于所有方法,我们都会考虑任何必要的数据结构构建以实现时间序列可视化。对于体素网格,我们使用计算内核将粒子的 RBF 贡献自动求和到 5123 网格中,然后将该总和除以与每个单元相交的粒子数。由于参考飞溅的技术限制,我们将渲染器限制为发射和吸收照明模型。对于 Knoll 等人的方法,我们稍微减小步长以减少任何严重的视觉伪影。

如表 3 所示,我们观察到,在所有情况下,基于体素的渲染均由体素化过程主导,特别是在粒子重叠度较高的情况下,如“锅炉”的情况。时间序列探索以及色彩图和粒子半径操作都存在此问题。渲染生成的网格速度很快,因为粒子 RBF 积分是先验完成的,但会因量化而导致视觉伪像,尤其是对于“宇宙学”中的精细结构。相比之下,我们的方法以及 Knoll 等人的方法。可以交互式地更新所需的加速结构,从而随着时间的推移实现平滑的交互。
在这里插入图片描述

我们的方法在 RT 核心飞溅基线的性能方面具有竞争力。对于像“喷嘴”中使用的更多类似表面的传递函数,泼溅从早期光线终止中受益更多。然而,对于光学更薄的介质(例如“Viscus”数据集中的水),当许多透明粒子相交时,溅射性能会下降,但不会导致早期光线终止。在这些体积更大的情况下,像我们这样的径向基函数似乎表现得更好,因为点位置可以沿射线采取更保守的采样。

5 结论

在这项工作中,我们提出了一种结合属性感知径向基函数、硬件光线追踪和 GPU 并行树构建来可视化时间序列体积粒子数据集的新颖方法。通过将粒子的颜色映射属性集成到 RBF 场中,我们能够提高数据的表现力,并且通过合并蓝色噪声,我们能够显着提高对时间序列探索的理解。

我们的方法的一个潜在限制是,对于许多大而透明的粒子,我们面临由于过多的零碰撞而导致的过采样问题。使用我们的方法对空白区域进行采样很便宜,但并非免费。我们可能会受益于更严格的边界主线,这将减少沿光线采集的样本数量,特别是在这些空白区域。我们还怀疑,诸如截断的 K 最近邻查询之类的替代查询公式将有助于缓解粒子重叠较大的一些问题。

演示我们方法的示例代码和数据可以在 https://github.com/gprt-org/attribute-aware-rbfs 在线找到 [24],随着 GPU 架构的不断发展,提供了更多的洞察机会。

参考文献

在这里插入图片描述

相关文章:

【论文阅读】-- Attribute-Aware RBFs:使用 RT Core 范围查询交互式可视化时间序列颗粒体积

Attribute-Aware RBFs: Interactive Visualization of Time Series Particle Volumes Using RT Core Range Queries 摘要1 引言2 相关工作2.1 粒子体渲染2.2 RT核心方法 3 渲染彩色时间序列粒子体积3.1 场重构3.1.1 密度场 Φ3.1.2 属性字段 θ3.1.3 优化场重建 3.2 树结构构建…...

A类IP介绍

1)A类ip给谁用: 给广域网用,公网ip使用A类地址,作为公网ip时,Ip地址是全球唯一的。 2)基本介绍 ip地址范围 - 理论范围 0.0.0.0 ~127.255.255.255:00000000 00000000 00000000 00000000 ~ 0111…...

HTML5基本语法

文章目录 HTML5基本语法一、基础标签1、分级标题2、段标签3、换行及水平线标签4、文本格式标签 二、图片标签1、格式2、属性介绍 三、音频标签1、格式2、属性介绍 四、视频标签1、格式2、属性介绍 五、链接标签1、格式2、显示特点3、属性介绍4、补充(空链接&#xf…...

正则表达式常用表示

视频教程:10分钟快速掌握正则表达式 正则表达式在线测试工具(亲测好用):测试工具 正则表达式常用表示 限定符 a*:a出现0次或多次a:a出现1次或多次a?:a出现0次或1次a{6}:a出现6次a…...

【OpenHarmony4.1 之 U-Boot 2024.07源码深度解析】007 - evb-rk3568_defconfig 配置编译全过程

【OpenHarmony4.1 之 U-Boot 2024.07源码深度解析】007 - evb-rk3568_defconfig 配置编译全过程 一、编译后目录列表二、make distclean三、生成.config文件:make V=1 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- evb-rk3568_defconfig四、开始编译:CROSS_COMPILE=aarch64-…...

11.1 Go 标准库的组成

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...

【UG\NX二次开发】UF 调用Grip例子(实现Grip调用目标dll)(UF_call_grip)

此例子是对:【UG\NX二次开发】UF 加载调用与卸载目标dll(UF_load_library、UF_unload_library)_ug二次开发dll自动加载-CSDN博客的补充。 ①创建txt文本,编写以下内容(功能:接收路径,调用该路径的dll)。改后缀为Grip文件(.grs)。…...

[算法刷题积累] 两数之和以及进阶引用

两数之和很经典,通常对于首先想到的就是暴力的求解,当然这没有问题,但是我们如果想要追求更优秀算法,就需要去实现更加简便的复杂度。 这里就要提到我们的哈希表法: 我们可以使用unordered_map去实现,也可以根据题目&a…...

pytest+parametrize+yaml实例

# 一、yaml格式 # # yaml是一种数据类型,可以和json之间灵活的切换,支持注释、换行、字符串等。可以用于配置文件或编写测试用例。 # # 数据结构:一般是键值对的方式出现。注意编写时值前面必须有空格,键:(…...

【HarmonyOS】鸿蒙应用模块化实现

【HarmonyOS】鸿蒙应用模块化实现 一、Module的概念 Module是HarmonyOS应用的基本功能单元,包含了源代码、资源文件、第三方库及应用清单文件,每一个Module都可以独立进行编译和运行。一个HarmonyOS应用通常会包含一个或多个Module,因此&am…...

深入Node.js:实现网易云音乐数据自动化抓取

随着互联网技术的飞速发展,数据已成为企业和个人获取信息、洞察市场趋势的重要资源。音频数据,尤其是来自流行音乐平台如网易云音乐的数据,因其丰富的用户交互和内容多样性,成为研究用户行为和市场动态的宝贵资料。本文将深入探讨…...

【Docker实战】jenkins卡在编译Dockerfile的问题

我们的项目是标准的CI/CD流程,也即是GitlabJenkinsHarborDocker的容器自动化部署。 经历了上上周的docker灾难,上周的服务器磁盘空间灾难,这次又发生了jenkins卡住的灾难。 当然,这些灾难有一定的连锁反应,是先发生的d…...

rust 多线程分发数据

use std::sync::{Arc, Mutex}; use std::collections::VecDeque; use std::thread::{self, sleep}; use rand::Rng; use std::time::Duration;fn main() {let list: Arc<Mutex<VecDeque<String>>> Arc::new(Mutex::new(VecDeque::new()));// 创建修改线程le…...

CentOS 7x 使用Docker 安装oracle11g完整方法

1.安装docker-ce 安装依赖的软件包 yum install -y yum-utils device-mapper-persistent-data lvm2添加Docker的阿里云yum源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo更新软件包索引 yum makecache fast查看docker…...

DDP算法之线性化和二次近似(Linearization and Quadratic Approximation)

DDP算法线性化和二次近似 在DDP算法中,第三步是线性化系统动力学方程和二次近似代价函数。这一步是关键,它使得DDP能够递归地处理非线性最优控制问题。通过线性化和二次近似,我们将复杂的非线性问题转换为一系列简单的线性二次问题,逐步逼近最优解。通过这些线性化和二次近…...

Shellcode详解

Shellcode详解 一、Shellcode的特点二、Shellcode的类型三、Shellcode的工作原理四、防御措施五、常见的PHP Web Shell示例5.1 简单的命令执行5.2 更复杂的Web Shell5.3 防御措施5.4 实际案例 Shellcode是一种小巧、紧凑的机器代码&#xff0c;通常用于利用软件漏洞或注入攻击中…...

sherpa-onnx说话人识别+语音识别自动开启(VAD)+语音识别Python API

专栏总目录 获取该开源项目的渠道,是我在b站上,看到了由csukuangfj制作的一套语音识别视频。以下地址均为csukuangfj在视频中提供,感谢分享! 新一代 Kaldi: 说话人识别+VAD+语音识别之 Python API_哔哩哔哩_bilibili 开源项目地址:GitHub - k2-fsa/sherpa-onnx: Speech-t…...

提取人脸——OpenCV

提取人脸 导入所需的库创建窗口显示原始图片显示检测到的人脸创建全局变量定义字体对象定义一个函数select_image定义了extract_faces函数设置按钮运行GUI主循环运行显示 导入所需的库 tkinter&#xff1a;用于创建图形用户界面。 filedialog&#xff1a;用于打开文件对话框。 …...

python数据可视化:在图形中添加注释matplotlib.pyplot.annotate()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 python数据可视化&#xff1a; 在图形中添加注释 matplotlib.pyplot.annotate() 请问关于以下代码表述正确的选项是&#xff1f; import matplotlib.pyplot as plt x [1, 2, 3, 4, 5] y […...

IDEA debug 调试Evaluate Expression应用

链接&#xff1a; https://blog.csdn.net/xfx_1994/article/details/104136849?utm_mediumdistribute.pc_aggpage_search_result.none-task-blog-2aggregatepagefirst_rank_v2~rank_aggregation-2-104136849.pc_agg_rank_aggregation&utm_termidea%E4%B8%ADevaluate&s…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...