En esta página

Renderizado volumétrico

Renderizado de objetos volumétricos.

Renderizado volumétrico muestra cómo utilizar QCustom3DVolume para mostrar datos volumétricos.

Ejecución del ejemplo

Para ejecutar el ejemplo desde Qt Creatorabra el modo Welcome y seleccione el ejemplo de Examples. Para más información, consulte Qt Creator: Tutorial: Construir y Ejecutar.

Inicialización del elemento Volumen

Los ítems QCustom3DVolume son ítems especiales personalizados (ver QCustom3DItem), que pueden ser utilizados para mostrar datos volumétricos. Los ítems volumétricos sólo son compatibles con la proyección ortográfica, por lo que primero asegúrese de que el gráfico la utiliza:

m_graph->setOrthoProjection(true);

Cree un ítem volumétrico ligado a los rangos de datos de los ejes:

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

Indique que la escala del volumen debe seguir los cambios en los rangos de datos estableciendo la propiedad QCustom3DItem::scalingAbsolute a false. A continuación, defina el contenido interno del volumen:

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

Utiliza un color indexado de ocho bits para la textura, ya que es compacto y facilita el ajuste de los colores sin necesidad de reiniciar toda la textura. Para los datos de la textura, utilice los datos creados anteriormente basados en mapas de altura. Normalmente, los datos para los elementos de volumen vienen pregenerados en forma de una pila de imágenes, por lo que los detalles de la generación de datos se pueden omitir. Para más información sobre el proceso real de generación de datos, consulte el código de ejemplo.

Dado que se utilizan colores indexados de ocho bits, se necesita una tabla de colores para asignar los índices de color de ocho bits a los colores reales. En un caso de uso típico, se obtendría la tabla de colores de las imágenes de origen en lugar de utilizar una definida manualmente:

m_volumeItem->setColorTable(m_colorTable1);

Para tener la opción de mostrar marcos de corte alrededor del volumen, inicialice sus propiedades. Inicialmente, los marcos estarán ocultos:

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

Finalmente, añada el volumen como un elemento personalizado al gráfico para mostrarlo:

m_graph->addCustomItem(m_volumeItem);

Cortar el volumen

A menos que el volumen sea muy transparente, sólo podrás ver su superficie, lo que no suele ser muy útil. Una forma de inspeccionar la estructura interna del volumen es ver los cortes del volumen. QCustom3DVolume proporciona dos formas de mostrar los cortes. La primera es mostrar los cortes seleccionados en lugar del volumen. Por ejemplo, para especificar un corte perpendicular al eje X, utilice el siguiente método:

m_volumeItem->setSliceIndexX(m_sliceIndexX);

Para mostrar la rebanada especificada anteriormente, también se debe establecer la propiedad QCustom3DVolume::drawSlices:

m_volumeItem->setDrawSlices(true);

La segunda forma de visualizar cortes es utilizar el método QCustom3DVolume::renderSlice(), que produce una QImage a partir del corte especificado. Esta imagen puede mostrarse en otro widget, como QLabel:

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

Ajustar la transparencia del volumen

A veces, ver sólo los cortes no nos da una buena comprensión de la estructura interna del volumen. QCustom3DVolume proporciona dos propiedades que se pueden utilizar para ajustar la transparencia del volumen:

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

QCustom3DVolume::alphaMultiplier es un multiplicador general que se aplica al valor alfa de cada vóxel del volumen. Permite añadir una transparencia uniforme a las partes ya algo transparentes del volumen para revelar los detalles opacos internos. Este multiplicador no afecta a los colores totalmente opacos, a menos que la propiedad QCustom3DVolume::preserveOpacity esté establecida en false.

Una forma alternativa de ajustar la transparencia del volumen es ajustar directamente los valores alfa de los vóxeles. Para texturas indexadas de ocho bits, esto se hace simplemente modificando y reseteando la tabla de colores:

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 de Alta Definición vs. Shader de Baja Definición

Por defecto, el renderizado volumétrico utiliza un shader de alta definición. Tiene en cuenta cada vóxel del volumen con el peso correcto al trazar el contenido del volumen, proporcionando una representación precisa incluso de los detalles más finos del volumen. Sin embargo, esto es muy costoso desde el punto de vista computacional, por lo que la velocidad de fotogramas se resiente. Si la velocidad de renderizado es más importante que la precisión de píxel del contenido del volumen, utilice el sombreador de baja definición, mucho más rápido, configurando la propiedad QCustom3DVolume::useHighDefShader false . El shader de baja definición consigue la velocidad haciendo concesiones en la precisión, por lo que no garantiza que cada vóxel del volumen sea muestreado. Esto puede llevar a parpadeos u otros artefactos de renderizado en los detalles más finos del volumen.

m_volumeItem->setUseHighDefShader(enabled);

Contenido de ejemplo

Proyecto de ejemplo @ 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.