我在浏览器中有一个 3D 球,现在我想在它上面挖一个洞看看它的背面。
我怎样才能让它成为可能?
例如,我希望立方体的白色三角形部分可以是透明的(我的意思是我们可以看到立方体后面的背景)。
我试图改变片段着色器中的 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/