2016-09-18 11 views
2

This вводит метод Volume Rendering с использованием устаревшего API OpenGL. Но теперь я хочу завершить рендеринг тома с помощью GLSL, и я закончил некоторые его части. Мой вопрос - как это сделать. В приведенной выше ссылке смешивание заполняется следующими кодами:Как сделать смешение в Volume Rendering с помощью GLSL?

glEnable(GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

Но как можно закончить смешивание с использованием GLSL?

Я попытался с помощью следующего уравнения:

C = Cs*As + Cd(1 - As) 

Cs это цвет исходного объекта. Cd - цвет целевого объекта. Как и альфа исходного объекта. И мой код в пиксельный шейдер выглядит следующим образом:

...... 
vec3 dir = backPoint - frontPoint; 
float len = length(dir); 
float stepSize = 0.01; 
vec3 deltaDir = normalize(dir)*stepSize; 
float deltaLen = length(deltaDir); 
float accLen = 0; 
float accAlpha = 0; 
float sampleAlpha = 0; 
vec4 accColor = vec4(0.0); 

vec3 samplePoint = frontPoint; 
vec4 sampleColor; 
while(accLen < len && accColor.a <= 1.0){ 
    sampleColor = texture(texture3D, samplePoint); 

    accColor = sampleColor*sampleColor.a + accColor*(1-sampleColor.a); 

    accLen += deltaLen; 
    samplePoint += deltaDir; 
} 
color = accColor; 
...... 

В моем проекте, я позволяю значение г, г, б, а 3D-текстуры, чтобы быть таким же. Но я не могу получить результат одной из приведенных выше ссылок. Можете ли вы помочь мне решить проблему смешивания с помощью GLSL?

+0

Смешивание выполняется самим HW не шейдерами в GLSL, поэтому вы должны оставить «glEnable» и «glBlendFunc» в своем проекте GLSL, как есть, и выводить из фрагментарного шейдера только цвет, чтобы не смешивать уравнение смешивания. Это будет работать только в том случае, если вы будете использовать каждый смешанный примитив как отдельный перенос рендеринга в/из текстуры, который безумно медленный ... если количество примитивов не велико. – Spektre

+0

Например, см. [Мой простой шейдер атмосферного рассеивания в GLSL] (http://stackoverflow.com/a/19659648/2521214), который сочетает в себе родное Blending of gfx card и GLSL-шейдеры (хотя в двухпроходном рендеринге, но это не имеет ничего общего с смешиванием) – Spektre

+1

Это raycasting, и смешивание действительно является частью алгоритма. – kaerimasu

ответ

1

Естественно выполнять вычисления в предварительно умноженном альфа-цветовом пространстве. Он лучше подходит для поглощения излучения объемных явлений. Соответствующие уравнения:

C = Cs + (1 - As)*Cd 
A = 1 - (1 - As)*(1 - Ad) = As + (1 - As)*Ad 

Хотя можно сделать расчеты в не-альфа предварительно умноженные цветового пространства, это потребовало бы деление на альфа-значений и в целом более сложным. (Ваш код работает без предварительно умноженных и не принимает его во внимание ...)

Так в OpenGL настройки смешивания вы используете:

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

и использовать эту формулу в шейдере:

accColor = sampleColor + accColor*(1-sampleColor.a); 

Вы также должны учитывать это при создании трехмерных текстур. Например, текстура, где для всех пикселей R = G = B = A соответствует белому туманному веществу, так что вам нужно посмотреть его на темном фоне.