artifacts when rendering both sides of a transparent object with three.js

前端 未结 4 1078
梦谈多话
梦谈多话 2020-11-27 19:27

I try to render both sides of a transparent object with three.js. Other objects located within the transparent object should show too. Sadly I get artifacts I don\'t know to

相关标签:
4条回答
  • 2020-11-27 20:13

    Make a clon of the original mesh and flip its normals; then make two identical "one sided" material for each with different name. Not the most classy approach but it worked just fine. I struggled with the same problem, this is what I did :P

    The .json file looks like this:

        {
    "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 讨论(0)
  • 2020-11-27 20:20

    Generally to do transparent objects you need to sort them front to back (I'm guessing three.js already does this). If your object is convex (like both of those are) then you can sometimes get by by rendering each object twice, once with gl.cullFace(gl.CCW) and again with gl.cullFace(gl.CW). So for example if the cube is inside the sphere you'd effectively do

    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.
    

    I have no idea how to do that in three.js

    This only handles objects that are convex and not intersecting (one object is contained entirely inside the other).

    0 讨论(0)
  • 2020-11-27 20:22

    To render that scene correctly with alpha blending, the triangles would have to be rendered from back to front each frame. Your scene is particularly challenging since you have one object inside another, and rendering both sides, which would require rendering part of the sphere, then the cube, then the rest of the sphere. I doubt three.js (or any other scene graph library) can handle this case.

    Additive or subtractive blending will work without sorting, but doesn't look as nice.

    0 讨论(0)
  • 2020-11-27 20:29

    Self-transparency is particularly difficult in WebGL and three.js. You just have to really understand the issues, and then adapt your code to achieve the effect you want.

    You can achieve the look of a double-sided, transparent sphere in three.js, with a trick: You need to render two transparent spheres -- one with material.side = THREE.BackSide, and one with material.side = THREE.FrontSide.

    Using such methods is generally required if you want self-transparency without artifacts -- especially if you allow the camera or object to move.

    Here is a fiddle: http://jsfiddle.net/x5bm0qLf/

    EDIT: Updated fiddle to three.js r.105

    0 讨论(0)
提交回复
热议问题