使用three.js渲染透明物体两侧时出现伪影问题

18
我尝试使用three.js渲染透明物体的两侧。位于透明物体内部的其他物体也应该显示出来。不幸的是,我得到了一些似乎无法处理的伪影。以下是一个测试页面:https://dl.dropbox.com/u/3778149/webgl_translucency/test.html 这里有一个所述伪影的图像。它们似乎来自于潜在的球体几何形状。 混合模式为:THREE.AdditiveBlending = 1 的伪影 有趣的是,当混合模式为THREE.SubtractiveBlending = 2时,这些伪影不可见。 输入图像描述 感谢任何帮助!
Alex

请查看此线程:https://github.com/mrdoob/three.js/issues/2476。 - WestLangley
4个回答

18

在WebGL和three.js中,自身透明度特别困难。您需要真正理解问题,然后调整代码以实现所需效果。

使用一个技巧,您可以在three.js中实现双面透明球的外观:您需要渲染两个透明球 -- 一个使用 material.side = THREE.BackSide ,另一个使用 material.side = THREE.FrontSide

如果您想要自身透明度而不产生伪影,尤其是当允许摄像机或对象移动时,则通常需要使用这种方法。

three.js r.143


如果您交叉两个透明对象,也可以获得不同类型的工件(此处演示,以及来自@mrdoob的解释)。 - Drew Noakes
谢谢你提供的示例,非常好。我需要看看是否能够禁用场景中所有对象的排序。关于我的更改 - 你是指哪个小玩意儿?现在你已经将你的小玩意儿更新到r59,随时可以删除我发布的链接,因为它已经没有任何作用了。 - Drew Noakes

5
通常,要创建透明对象,需要按前后顺序对它们进行排序(我猜测three.js已经做到了这一点)。如果您的对象是凸面的(就像这两个对象一样),那么有时可以通过两次渲染每个对象来解决问题,一次使用gl.cullFace(gl.CCW),另一次使用gl.cullFace(gl.CW)。例如,如果立方体在球体内部,则需要执行以下操作:
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.CW);
drawSphere();  // draws the back of the sphere
drawCube();    // draws the back of the cube
gl.cullFace(gl.CCW);
drawCube();    // draws the front of the cube.
drawSphere();  // draws the front of the sphere.

我不知道如何在three.js中实现这个。
这仅处理是凸的且不相交的物体(一个对象完全包含在另一个对象中)。

是的,three.js会相应地对对象进行排序,并且 - 如您所解释的 - 通过使前面和后面成为单独的对象,它们可以从排序中获益。感谢指出凸面和非相交对象的限制。 - arose

0

制作原网格的克隆并翻转其法线;然后为每个克隆网格创建两个相同的“单面”材质,但名称不同。虽然不是最优雅的方法,但它完全可行。我曾经也遇到过同样的问题,这就是我所做的 :P

.json文件看起来像这样:

    {
"materials":[
    { "name":"ext", "texture":"f_03.jpg", "ambient":[255.0,255.0,255.0], "diffuse":[255.0,255.0,255.0], "specular":[255.0,255.0,255.0], "opacity":0.7 },
    { "name":"int", "texture":"f_03.jpg", "ambient":[255.0,255.0,255.0], "diffuse":[255.0,255.0,255.0], "specular":[255.0,255.0,255.0], "opacity":0.7 }
],
"meshes":[
    {
        "name":"Cylinder001",
        "material":"ext", ...

    {
        "name":"Cylinder002",
        "material":"int", ...

0
为了正确地使用alpha混合渲染该场景,每帧三角形都必须从后往前渲染。你的场景尤其具有挑战性,因为你有一个物体在另一个物体内部,并且需要渲染两侧,这将需要先渲染部分球体,然后是立方体,最后再渲染剩余的球体。我怀疑three.js(或任何其他场景图库)能够处理这种情况。
加法混合或减法混合可以在不排序的情况下工作,但效果不太好。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接