html - WebGL : How do make part of an object transparent?

标签 html opengl-es 3d webgl

我在浏览器中有一个 3D 球,现在我想在它上面挖一个洞看看它的背面。

我怎样才能让它成为可能?

例如,我希望立方体的白色三角形部分可以是透明的(我的意思是我们可以看到立方体后面的背景)。

enter image description here

我试图改变片段着色器中的 alpha(代码中的区域是正方形而不是三角形,没关系):

<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>

这确实有效,但该区域变成白色(不透明),所以我尝试启用混合,但这会使整个立方体透明。

所以现在我想是否有办法在片段着色器中启用混合,并且我可以在else block 中禁用它。

这是我的整个项目 https://gist.github.com/royguo/5873503 :

  • index.html:此处为着色器脚本。
  • buffers.js :所有对象都在这里。
  • shaders.js :初始化着色器。

最佳答案

您应该使用模板缓冲区。 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) 启用立方体的深度和颜色书写

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

5)为cube配置stencil:不写测试stencil值

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 的第二个参数)

此代码在 Ios 平台上与 Opengl ES 2 一起运行良好。它不依赖于任何扩展。 WebGL 使用相同的 API。

唯一的小缺陷:三角形边界没有msaa。天下没有免费的午餐:)

关于html - WebGL : How do make part of an object transparent?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17253718/

相关文章:

jquery - 将 sibling 分组到一个div中

javascript - 可点击的表格行

计算 3D 网格的表面积

ios - 尽管锁定了显示方向,如何检测设备旋转?

wpf - 在 3D 对象 wpf 中放置一个控件

python - 旋转矩形直到碰到三角形,并确定交点

php - 将元素添加到状态更改按钮 Html

html - CSS 断字语言

iphone - OpenGL ES 如何正确组合 Orthof 和 Frustum

ios - 为什么 GL_LINEAR_MIPMAP_LINEAR 给出 INVALID_ENUM 错误?