in OpenGL I have drawn a transparent cube in orthogonal projection, the enviroment has a front ligth. The result is reported in figure. What I don't understand is why there is a missing edge?
gl.Enable(OpenGL.GL_BLEND);
gl.BlendFunc(OpenGL.GL_SRC_ALPHA, OpenGL.GL_ONE_MINUS_SRC_ALPHA);
I use a DrawElements() function that uses indices.
Are there any suggestions?
CodePudding user response:
This is caused by depth testing. OpenGL renders one triangle (or square) at a time. When depth testing is turned on, it skips rendering a pixel if it's already rendered something in front of that pixel. This is good for solid objects, but it doesn't work for transparent ones, because the back parts have to be rendered first or else they don't get rendered at all.
There are many ways to do transparency, but none of them are particularly nice. Unfortunately, whichever way you slice it, transparent objects are just not as easy to render as opaque ones.
So here are some ways to render transparent things:
- Sort the faces and render back-to-front.
- Sort the faces and render front-to-back, so the back is invisible.
- Use face culling and render twice: cull front faces and render, then cull back faces and render. This gives the same effect as back-to-front by getting OpenGL to do it for you. Only works for convex objects (cubes are convex) and if you have more than one transparent object you still have to sort the objects.
- Use face culling to cull back faces. This gives the same effect as rendering back-to-front, by getting OpenGL to do it for you. Same caveats as the previous one.
- Use a different blending mode where the rendering order doesn't matter, such as multiplicative or additive, and turn depth testing off. Multiplicative blending mode removes light without adding it - looks like cellophane instead of stained glass - you'd need a white background. Additive blending mode looks like one of them sci-fi spaceship control screens - it makes its own light and you can also see through it.
- Depth peeling and linked list buffers are two techniques which do separate sorting for each pixel, but they require more intense processing and very complicated shaders.
- Raytracing (enough said)
- If all the faces are the same colour, you can just turn depth testing off and it will look okay. Since the faces are all the same you can't tell they are rendered in the wrong order. This works for your red cube but it won't work if you add different colours or a texture.
- To properly render a cube with a translucent interior, not just a translucent surface, you need a volumetric translucency effect which is also more complicated and out of scope here. You would render the back, the front, and apply a different amount of translucency depending on the distance between them.
CodePudding user response:
I resolved thaks to user253751 putting this to instructions:
gl.Enable(OpenGL.GL_DEPTH_TEST);
gl.DepthFunc(OpenGL.GL_ALWAYS);