体积渲染
体素对象的渲染。
“体积渲染”演示了如何使用QCustom3DVolume 来显示体积数据。

运行示例
您可以通过以下方式运行示例:
- Qt Creator
打开Welcome 模式,并从Examples 中选择该示例。有关更多信息,请参阅Qt Creator :教程:构建和运行。
- Qt Extension for Visual Studio Code
在“Command Palette ”中运行Qt: Open Qt examples 命令,并从列表中选择该示例。有关更多信息,请参阅Qt Extension for Visual Studio Code :教程:构建和运行。
初始化体积项
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));纹理请使用 8 位索引色,因为这种格式体积小,且便于调整颜色而无需重置整个纹理。纹理数据请使用之前基于高度图生成的数据。通常,体积项的数据会以图像堆栈的形式预先生成,因此可以跳过数据生成的细节。 有关实际数据生成过程的更多信息,请参阅示例代码。
由于使用了 8 位索引色,因此需要一个颜色表来将 8 位颜色索引映射到实际颜色。在典型用例中,您应从源图像中获取颜色表,而不是手动定义一个:
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值。对于8位索引纹理,只需修改并重置颜色表即可:
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);示例内容
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.