Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用three.js中的深度缓冲区屏蔽对象?_Javascript_Three.js_Webgl - Fatal编程技术网

Javascript 如何使用three.js中的深度缓冲区屏蔽对象?

Javascript 如何使用three.js中的深度缓冲区屏蔽对象?,javascript,three.js,webgl,Javascript,Three.js,Webgl,我正在用three.js编写一个2D游戏。首先,我想渲染背景风景。然后,我想渲染一个透明的四元(不透明度===0),即使您看不到它,它仍然会将值写入深度缓冲区。然后,我想渲染后面有z的对象,该z将其碎片放置在透明四边形后面,这样,由于深度测试失败,任何与透明四边形具有相同屏幕空间位置的碎片都会被丢弃 根据我对OpenGL的理解,这是可能的,但当我的透明四边形的片段着色器的输出具有gl\u FragColor.a==0时,three.js似乎没有为我的透明四边形写入深度值 我已经设置了render

我正在用three.js编写一个2D游戏。首先,我想渲染背景风景。然后,我想渲染一个透明的四元(
不透明度===0
),即使您看不到它,它仍然会将值写入深度缓冲区。然后,我想渲染后面有z的对象,该z将其碎片放置在透明四边形后面,这样,由于深度测试失败,任何与透明四边形具有相同屏幕空间位置的碎片都会被丢弃

根据我对OpenGL的理解,这是可能的,但当我的透明四边形的片段着色器的输出具有
gl\u 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)
let制服={
颜色:{
键入:“v4”,
值:新的三个矢量4(0.2,0.8,0.8,1),
},
不透明度:{
类型:“f”,
价值:1,
},
左区:{
类型:“f”,
值:-1,
},
地区(右):{
类型:“f”,
值:-1,
},
地区(顶部):{
类型:“f”,
值:-1,
},
地区(下):{
类型:“f”,
值:-1,
},
}
让顶点着色=
`改变vec2屏幕空间位置;
void main()
{
vec4 mvPosition=modelViewMatrix*vec4(位置,1.0);
屏幕空间位置=mvPosition.xy;
gl_位置=投影矩阵*mvPosition;
}`
让我们来看看这个着色器=
`vec4颜色均匀;
均匀浮动不透明度;
均匀浮动区域_左;
均匀浮动区域_右;
均匀浮动区_顶;
底部均匀浮动区域;
改变vec2屏幕空间位置;
void main()
{
//下面只检查我在“屏幕空间”中定义的2D框
//(实际上,这是相机空间,但我使用的是正交相机
//是像素)并将不透明度设置为零(如果碎片在内部)
//它。
浮动最终不透明度=不透明度;
vec2位置=屏幕空间位置;

如果(position.x>=region\u left&&position.x=region\u top&&position.y以下操作从
r73
起生效。仔细控制
三个.Mesh
渲染器
位置
属性是解决方案

首先,我通过删除
renderer.sortObjects=false
行重新启用排序。其次,我确保要遮罩的对象的
z
位置将它们放置在透明四边形后面

最后,我设置
mesh.renderOrder=1
(即使用
renderOrder<1
在任何其他网格之后渲染此网格)对于我想要遮罩的每个场景对象的
三个.Mesh
对象,以及透明四边形的
Mesh.renderder=0.5
renderder
的默认值是
0
,因此在透明四边形和遮罩之前,任何网格的
renderder
我没有显式地将渲染设置为正常d对象


请注意,必须为每个网格设置
renderOrder
。此属性不会传播到子
Object3D
对象。

也许三个.js的默认autoClearDepth=true是由零alpha触发的?文档中不清楚从深度缓冲区中删除对象的测试是什么。