2012-02-19 3 views
0

Чтобы предисловие к этому, я пытаюсь воспроизвести алгоритм рендеринга воды, описанный в этой статье http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter19.html. Часть этого алгоритма требует рендеринга альфа-маски в фреймбуфер, чтобы позднее использовать для выборки текстур из первоначально рендерированной сцены. Короче говоря, алгоритм выглядит следующим образом:WebGL рендеринг текстуры - как я могу записать данные в альфа-канал?

  1. Рендер геометрию сцены в текстуру S, пропуская рефракции сетки и заменить его с альфа маски
  2. визуализации рефракции сетки путем выборки текстуры S с возмущением IF это внутри альфа-маски, в противном случае просто непосредственно образец текстуры S

к сожалению, я все еще учусь WebGL и на самом деле не знаю достаточно, чтобы знать, как подойти к этому , Кроме того, в этой статье используется HLSL, и преобразование для меня нетривиально. Очевидно, что попытки сделать это в пиксельный шейдер не будет работать:

void main(void) { 
    gl_FragColor = vec4(0.0); 
} 

потому, что она будет просто смешать с ранее оказанной геометрии и альфа-значение равно будет 1,0.

Вот краткий обзор того, что у меня есть:

function animate(){ 
    ... snip ... 
    renderer.render(scene, camera, rtTexture, true); 

    renderer.render(screenScene, screenCamera); 
} 

// water fragment shader 
void main(void){ 
    // black out the alpha channel 
    gl_FragColor = vec4(0.0); 
} 

// screen fragment shader 
varying vec2 vUv; 
uniform sampler2D screenTex; 

void main(void) { 
    gl_FragColor = texture2D(screenTex, vUv); 

    // just trying to see what the alpha mask would look like 
    if(gl_FragColor.a < 0.1){ 
     gl_FragColor.b = 1.0; 
    } 
} 

Весь код можно найти на http://scottrabin.github.com/Terrain/

ответ

0

Очевидно, что попытки сделать это в пиксельный шейдер не будет работать: , потому что он будет просто смешаться с ранее обработанной геометрией, а значение альфа будет равно 1.0.

Это зависит от вас. Просто используйте соответствующие режимы смешивания:

glBlendFuncSeparate(..., ..., GL_ONE, GL_ZERO); 

glBlendFuncSeparate устанавливает отдельное наложение для частей RGB и альфа цвета. В этом случае он записывает исходную альфа непосредственно в пункт назначения.

Обратите внимание, что если вы рисуете что-то непрозрачное, вам не нужны режимы наложения. Выходная альфа будет записана так же, как и цвет.

+0

Я использую Three.js и вызывая 'renderer.context.blendFuncSeparate (gl.ONE, gl.ZERO, gl.ONE, gl.ZERO)' не делает шейдер фрагмента экрана визуализированным синим цветом по желанию , GL spec также говорит, что вы должны включить GL_BLEND, который ничего не изменил, когда я тоже это положил. Я что-то там пропал? –