2013-06-22 2 views
3

У меня есть 3D-шар в браузере, теперь я хочу выкопать отверстие на нем, чтобы увидеть его обратно.WebGL: Как сделать часть объекта прозрачной?

Как я могу сделать это возможным?

Например, я хочу, чтобы часть белого кубика была прозрачной (я имею в виду, что мы могли видеть фон за кубом).

enter image description here

Я попытался изменить альфа в пиксельный шейдер (область в коде есть квадрат не треугольник, не имеет значения):

<script id="shader-fs-alpha" type="x-shader/x-fragment"> 
    precision mediump float; 

    varying vec4 vColor; 

    uniform float uAlpha; 

    void main(void) { 
     if(gl_FragCoord.x < 350.0 && gl_FragCoord.x > 300.0 
     && gl_FragCoord.y < 300.0 && gl_FragCoord.y > 230.0 
     ) { 
     gl_FragColor = vec4(0, 0 ,0, 0.0); 
     } else { 
     gl_FragColor = vec4(vColor.rgb, 1.0); 
     } 
    } 
</script> 

Это на самом деле работает, но область становится белой (не прозрачной), поэтому я попытался включить смешивание, но это делает весь куб прозрачным.

Так что теперь я подумал, что есть способ включить bleanding в флеш-шейдере, и я мог бы отключить его в блоке else.

Вот весь мой проект https://gist.github.com/royguo/5873503:

  • index.html: Shader скрипт здесь.
  • buffers.js: Все объекты здесь.
  • shaders.js: Init шейдеры.

ответ

0

Или удалите некоторые треугольники из шаровой сетки или нанесите на него текстуру с прозрачными частями, включите смешение и отключите любой тип отбраковки, чтобы вы не потеряли обратные треугольники.

EDIT:

Вот учебник по гармонирующий WebGL: http://learningwebgl.com/blog/?p=859 У вас есть несколько режимов, чтобы выбрать из того, как два пикселя будет мне смешано, и путем изменения значения альфа вы можете иметь все, что вы хотите.

В конце концов вы применяете текстуру, которая имеет альфа, установленную в 1.0 везде, кроме тех частей, где она должна быть «полая», а затем разрешать смешивание. Надеюсь, я поняла.

СОВЕТ. Вместо чтения документации (которая иногда может быть более запутанной, чем помогая), попробуйте это http://www.nihilogic.dk/labs/webgl_cheat_sheet/WebGL_Cheat_Sheet.htm,. Он перечисляет все функции очень красиво.

+0

Не могли бы вы предоставить более подробную информацию? Мне очень нужна ваша помощь, спасибо! – MrROY

+0

отредактировал ответ немного. –

1

Вы можете отобразить часть сцены без объекта (или объектов внутри) текстуры, а затем проецировать текстуру на поверхность перед объектом. Просто убедитесь, что поверхность непосредственно обращена к камере (параллельна плоскости x-y в пространстве кулачка) и что текстура визуализируется с тем же центром и перспективой, что и экран.

Используйте Learning WebGL: Rendering to Textures, если вам нужна помощь в этом. Вы также должны проверить параметры освещения, чтобы убедиться, что на поверхность не влияет освещение, которое получает ваш объект.

также: official WebGL reference sheet

4

Вы должны использовать буфера трафарета. 2 шага: один, нарисуйте треугольник на трафарете. Два, нарисуйте куб с помощью теста трафарета.

// you can use this code multiple time without clearing stencil 
// just increment mask_id 
mask_id = 1; 

// allow to draw inside or outside mask 
invert_mask = false; 

1) Включить буфер трафарета. не настроить его: нет тестирования и написать mask_id значение

glEnable(GL_STENCIL_TEST); 
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); 
glStencilFunc(GL_ALWAYS, mask_id, 0); 

2) удаления цвета & глубины писать

glDepthMask(GL_FALSE); 
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 

3) здесь нарисовать свой треугольник :)

4) Enabled глубина & цвета письменность куб

glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
glDepthMask(GL_TRUE); 

5) Настроить не трафарет для куба: нет записи и тестового значения трафарета

glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 
glStencilFunc(invert_mask ? GL_NOTEQUAL : GL_EQUAL, mask_id, 0xff); 

6) здесь сделать свой куб :)

7) Очистка: удалить тест трафарета

glDisable(GL_STENCIL_TEST); 

Не забудьте запросить трафарет при создании контекста opengl (см. WebGLContextAttributes, второй параметр getContext)

Этот код хорошо работает с Opengl ES 2 на платформе Ios. Это не зависело от какого-либо расширения. WebGL использует тот же API.

Единственный небольшой дефект: нет msaa на границах треугольника. Там нет никакого свободного обеда :)

1

попробуйте добавить эти строки

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

Он работал для меня с OpenGL ES.