本文介绍了使用three.js遮挡真实对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实验性的增强现实网络浏览器中使用three.js. (该浏览器称为Argon.本质上,Argon使用高通公司的Vuforia AR SDK跟踪电话摄像头中的图像和对象.Argon将跟踪信息发送到Javascript中,在Javascript中,它使用带有three.js的透明网页在顶部创建3D图形.电话视频供稿.)不过,我的问题是关于three.js.

Argon发送到网页中的数据使我可以将3D摄像头与物理电话摄像头对齐,并绘制3D图形,以使它们看起来与真实世界一致.我还想让物理世界中的某些事物遮挡3D图形(我拥有物理对象的3D模型,因为我已经设置了场景,或者因为它们是准备好的对象,例如Vuforia正在跟踪的盒子).

我想知道人们是否对three.js提出了实现这种遮挡的最佳方法的建议.谢谢.

解决方案

看来下一个版本的three.js(R71)将具有更简单的方法,因此,如果可以使用dev分支(或只是等待),您可以更轻松地完成此操作.看到这篇文章: three.js透明对象遮挡


我的原始答案(不使用R71中的新功能):

我认为最好的方法是(例如,通过创建新的渲染过程来避免额外的工作)修改WebGL渲染器(src/renderers/WebGLRenderer.js)并添加对新型对象的支持,也许称它们为"occlusionObjects".

如果您在渲染器中查看,则会看到两个当前对象列表,即opaqueObjects和transparentObjects.渲染器将​​可渲染对象分类到这两个列表中,以便它可以首先渲染不透明对象,然后再渲染不透明对象.您需要做的是将所有新对象存储在occlusionObjects列表中,而不是将这两个对象存储到occlusionObjects列表中.您将看到不透明和透明对象是根据其材料属性排序的.我认为在这里,您可能想向要成为遮挡物的对象添加一个属性(也许是"myObject.occluder = true"),然后将这些对象拉出来.

一旦有了三个列表,就可以看看render()函数对这些对象列表的作用.您会在几个地方看到这样的渲染调用:

renderObjects( opaqueObjects, camera, lights, fog, true, material );

在该行之前添加类似的内容,以关闭对颜色缓冲区的写入,仅将遮挡对象渲染到深度缓冲区中,然后在渲染其余对象之前重新打开颜色缓冲区写入.

context.colorMask( false, false, false, false);
renderObjects( occluderObjects, camera, lights, fog, true, material );
context.colorMask(true, true, true, true);

您需要在几个地方进行此操作,但这应该可以工作.

现在,您只需将场景中的任何对象标记为"occluder = true",它们将仅渲染到深度缓冲区中,从而使视频能够透彻显示并遮盖在它们后面渲染的任何不透明或透明对象.

I’m using three.js inside an experimental augmented-reality web browser. (The browser is called Argon. Essentially, Argon uses Qualcomm’s Vuforia AR SDK to track images and objects in the phone camera. Argon sends the tracking information into Javascript, where it uses transparent web pages with three.js to create 3D graphics on top of the phone video feed.) My question is about three.js, however.

The data Argon sends into the web page allows me to align the 3D camera with the physical phone camera and draw 3D graphics such that they appear to align with the real world as expected. I would also like to have some of the things in the physical world occlude the 3D graphics (I have 3D models of the physical objects, because I’ve set the scene up or because they are prepared objects like boxes that are being tracked by Vuforia).

I’m wondering if folks have suggestions on the best way to accomplish this occlusion with three.js. Thanks.

解决方案

EDIT: it appears that the next version of three.js (R71) will have a simpler way to do this, so if you can use the dev branch (or just wait), you can do this much more easily. See this post: three.js transparent object occlusion


MY ORIGINAL ANSWER (without using the new features in R71):

I think the best way to do this is (to avoid extra work by creating new rendering passes for example) to modify the WebGL renderer (src/renderers/WebGLRenderer.js) and add support for a new kind of object, perhaps call them "occlusionObjects".

If you look in the renderer, you will see two current object lists, opaqueObjects and transparentObjects. The renderer sorts the renderable objects into these two lists, so that it can render the opaque objects first, and then the transparent objects after them. What you need to do is store all of your new objects into the occlusionObjects list rather than those two. You will see that the opaque and transparent objects are sorted based on their material properties. I think here, you may want to add a property to an object you want to be an occluder ("myObject.occluder = true", perhaps), and just pull those objects out.

Once you have the three lists, look what the render() function does with these object lists. You’ll see a couple of places with rendering calls like this:

renderObjects( opaqueObjects, camera, lights, fog, true, material );

Add something like this before that line, to turn off writing into the color buffers, render the occlusion objects into the depth buffer only, and then turn color buffer writes back on before you render the remaining objects.

context.colorMask( false, false, false, false);
renderObjects( occluderObjects, camera, lights, fog, true, material );
context.colorMask(true, true, true, true);

You’ll need to do this in a couple of places, but it should work.

Now you can just mark any objects in your scene as "occluder = true" and they will only render into the depth buffer, allowing the video to show through and occluding any opaque or transparent objects rendered behind them.

这篇关于使用three.js遮挡真实对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 03:08