Bloom filter causes flicker (in a VR context)

I’ve been trying to get Tamarin 2 working in some of my real projects and I’m experiencing an issue where if the cameras have a bloom filter applied they flicker (otherwise they are fine). I think that flicker is the glow being applied only on some frames.

A minimal example that includes Tamarin is:

public class Main extends SimpleApplication{
    
    public static void main(String[] args) {
        AppSettings settings = new AppSettings(true);
        settings.put("Renderer", AppSettings.LWJGL_OPENGL45);
        settings.setTitle("Tamarin OpenXR Example");
        settings.setVSync(false); 
        Main app = new Main();
        app.setLostFocusBehavior(LostFocusBehavior.Disabled);
        app.setSettings(settings);
        app.setShowSettings(false);
        app.start();
    }
    
    @Override
    public void simpleInitApp(){
        XrAppState xrAppState = new XrAppState();

        xrAppState.configureBothViewports(v -> {
            FilterPostProcessor fpp=new FilterPostProcessor(assetManager);
            BloomFilter bf=new BloomFilter(BloomFilter.GlowMode.Objects);
            bf.setBlurScale(0.5f);
            fpp.addFilter(bf);
            v.addProcessor(fpp);
        });

        getStateManager().attach(xrAppState);

        Box b = new Box(0.1f, 0.1f, 0.1f);
        Geometry geom = new Geometry("Box", b);
        Material mat = new Material(assetManager,
                "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Gray);
        geom.setMaterial(mat);

        geom.setLocalTranslation(0, 1, 5f);
        xrAppState.playerLookAtPosition(new Vector3f(0,1,5));
        rootNode.attachChild(geom);
    }

}

I’ll try to create a minimal example that doesn’t involve Tamarin if the problem isn’t immediately obvious to someone (but that will probably be hard so I wanted to at least see if someone had an idea first).

The way this works is

During XrAppState#update the viewport is given an output frame buffer to render into

@Override
public void update(float tpf){
    ...
    leftViewPort.setOutputFrameBuffer(inProgressXrRender.getLeftBufferToRenderTo()); 
    ...
}

Then later during the post render OpenXR is informed that the scenes are ready

@Override
public void postRender(){
    super.postRender();
    if (inProgressXrRender !=null){
        xrSession.presentFrameBuffersToOpenXr(inProgressXrRender);
        inProgressXrRender = null;
    }
}

My two current working theories are:

  • The bloom filter is only applying to the frame buffer that is attached to the viewport when the filter is applied; it’s triple buffered so that would make a kind of sense, but the processors belong to the viewport, not the framebuffer
  • The bloom filter may or may not be “ready” by the time I present it to OpenXR. But it feels like too regular a flicker for that theory to make sense.

Anything people think could plausibly be causing these problems?

My initial point of research would be the filter post proc. I am quite sure there have been some issues with it when using more viewports.

To replicate rendering with two viewports should cause the same issues.

I do not now at what point the ffp gets a handle for the output framebuffer.

A regular flickering might hint, that the ffp does not update its output target

1 Like

I think you’re right. Getting the debugger out; in FilterPostProcessor the outputBuffer is only set once (for each eye)

At FilterPostProcessor.java#L483

    if (renderFrameBuffer == null && renderFrameBufferMS == null) {
        outputBuffer = viewPort.getOutputFrameBuffer();
    }

And the output buffer is constantly cycling through 3 different buffers for me.

Does this mean that this approach of setting the output buffer isn’t supported along side FilterPostProcessors? I was originally letting JMonkey draw to its frame buffer then copying it into the swap chain each frame but that seems much less efficient (copying across loads of memory every single frame). But it would probably not suffer from this problem

I think it would be best if the Fpp check if the viewport render target has changed.

As i see no setter for the outputbuffer, the alternative is java reflection.
Or, copy the output texture as you mentioned.

Ultimately the jme fpp is not flexible enough for Vr. You always end up dooing lots of unnecesary double rendering. Shadowmaps are a prime example.