Sur cette page

Rendu volumétrique

Rendu d'objets volumétriques.

Lerendu volumétrique montre comment utiliser QCustom3DVolume pour afficher des données volumétriques.

Exécution de l'exemple

Pour exécuter l'exemple à partir de Qt CreatorOuvrez le mode Welcome et sélectionnez l'exemple à partir de Examples. Pour plus d'informations, voir Qt Creator: Tutoriel : Construire et exécuter.

Initialisation de l'élément de volume

Les éléments QCustom3DVolume sont des éléments personnalisés spéciaux (voir QCustom3DItem), qui peuvent être utilisés pour afficher des données volumétriques. Les éléments volumétriques ne sont pris en charge qu'avec la projection orthographique, il faut donc d'abord s'assurer que le graphique l'utilise :

m_graph->setOrthoProjection(true);

Créez un élément volumétrique lié aux plages de données des axes :

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);

Indiquez que l'échelle du volume doit suivre les changements dans les plages de données en définissant la propriété QCustom3DItem::scalingAbsolute sur false. Ensuite, définissez le contenu interne du volume :

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));

Utilisez des couleurs indexées sur huit bits pour la texture, car elles sont compactes et permettent d'ajuster facilement les couleurs sans avoir à réinitialiser l'ensemble de la texture. Pour les données de texture, utilisez les données créées précédemment sur la base des cartes de hauteur. En règle générale, les données relatives aux éléments de volume sont prégénérées sous la forme d'une pile d'images, de sorte que les détails de la génération des données peuvent être ignorés. Pour plus d'informations sur le processus de génération des données, voir l'exemple de code.

Étant donné que des couleurs indexées sur huit bits sont utilisées, une table des couleurs est nécessaire pour faire correspondre les index de couleurs sur huit bits aux couleurs réelles. Dans un cas d'utilisation typique, vous obtiendrez la table des couleurs à partir des images sources au lieu d'utiliser une table définie manuellement :

m_volumeItem->setColorTable(m_colorTable1);

Pour avoir la possibilité d'afficher les cadres de tranches autour du volume, initialisez leurs propriétés. Initialement, les cadres seront cachés :

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);

Enfin, ajoutez le volume en tant qu'élément personnalisé au graphique pour l'afficher :

m_graph->addCustomItem(m_volumeItem);

Trancher dans le volume

À moins que le volume ne soit largement transparent, vous ne pouvez en voir que la surface, ce qui n'est souvent pas très utile. Une façon d'inspecter la structure interne du volume est de visualiser les tranches du volume. QCustom3DVolume propose deux façons d'afficher les tranches. La première consiste à afficher les tranches sélectionnées à la place du volume. Par exemple, pour spécifier une tranche perpendiculaire à l'axe X, utilisez la méthode suivante :

m_volumeItem->setSliceIndexX(m_sliceIndexX);

Pour afficher la tranche spécifiée ci-dessus, la propriété QCustom3DVolume::drawSlices doit également être définie :

m_volumeItem->setDrawSlices(true);

La deuxième façon de visualiser les tranches est d'utiliser la méthode QCustom3DVolume::renderSlice(), qui produit une image QImage à partir de la tranche spécifiée. Cette image peut ensuite être affichée sur un autre widget, tel que QLabel:

m_sliceLabelX->setPixmap(
            QPixmap::fromImage(m_volumeItem->renderSlice(Qt::XAxis, m_sliceIndexX)));

Réglage de la transparence des volumes

Parfois, l'affichage des seules tranches ne permet pas de bien comprendre la structure interne du volume. QCustom3DVolume fournit deux propriétés qui peuvent être utilisées pour ajuster la transparence du volume :

m_volumeItem->setAlphaMultiplier(mult);
    ...
m_volumeItem->setPreserveOpacity(enabled);

QCustom3DVolume::alphaMultiplier est un multiplicateur général qui est appliqué à la valeur alpha de chaque voxel du volume. Il permet d'ajouter une transparence uniforme aux parties déjà quelque peu transparentes du volume afin de révéler les détails opaques internes. Ce multiplicateur n'affecte pas les couleurs totalement opaques, sauf si la propriété QCustom3DVolume::preserveOpacity est définie sur false.

Une autre façon d'ajuster la transparence du volume consiste à ajuster directement les valeurs alpha des voxels. Pour les textures indexées sur huit bits, il suffit de modifier et de réinitialiser la table des couleurs :

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);

Shader haute définition ou basse définition

Par défaut, le rendu volumétrique utilise un shader haute définition. Il prend en compte chaque voxel du volume avec le poids correct lors du ray-tracing du contenu du volume, fournissant ainsi une représentation précise des détails les plus fins du volume. Toutefois, cette méthode est très coûteuse en termes de calcul, et la fréquence d'images en pâtit. Si la vitesse de rendu est plus importante que la précision au pixel près du contenu du volume, utilisez le nuanceur basse définition, beaucoup plus rapide, en définissant la propriété QCustom3DVolume::useHighDefShader false . Le shader basse définition atteint la vitesse en faisant des compromis sur la précision, il ne garantit donc pas que chaque voxel du volume sera échantillonné. Il ne garantit donc pas que chaque voxel du volume sera échantillonné, ce qui peut entraîner un scintillement ou d'autres artefacts de rendu sur les détails les plus fins du volume.

m_volumeItem->setUseHighDefShader(enabled);

Contenu de l'exemple

Exemple de projet @ code.qt.io

© 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.