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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/23.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
Three.js 使用遮罩隐藏对象的一部分(EffectComposer) 问题的描述_Three.js_Mask - Fatal编程技术网

Three.js 使用遮罩隐藏对象的一部分(EffectComposer) 问题的描述

Three.js 使用遮罩隐藏对象的一部分(EffectComposer) 问题的描述,three.js,mask,Three.js,Mask,我目前正在发现的EffectComposer,我正在寻找通过另一个使用遮罩隐藏对象部分的方法 假设你有一个简单的场景:相机和圆柱体之间的立方体。立方体将扮演遮罩的角色,并将圆柱体隐藏在其后面: 测试的溶液 我已经使用了以下ThreeJS示例,并尝试调整它们以获得我想要的结果,但没有成功: 我想问题在于传球的使用 我尝试了两种解决方案(查看下面的代码片段以了解添加的过程的类型): 1-添加遮罩类,然后添加渲染类,以便仅在遮罩内绘制场景的渲染 composer = new THREE.

我目前正在发现的
EffectComposer
,我正在寻找通过另一个使用遮罩隐藏对象部分的方法

假设你有一个简单的场景:相机和圆柱体之间的立方体。立方体将扮演遮罩的角色,并将圆柱体隐藏在其后面:

测试的溶液 我已经使用了以下ThreeJS示例,并尝试调整它们以获得我想要的结果,但没有成功:

我想问题在于传球的使用

我尝试了两种解决方案(查看下面的代码片段以了解添加的过程的类型):

1-添加遮罩类,然后添加渲染类,以便仅在遮罩内绘制场景的渲染

  composer = new THREE.EffectComposer(renderer, renderTarget);
  composer.addPass(maskPass1);
  composer.addPass(renderPass);
  composer.addPass(clearMaskPass);
  composer.addPass(outputPass);
2-添加渲染过程,然后添加反转遮罩和clearPass以移除像素

  maskPass1.inverse = true;
  composer = new THREE.EffectComposer(renderer, renderTarget);
  composer.addPass(renderPass);
  composer.addPass(maskPass1);
  composer.addPass(clearPass);
  composer.addPass(clearMaskPass);
  composer.addPass(outputPass);
在下面,您将看到一个代码片段,显示我到目前为止所做的工作。我使用了
DotScreenPass
来查看maskPass的效果

在下图中,您将在左侧看到我使用代码段得到的结果,在右侧看到我想要的结果

代码片段
var编写器、渲染器;
圆环体变分盒;
init();
制作动画();
函数init(){
//设置渲染器
renderer=new THREE.WebGLRenderer({antialas:false});
renderer.setClearColor(0xE0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth、window.innerHeight);
renderer.autoClear=false;
document.body.appendChild(renderer.doElement);
//设置场景
var摄像机=新的三透视摄像机(50,window.innerWidth/window.innerHeight,11000);
摄像机位置z=10;
var scene1=new THREE.Scene();
var scene2=new THREE.Scene();
//添加对象
box=新的THREE.Mesh(新的THREE.BoxGeometry(4,4,4));
框。旋转(Math.PI/6);
框.rotateX(-Math.PI/6);
场景1.添加(框);
圆环=新的三网格(新的三网格几何体(3,1,16,32),新的三网格基本材质({
颜色:0xff0000
}));
场景2.添加(圆环体);
//为作曲家创建通行证
var clearPass=new THREE.clearPass();
var clearMaskPass=new THREE.clearMaskPass();
var maskPass1=新的三个MaskPass(场景1,摄像头);
var maskPass2=新的三个MaskPass(场景2,摄像头);
maskPass1.inverse=true
var renderPass=new THREE.renderPass(场景2,摄像头);
var screenDotPass=new THREE.DotScreenPass();
var outputPass=new THREE.ShaderPass(THREE.CopyShader);
outputPass.renderToScreen=true;
var renderTarget=new THREE.WebGLRenderTarget(window.innerWidth、window.innerHeight、{
minFilter:THREE.LinearFilter,
磁过滤器:三线过滤器,
格式:THREE.RGBFormat,
模具缓冲区:真
});
//创建编写器并添加过程
composer=new THREE.EffectComposer(渲染器、渲染目标);
作曲家:addPass(renderPass);
作曲家addPass(maskPass1);
作曲家:addPass(screenDotPass);
作曲家addPass(clearMaskPass);
编写器。addPass(outputPass);
}
函数animate(){
请求动画帧(动画);
var time=performance.now()*0.001;
.clear();
作曲者。渲染(时间);
}
正文
{
背景色:#000;
边际:0px;
溢出:隐藏;
}

经过进一步研究,我发现了两种解决方案,但它们没有使用EffectComposer(这对我来说不是问题)

第一个:深度缓冲区(Z缓冲区) 其思路如下:

  • 创建两个场景,第一个包含扮演遮罩角色的对象,另一个包含普通场景
  • 防止渲染器写入颜色缓冲区,仅写入深度缓冲区(z缓冲区)并“渲染”遮罩场景。z缓冲区现在包含遮罩场景的深度信息
  • 启用回写到颜色缓冲区,并渲染正常场景。由于深度比较,无法渲染正常场景的某些片段
  • 谢谢@WestLangley的提问:

    第二种解决方案:模具缓冲区 我没有测试这个解决方案,但是JSFIDLE看起来不错

    见这个问题:

    以及相关的JSFIDLE:

    var composer, renderer;
    var box, sphere;
    var scene1, scene2;
    var camera;
    
    init();
    animate();
    
    function init() {
    
      // Setup renderer
      renderer = new THREE.WebGLRenderer({
        antialias: false
      });
      renderer.setClearColor(0xe5e5e5);
      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setSize(window.innerWidth, window.innerHeight);
    
      // VERY IMPORTANT
      renderer.autoClear = false ;
    
      document.body.appendChild(renderer.domElement);
    
      // Setup scenes
      camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000);
      camera.position.z = 15;
    
      scene1 = new THREE.Scene();
      scene2 = new THREE.Scene();
    
      // Add objects
      box = new THREE.Mesh(new THREE.BoxGeometry(4, 4, 4), new THREE.MeshBasicMaterial({
        color: 0x008800
      }));
      box.rotateY(Math.PI / 6);
      box.rotateX(-Math.PI / 6);
      box.position.z += 1;
      scene1.add(box);
    
      sphere = new THREE.Mesh(new THREE.SphereGeometry(4, 16, 16), new THREE.MeshBasicMaterial({
        color: 0xff0000
      }));
      scene2.add(sphere);
    }
    
    function animate() {
    
      requestAnimationFrame(animate);
    
      // Manually clear the renderer
      renderer.clear();
    
      // Sets which color components to enable or to disable when drawing or rendering to a WebGLFramebuffer
      renderer.context.colorMask(false, false, false, false); // R, G, B, A
      renderer.render(scene1, camera);
    
      // Enable back the writing into the color and alpha component
      renderer.context.colorMask(true, true, true, true);
      renderer.render(scene2, camera);
    
    }