Transparency and FaceCullMode.Off

Hi guys,

I have a mesh I want to render front and back, and with transparency. The problem is that it ends up looking like this:

I have checked my normals and tried both flat and smooth normals, nothing changes it. Any idea how to fix this?

That’s because at some angles the back triangles get rendered first and at some angles the front triangles do (and cause issues).

To render transparent objects like this you have to render the inside and outside separately (ordered to render inside first) or order the mesh to have separate inside and outside triangles ordered to always render the inside triangles first.

1 Like
@pspeed said: That's because at some angles the back triangles get rendered first and at some angles the front triangles do (and cause issues).

To render transparent objects like this you have to render the inside and outside separately (ordered to render inside first) or order the mesh to have separate inside and outside triangles ordered to always render the inside triangles first.

I saw a similar explanation on the unity forums about this issue. I would like to make my shader have two render passes, but from what I understand it is not possible to define this in a j3md file. I would need to implement two techniques, one for rendering back-faces and one for rendering front-faces, defining the FaceCullMode in each RenderState.

I guess I would then have render it with a forcedTechnique. Inside a filter? The front faces being rendered in the default technique pass and the back faces being rendered on the postQueue. Something along the lines of:

[java]
public class BackFaceFilter extends Filter {

@Override
protected void postQueue(RenderQueue queue) {
    Renderer r = renderManager.getRenderer();
    r.setFrameBuffer(normalPass.getRenderFrameBuffer());
    renderManager.getRenderer().clearBuffers(true, true, true);
    renderManager.setForcedTechnique("BackFacePass");
    renderManager.renderViewPortQueues(viewPort, false);
    renderManager.setForcedTechnique(null);
    renderManager.getRenderer().setFrameBuffer(viewPort.getOutputFrameBuffer());
}

[/java]

Am I approximately right?

I just tried the solution with two separate geometries for front and back, and it gives another issue. They are rendered in the wrong order, resulting in this:

Even if I could fix the render order for these two meshes, I would get issues when including more transparent objects, I assume. I guess the only valid approach I see is the render pass way.

@nihal said: I just tried the solution with two separate geometries for front and back, and it gives another issue. They are rendered in the wrong order, resulting in this:

Even if I could fix the render order for these two meshes, I would get issues when including more transparent objects, I assume. I guess the only valid approach I see is the render pass way.

Note: not front and back. Inside and outside.

Transparent objects must be drawn from farthest to nearest or they don’t render right. The nearer ones will obscure the back ones. JME automatically sorts objects by distance.

This doesn’t work within a mesh though as the triangles of the mesh will always be drawn in the same order.

So as mentioned before, you have two options:

  1. reorder the triangles of your mesh so that all of the inside facing triangles are first. They will always be drawn before the outside triangles in that case and transparency is rendered properly for the object. Your cylinder is a nice case because it is convex so this technique would work from any angle. If you are loading this as a model then it becomes more difficult.

  2. create two Geometries. One with the mesh with front face culling and one with the mesh with back face culling. If you attach these to the same node (inside first and then outside) then I think JME will render them in order. It may not be guaranteed, though. (You also may have to flip the order because transparent bucket sorting may reverse them.) If “hoping and praying” doesn’t work then you could always resort to a custom geometry comparator for the transparent bucket that would always sort the inside geometry in proper relation to the outside one. There are a few techniques for this but it’s easier to try the other ways first.

You don’t have to render multiple passes. You just have to get the inside faces to render before the outside ones.

1 Like

I got this working with option 2 now. Thank you.

Could this be done with shader nodes? Is there a way to define RenderStates inside a ShaderNode? For setting the FaceCullMode for each node.

@nihal said: I got this working with option 2 now. Thank you.

Could this be done with shader nodes? Is there a way to define RenderStates inside a ShaderNode? For setting the FaceCullMode for each node.

It’s a material (additional render state) property and not a shader property. You can specify this sort of thing in the j3m or j3md, though.

Not sure it helps much since (if it were me) I’d just clone the original Geometry, clone its material, and grab the render state and switch the face culling.

@pspeed said: It's a material (additional render state) property and not a shader property. You can specify this sort of thing in the j3m or j3md, though.

Not sure it helps much since (if it were me) I’d just clone the original Geometry, clone its material, and grab the render state and switch the face culling.

That makes sence, thanks. I have it working with two separate geometries for now. I had to implement a new GeometryComparator for the Transparent queue, as the meshes were being sorted opposite of what I wanted, no matter of the order they were attached. Looks good now, though. Cheers. :slight_smile: