2016-09-04 12 views
1

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

具体的なコードは次のとおりです。colorSample = texture(TransferFunc、intensity);

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

} 

私はこの問題を解決するのに役立ちます。ありがとうございました!

答えて

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ファイルから読み取られる場合、転送機能のこれらの異なる部分に使用される値の範囲を示すタグを含めることができます。

+0

ありがとうございました。質問があります。強度が0〜255の範囲にある場合は、伝達関数は必要ありません。さらに、私の仕事はDICOMファイルと関係があり、DICOMファイルに精通しているようです。詳細な質問をするために電子メールを送れますか?ありがとうございました! – Hurricane

+0

@ハリケーン:それは解釈の問題です。あなたは***それぞれのボクセルの強度をグレイスケールに直接写像できますが、それは既に伝達関数、つまり各カラーチャンネルのアイデンティティの適用です。 – thokra

+0

@thokra:ありがとう! – Hurricane

関連する問題