1

GLSL を使用したボリューム レンダリングに問題があります。ソース コードは、次のリンクhttps://github.com/toolchainX/Volume_Rendering_Using_GLSLにあります。という名前のフラグメントシェーダーではraycasting.frag、sampler1DTransferFuncが表示されますが、実際の機能 (使い方や意味) はわかりませんTransferFunc。以下、raycasting.frag の詳細です。

具体的なコードは次のとおりです。

#version 400
in vec3 EntryPoint;
in vec4 ExitPointCoord;

uniform sampler2D ExitPoints;
uniform sampler3D VolumeTex;
uniform sampler1D TransferFunc;  
uniform float     StepSize;
uniform vec2      ScreenSize;
layout (location = 0) out vec4 FragColor;

void main()
{
    // ExitPointCoord 的坐标是设备规范化坐标
    // 出现了和纹理坐标有关的问题。
    vec3 exitPoint = texture(ExitPoints, gl_FragCoord.st/ScreenSize).xyz;
    // that will actually give you clip-space coordinates rather than
    // normalised device coordinates, since you're not performing the perspective
    // division which happens during the rasterisation process (between the vertex
    // shader and fragment shader
    // vec2 exitFragCoord = (ExitPointCoord.xy / ExitPointCoord.w + 1.0)/2.0;
    // vec3 exitPoint  = texture(ExitPoints, exitFragCoord).xyz;
    if (EntryPoint == exitPoint)
        //background need no raycasting
        discard;
    vec3 dir = exitPoint - EntryPoint;
    float len = length(dir); // the length from front to back is calculated and used to terminate the ray
    vec3 deltaDir = normalize(dir) * StepSize;
    float deltaDirLen = length(deltaDir);
    vec3 voxelCoord = EntryPoint;
    vec4 colorAcum = vec4(0.0); // The dest color
    float alphaAcum = 0.0;                // The  dest alpha for blending
    /* 定义颜色查找的坐标 */
    float intensity;
    float lengthAcum = 0.0;
    vec4 colorSample; // The src color 
    float alphaSample; // The src alpha
    // backgroundColor
    vec4 bgColor = vec4(1.0, 1.0, 1.0, 0.0);

    for(int i = 0; i < 1600; i++){
        // 获得体数据中的标量值scaler value
        intensity =  texture(VolumeTex, voxelCoord).x;
        // 查找传输函数中映射后的值
        // 依赖性纹理读取  
        colorSample = texture(TransferFunc, intensity);
        // modulate the value of colorSample.a
        // front-to-back integration
        if (colorSample.a > 0.0) {
            // accomodate for variable sampling rates (base interval defined by mod_compositing.frag)
            colorSample.a = 1.0 - pow(1.0 - colorSample.a, StepSize*200.0f);
            colorAcum.rgb += (1.0 - colorAcum.a) * colorSample.rgb * colorSample.a;
            colorAcum.a += (1.0 - colorAcum.a) * colorSample.a;
        }
        voxelCoord += deltaDir;
        lengthAcum += deltaDirLen;
        if (lengthAcum >= len ){    
            colorAcum.rgb = colorAcum.rgb*colorAcum.a + (1 - colorAcum.a)*bgColor.rgb;      
            break;  // terminate if opacity > 1 or the ray is outside the volume    
        }else if (colorAcum.a > 1.0){
            colorAcum.a = 1.0;
            break;
        }
    }
    FragColor = colorAcum;
    // for test
    // FragColor = vec4(EntryPoint, 1.0);
    // FragColor = vec4(exitPoint, 1.0);

}

問題の解決にご協力いただければ幸いです。ありがとうございました!

4

1 に答える 1

0

伝達関数は、3D ボリューム データセットの強度を色にマッピングする方法を決定します。

医用画像などの多くの 3D データセットには、ボクセルごとに 1 つの値が含まれています。たとえば、CT スキャンの場合、これは X 線の吸収量になります (少なくとも、それは私が考えていることです...)。

3D データセットをレンダリングするとき、さまざまな強度をさまざまな色としてエンコードする必要があります。それが伝達関数です。1D テクスチャを使用して伝達関数をエンコードする場合、このテクスチャには、可能な強度値ごとに RGBA カラーが含まれます。

これらの伝達関数は、結果の画像の見栄えを良くしたり便利にしたりするために必要なものであれば何でもかまいません。非常に典型的な伝達関数の形式は次のとおりです。

  • 特定の強度値を下回ると、完全に透明 (アルファ = 0.0) になります。
  • それを超える値の範囲に対して、アルファが 0.0 から 1.0 まで増加する線形ランプ。最良の視覚的結果を得るために、これには多くの場合、3 つの異なる色の使用が含まれます。たとえば、黒はアルファ = 0.0、赤はアルファ = 0.5、白はアルファ = 1.0 で、これらの値の間で色が補間されます。
  • その上は完全に不透明 (アルファ = 1.0) です。

画像データが DICOM ファイルから読み取られる場合、伝達関数のこれらのさまざまな部分に使用する必要がある値の範囲を示すタグを含めることができます。

于 2016-09-04T05:25:47.330 に答える