体积渲染
渲染体积对象。
体积渲染 展示了如何使用 QCustom3DVolume 来显示体积数据。
运行示例
要从 Qt Creator 运行示例,打开 欢迎 模式并从 示例 中选择示例。有关更多信息,请访问 构建和运行示例。
初始化体积项
QCustom3DVolume 项是特殊的自定义项(见 QCustom3DItem),可以用来显示体积数据。体积项仅支持正交投影,因此首先确保图形正在使用它
m_graph->setOrthoProjection(true);
创建一个与坐标轴数据范围相关的体积项
m_volumeItem = new QCustom3DVolume; // Adjust water level to zero with a minor tweak to y-coordinate position and scaling m_volumeItem->setScaling( QVector3D(m_graph->axisX()->max() - m_graph->axisX()->min(), (m_graph->axisY()->max() - m_graph->axisY()->min()) * 0.91f, m_graph->axisZ()->max() - m_graph->axisZ()->min())); m_volumeItem->setPosition( QVector3D((m_graph->axisX()->max() + m_graph->axisX()->min()) / 2.0f, -0.045f * (m_graph->axisY()->max() - m_graph->axisY()->min()) + (m_graph->axisY()->max() + m_graph->axisY()->min()) / 2.0f, (m_graph->axisZ()->max() + m_graph->axisZ()->min()) / 2.0f)); m_volumeItem->setScalingAbsolute(false);
通过将 QCustom3DItem::scalingAbsolute 属性设置为 false
来指示体积的缩放应随数据范围的改变而改变。接下来,定义体积的内部内容
m_volumeItem->setTextureWidth(lowDetailSize); m_volumeItem->setTextureHeight(lowDetailSize / 2); m_volumeItem->setTextureDepth(lowDetailSize); m_volumeItem->setTextureFormat(QImage::Format_Indexed8); m_volumeItem->setTextureData(new QList<uchar>(*m_lowDetailData));
为了纹理,使用八位索引颜色,因为它紧凑且易于调整颜色,而无需重新设置整个纹理。对于纹理数据,使用之前基于高度图创建的数据。通常,体积项的数据以图像栈的形式预先生成,因此可以跳过数据生成细节。有关实际数据生成过程的信息,请参阅示例代码。
由于使用了八位索引颜色,需要颜色表来将八位颜色索引映射到实际颜色。在典型用例中,会从源图像中获取颜色表,而不是手动定义一个
m_volumeItem->setColorTable(m_colorTable1);
为了有选项显示围绕体积的切片框架,初始化它们的属性。最初,框架将被隐藏
m_volumeItem->setSliceFrameGaps(QVector3D(0.01f, 0.02f, 0.01f)); m_volumeItem->setSliceFrameThicknesses(QVector3D(0.0025f, 0.005f, 0.0025f)); m_volumeItem->setSliceFrameWidths(QVector3D(0.0025f, 0.005f, 0.0025f)); m_volumeItem->setDrawSliceFrames(false);
最后,将体积作为自定义项添加到图形中以便显示它
m_graph->addCustomItem(m_volumeItem);
在体积中进行切片
除非体积大部分是透明的,否则只能看到其表面,这通常不是很有帮助。查看体积的内部结构的一种方法是通过查看体积的切片。QCustom3DVolume 提供了两种显示切片的方法。第一种方法是将选定的切片显示在体积的位置。例如,要指定垂直于 X 轴的切片,请使用以下方法
m_volumeItem->setSliceIndexX(m_sliceIndexX);
要显示上述指定的切片,必须将 QCustom3DVolume::drawSlices 属性也设置
m_volumeItem->setDrawSlices(true);
查看切片的第二种方法是使用QCustom3DVolume::renderSlice() 方法,该方法将指定的切片生成一个 QImage。然后这个图像可以在另一个小部件上显示,例如一个QLabel
调整体积透明度
有时,仅仅查看切片并不能很好地理解体积的内部结构。QCustom3DVolume 提供两个可以用来调整体积透明度的属性
m_volumeItem->setAlphaMultiplier(mult); ... m_volumeItem->setPreserveOpacity(enabled);
QCustom3DVolume::alphaMultiplier 是一个应用于体积中每个体素alpha值的一般乘数。这使得为已经稍微透明的体积部分添加均匀的透明度成为可能,以揭示内部的非透明细节。除非将 QCustom3DVolume::preserveOpacity 属性设置为 false
,否则此乘数不会影响全不透明的颜色。
调整体积透明度的另一种方法是直接调整体素的alpha值。对于八位索引纹理,这可以通过修改和重置颜色表来实现
int newAlpha = enabled ? terrainTransparency : 255; for (int i = aboveWaterGroundColorsMin; i < underWaterGroundColorsMax; i++) { QRgb oldColor1 = m_colorTable1.at(i); QRgb oldColor2 = m_colorTable2.at(i); m_colorTable1[i] = qRgba(qRed(oldColor1), qGreen(oldColor1), qBlue(oldColor1), newAlpha); m_colorTable2[i] = qRgba(qRed(oldColor2), qGreen(oldColor2), qBlue(oldColor2), newAlpha); } if (m_usingPrimaryTable) m_volumeItem->setColorTable(m_colorTable1); else m_volumeItem->setColorTable(m_colorTable2);
高清晰度与低清晰度着色器
默认情况下,体积渲染使用高清晰度着色器。它在体素追踪体积内容时为每个体素提供正确的权重,从而提供体积细节的精确表示。然而,这计算成本非常高,因此帧率会受到影响。如果渲染速度比体积内容的像素完美精度更重要,可以将QCustom3DVolume::useHighDefShader 属性设置为 false
使用更快的低清晰度着色器。低清晰度着色器通过在某些精度上做出妥协来提高速度,因此它不保证采样体积的每个体素。这可能导致体积细部上的闪烁或其他渲染错误。
m_volumeItem->setUseHighDefShader(enabled);
示例内容
© 2024 The Qt Company Ltd。本文件中包含的文档贡献的版权属于其各自的拥有者。本文件中提供的文档是根据自由软件基金会发布的 GNU自由文档许可协议版本1.3 的条款许可的。Qt及其相关标志是芬兰和/或其他国家和地区 The Qt Company Ltd. 的商标。所有其他商标是其各自所有者的财产。