如何在three.js中使用深度缓冲区屏蔽对象
How do I mask objects using the depth buffer in three.js?
我正在用three.js编写一个2D游戏。首先,我想渲染背景场景。然后,我想渲染一个透明四边形(opacity === 0
),即使您看不到它,它仍然会将值写入深度缓冲区。然后,我想渲染后面有z的对象,z将它们的片段放在透明四边形后面,这样任何与透明四边形具有相同屏幕空间位置的片段都会因为深度测试失败而被丢弃。
根据我对OpenGL的理解,这是可能的,但当透明四边形的碎片着色器的输出具有gl_FragColor.a === 0
时,three.js似乎没有为透明四边形写入深度值。
我已经设置了renderer.sortObjects = false
。我在z = 0
处有背景,在z = 1
处有透明四边形,并且在z = 0.5
处有要被深度缓冲区屏蔽的对象。
对于透明四边形,我设置了material.transparent = false
,但它显示的不是透明四边形上的背景景色,而是清晰的颜色。
以下是我如何创建透明四边形:
let uniforms = {
color: {
type: 'v4',
value: new three.Vector4(0.2, 0.8, 0.8, 1),
},
opacity: {
type: 'f',
value: 1,
},
region_left: {
type: 'f',
value: -1,
},
region_right: {
type: 'f',
value: -1,
},
region_top: {
type: 'f',
value: -1,
},
region_bottom: {
type: 'f',
value: -1,
},
}
let vertex_shader =
`varying vec2 screen_space_position;
void main()
{
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
screen_space_position = mvPosition.xy;
gl_Position = projectionMatrix * mvPosition;
}`
let fragment_shader =
`uniform vec4 color;
uniform float opacity;
uniform float region_left;
uniform float region_right;
uniform float region_top;
uniform float region_bottom;
varying vec2 screen_space_position;
void main()
{
// The following just checks a 2D box I've defined in 'screen space'
// (really it's camera space, but I'm using an ortho camera where units
// are pixels) and sets the opacity to zero if the fragment is inside
// it.
float final_opacity = opacity;
vec2 position = screen_space_position;
if (position.x >= region_left && position.x <= region_right &&
position.y >= region_top && position.y <= region_bottom)
{
final_opacity = 0.0;
}
gl_FragColor = vec4(color.rgb, color.a * final_opacity);
// I also tried just bypassing the above code and rendering 0 alpha
// across the entire quad
//gl_FragColor = vec4(1, 1, 1, 0);
}`
// Create geometry that represents a quad
let geometry = new three.PlaneGeometry(1, 1)
// PlaneGeometry assumes the lower left corner is (0, 0). This makes it
// so the upper left corner is (0, 0).
geometry.scale(1, -1, 1)
let material = new three.ShaderMaterial({
uniforms,
vertexShader: vertex_shader,
fragmentShader: fragment_shader,
transparent: true,
})
let mesh = new three.Mesh(geometry, material)
// Center the mesh
mesh.position.set(0.5, 0.5, 0)
let root = new three.Object3D()
root.add(mesh)
以下从r73
开始工作。小心控制three.Mesh
、renderOrder
和position
属性是解决方案。
首先,我通过删除renderer.sortObjects = false
行重新打开排序。其次,我确保要遮罩的对象的z
位置将它们放置在透明四边形后面。
最后,我为我想要遮罩的每个场景对象的three.Mesh
对象设置了mesh.renderOrder = 1
(即,在使用renderOrder < 1
的任何其他网格之后渲染该网格),为透明四边形设置了mesh.renderOrder = 0.5
。renderOrder
的默认值为0
,因此在透明四边形和遮罩对象之前,任何网格的renderOrder
I都没有明确地将渲染设置为正常。
请注意,必须为每个网格设置renderOrder
。此属性不会传播到子Object3D
对象。
- 在不知道深度或父属性的情况下从对象中删除属性
- 递归深度比较
- 如何对映射插件创建的敲除对象进行深度复制
- 3d上的深度比例错误
- 将对象从另一个不可变的Map分配给Map是否意味着深度克隆
- 从媒体源源缓冲区动态附加和删除mpeg短划线段
- Node.js服务器和浏览器之间共享二进制缓冲区
- 将ajax数组缓冲区响应绘制到画布中
- BatmanJS:深度嵌套路由
- Chai深度包含了对嵌套对象的断言
- javascript对象值的动态深度访问
- 与 lodash 进行对象深度比较的数组
- 重置剑道日期选择器的深度
- JavaScript中的深度嵌套函数
- 如何在JSDoc中记录深度大于2的符号
- 深度嵌套的backbone.js对象会导致错误
- Javascript 深度对象相等时,对象通过 json 字符串与生成器创建
- 通过WEBGL_depth_texture渲染缓冲区对象和深度纹理之间的区别是什么
- 如何渲染具有位移顶点的对象的深度缓冲区
- 如何在three.js中使用深度缓冲区屏蔽对象