WebGL рендерится в текстуру - как мне записать данные в альфа-канал? - PullRequest
1 голос
/ 19 февраля 2012

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

  1. Отображение геометрии сцены в текстуру S , пропуская сетки преломления и заменяя ее альфа-маской
  2. Отображение рефракциивыполняет сэмплирование текстуры S с возмущением, ЕСЛИ она находится внутри альфа-маски, в противном случае просто напрямую сэмплируем текстуру 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/

1 Ответ

0 голосов
/ 19 февраля 2012

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

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

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

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

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

...