Какова функция TransferFunc при объемном рендеринге с использованием GLSL?

У меня проблема с объемным рендерингом с использованием GLSL. Исходный код можно найти по следующей ссылке https://github.com/toolchainX/Volume_Rendering_Using_GLSL. Во фрагментном шейдере с именем raycasting.frag появляется sampler1D TransferFunc, но я не знаю фактической функции (использования или значения) TransferFunc. Ниже приведены подробности о raycasting.frag.

И конкретный код: colorSample = texture(TransferFunc, интенсивность);

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

}

Я надеюсь, что вы можете помочь мне решить проблему. Благодарю вас!


person Hurricane    schedule 04.09.2016    source источник


Ответы (1)


Передаточная функция определяет, как интенсивность из набора данных 3D-объема сопоставляется с цветом.

Многие наборы 3D-данных, например, из медицинских изображений, содержат одно значение для каждого вокселя. Например, для компьютерной томографии это будет степень поглощения рентгеновского излучения (по крайней мере, я так думаю...).

Когда вы визуализируете набор 3D-данных, вы хотите кодировать разные интенсивности как разные цвета. Вот что делает передаточная функция. Если вы используете одномерную текстуру для кодирования передаточной функции, эта текстура будет содержать цвет RGBA для каждого возможного значения интенсивности.

Эти передаточные функции могут быть чем угодно, чтобы итоговое изображение выглядело хорошо/полезно. Очень типичные передаточные функции имеют вид:

  • Полностью прозрачный (альфа = 0,0) ниже определенного значения интенсивности.
  • Линейная рампа с увеличением альфа от 0,0 до 1,0 для диапазона значений выше этого. Для достижения наилучших визуальных результатов это часто включает использование 3 разных цветов. Например, черный при альфа = 0,0, красный при альфа = 0,5 и белый при альфа = 1,0 с интерполяцией цветов между этими значениями.
  • Полностью непрозрачный (альфа = 1,0) выше этого.

Если ваши данные изображения считываются из файла DICOM, они могут содержать теги, которые сообщают вам диапазон значений, которые следует использовать для этих различных частей передаточной функции.

person Reto Koradi    schedule 04.09.2016
comment
Большое спасибо. У меня есть вопрос. Если интенсивность находится в диапазоне: от 0 до 255, передаточные функции не нужны, я прав? Более того, моя работа как-то связана с файлами DICOM, и кажется, что вы знакомы с файлами DICOM. Могу ли я получить вашу электронную почту, чтобы задать вам несколько подробных вопросов? Благодарю вас! - person Hurricane; 04.09.2016
comment
@Hurricane: это вопрос интерпретации. Вы можете сопоставить интенсивность каждого вокселя непосредственно с шкалой серого, но даже это уже является применением передаточной функции, а именно идентичности для каждого цветового канала. - person thokra; 05.09.2016
comment
@thokra: Большое спасибо! - person Hurricane; 05.09.2016
comment
@Hurricane Согласен с токрой, можешь попробовать. В зависимости от данных вы получите что-то, что выглядит несколько разумным, или может случиться так, что неинтересные части с низкой интенсивностью скроют всю интересную структуру данных. Выбор хорошей передаточной функции имеет решающее значение для получения действительно красивого объемного рендеринга. - person Reto Koradi; 05.09.2016
comment
@Hurricane Я бы не хотел публиковать здесь свой адрес электронной почты. Хотя догадаться довольно легко... Если хотите, можете связаться с LinkedIn. - person Reto Koradi; 05.09.2016
comment
@RetoKoradi: Хотя довольно легко догадаться, что это значит? А что такое LinkedIn? Благодарю вас! - person Hurricane; 06.09.2016
comment
@Hurricane Вы никогда не слышали о LinkedIn? Это профессиональная сеть, насчитывающая более 400 миллионов участников. Среди прочего, он стал одним из основных мест, где происходит найм на технические должности. - person Reto Koradi; 06.09.2016
comment
@RetoKoradi: Поскольку я китаец, я никогда не слышал о LinkedIn. Но я хочу кое-чему у вас научиться. Не могли бы вы сказать мне, как я могу связаться с вами в LinkedIn? - person Hurricane; 07.09.2016