ボリューメトリック・レンダリング

ボリューメトリック オブジェクトのレンダリング

ボリューメトリック・レンダリングではQCustom3DVolume を使用してボリューメトリック・データを表示する方法を示します。

例を実行する

Qt Creator からサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Example を参照してください。

ボリューム項目の初期化

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

ボリュームへのスライス

ボリュームの大部分が透明でない限り、ボリュームの表面しか見ることができません。ボリュームの内部構造を調べる1つの方法は、ボリュームのスライスを表示することです。QCustom3DVolume 、スライスを表示する2つの方法があります。1つ目は、ボリュームの代わりに選択したスライスを表示する方法です。例えば、X軸に垂直なスライスを指定するには、以下の方法を使用します:

m_volumeItem->setSliceIndexX(m_sliceIndexX);

上記で指定したスライスを表示するには、QCustom3DVolume::drawSlices プロパティも設定する必要があります:

m_volumeItem->setDrawSlices(true);

スライスを表示する 2 番目の方法は、QCustom3DVolume::renderSlice() メソッドを使用することです。 メソッドは、指定されたスライスからQImage を生成します。この画像は、QLabel などの別のウィジェットに表示できます:

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

ボリュームの透明度を調整する

スライスだけを見ても、ボリュームの内部構造がよくわからないことがあります。QCustom3DVolume は、ボリュームの透明度を調整するために使用できる2つのプロパティを提供しています:

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

QCustom3DVolume::alphaMultiplier は、ボリュームの各ボクセルのアルファ値に適用される一般的な乗数です。これにより、ボリュームのすでにある程度透明な部分に均一な透明度を追加して、内部の不透明な詳細を明らかにすることができます。この乗数は、QCustom3DVolume::preserveOpacity プロパティがfalse に設定されていない限り、完全に不透明な色には影響しません。

ボリュームの透明度を調整する別の方法は、ボクセルのアルファ値を直接調整することです。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);

コンテンツ例

サンプルプロジェクト @ code.qt.io

©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。