Unable to enable Anti-Aliasing for Quest 2

Hey there, hoping you can help.

I’m working on a VR implementation of jmonkeyengine using jme3-vr-3.2.1-stable.

For some reason I cannot seem to enable AA using “settings.setSamples(x);” as normal. I’ve been through the online documentation for it but cannot see what would be stopping it, but before I pull my hair out I thought I’d ask someone here with more experience if this is a known issue, if there is a solution, and what that might be.

So I’ve had a bit of a dig. Looking at the source for jme3-vr and it’s because all the FrameBufffers are created with samples of 1 (ignoring the setting to control samples).


But jme3-vr-3.2.1 is really old! And in more modern JME jme3-vr is getting deprecated so I’m not sure if you want to tie yourself to it if this is a new project. It was created back in the day when you had to bind with each VR headset with specific code for each and it was generally a pain (Not saying anything against the authors of jme3-vr, that was just the reality of VR development in those days). These days you’d probably want to use OpenXR which allows more of a write once, run on all headsets, workflow.

The idea now is that VR in JME will be provided by user contributed libraries. E.g. Tamarin. (For disclosure Tamarin is written by me). There is a full example at TamarinTestBed

However, Tamarin isn’t actually any better in this regard. It asks the runtime to recommend a number of samples and then sets up the texture images with that number of samples and the runtime recommends [drumroll] 1. But you’ve drawn my attention to it now and I’ll have a bit more of a dig as to why


Ah, ok!

Thanks so much for looking into it. Been pulling my hair out a bit trying to even find the cause of this issue myself, so thanks so much just for pointing it out.

Let me know if you find any solution, I will see what can be done about updating to something more modern as the project is quite large at this point and I’m dreading the amount of functions and such which will break :sweat_smile:

An option might be to do anti aliasing as a post processor FXAAFilter. My understanding is that this isn’t “as good” but might be good enough?

In Tamarin this would be done like this

    xrAppState.setMainViewportConfiguration(vp -> {
        FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
        fpp.addFilter(new FXAAFilter());

I think the jme3-vr equivalent to that would be to call VRViewManager#getLeftViewPort() and add the post processor to that (And obviously the right equivalent)

In case it’s helpful:

And for some readers maybe:

1 Like

I’ve now tried both your fix, which for some reason did not work as both viewports for some reason are null at all points, whether in environment, appstate, or otherwise. Really strange.

So instead I’ve tried to update to the newest JME 3.6.1 with the same VR package but now I have some stupid error that keeps me from being able to run anything in VR. This is it:

Exception in thread “AWT-EventQueue-0” java.lang.NoClassDefFoundError: org/lwjgl/openvr/VR

I saw in the VR thread that people talked about this being an issue with libs and jars either not being found or being setup correctly, but it worked fine before so I’m just scratching my head why it’s not working since all I’ve done is simply change out 3.2.1 jars with 3.6.1 jars.

Any ideas?

I don’t know if this is a step further or if it’s a step back, but when I add the LWJGL version from here: Releases · LWJGL/lwjgl3 · GitHub I no longer receive that error anymore because it finds the directory, but then I get a strange Architecture mismatch message, which I will post below. If either of these things make any sense to people, let me know:

[LWJGL] Platform/architecture mismatch detected for module: org.lwjgl
JVM platform: Windows amd64 17.0.9
OpenJDK 64-Bit Server VM v17.0.9+9 by Eclipse Adoptium
Platforms available on classpath:
[LWJGL] Failed to load a library. Possible solutions:
a) Add the directory that contains the shared library to -Djava.library.path or -Dorg.lwjgl.librarypath.
b) Add the JAR that contains the shared library to the classpath.
[LWJGL] Enable debug mode with -Dorg.lwjgl.util.Debug=true for better diagnostics.
[LWJGL] Enable the SharedLibraryLoader debug mode with -Dorg.lwjgl.util.DebugLoader=true for better diagnostics.
Exception in thread “AWT-EventQueue-0” java.lang.UnsatisfiedLinkError: Failed to locate library: lwjgl.dll
at org.lwjgl.system.Library.loadSystem(Library.java:174)
at org.lwjgl.system.Library.loadSystem(Library.java:64)
at org.lwjgl.system.Library.(Library.java:52)
at org.lwjgl.openvr.VR.(VR.java:27)
at com.jme3.input.vr.lwjgl_openvr.LWJGLOpenVR.initialize(LWJGLOpenVR.java:134)
at com.jme3.app.VREnvironment.initialize(VREnvironment.java:469)

I really appreciate any help with this as I’m completely baffled.

Doing all of this with jars is probably a bit painful (as some of those jar changes will imply different dependencies). Have you tried a gradle build system? It’s likely to be a lot less difficult in the long run.

What flavour of jme3-vr are you using? I recall that there was a setting like this in jme3 vr:

settings.put(VRConstants.SETTING_VRAPI, VRConstants.[flavour_here])

Currently I am using 3.6.1 just like the version of the jme. I picked the latest stable release.

Here are all settings used:

settings.put(VRConstants.SETTING_USE_COMPOSITOR, true);
settings.put(VRConstants.SETTING_DISABLE_VR, false);
settings.put(VRConstants.SETTING_ENABLE_MIRROR_WINDOW, false);
settings.put(VRConstants.SETTING_VR_FORCE, false);
settings.put(VRConstants.SETTING_FLIP_EYES, false);
settings.put(VRConstants.SETTING_NO_GUI, true);
settings.put(VRConstants.SETTING_DEFAULT_FOV, 108f);
settings.put(VRConstants.SETTING_DEFAULT_ASPECT_RATIO, 1f);

Here is an overview of the libs/jars that I’m currently using, with the last one (openvr) having been added because of the missing class def described in an earlier post.

The openvr.jar was downloaded from here: Releases · LWJGL/lwjgl3 · GitHub, it’s the 3.3.3, and within that download you can find openvr, and the jar is in that directory.

Xebioz and I have been talking about this on private message but to publicly mention it. Tamarin now does support MSAA (from version 2.5.0)!

Previously Tamarin had JME render directly into the frame buffers OpenXR used for its swapchain images. These swapchain images did not support samples. Now if samples are requested Tamarin gives each JME viewport an intermediate framebuffer (with the requested number of samples) and blits that to the final OpenXR swapchain image framebuffer before finishing the frame. Obviously not as performant as directly rendering into each swapchain but my understanding is that this is how VR engines with MSAA support do it. (If you don’t request samples it still does the direct render)



According to your screenshot, your class path contains both lwjgl and lwjgl3 libraries.

This is not a valid configuration. In order to use jme3-vr you have to only use jme3-lwjgl3 dependency (and remove jme3-lwjgl3).

I’m using jme3-vr (3.6.1) with my students and it’s work fine for us (we use Acer Ah101, Oculus quest 2 and Metaquest 3 headsets)

I’m working on an update of jme3-vr with bugs correction and I’m working on an update of jme3-vr for handling OpenXR using LWJGL bindings.

Have a nice day.

1 Like

Is there anything missing in Tamarin OpenXR that is driving you to create annother OpenXR library for JME?

My concern is that jme3-vr relies on high level interfaces that enables to be independent from the underlying implementation (OSVR, OpenVR, OpenXR, …).

A lot of my projects are relying on these high level interfaces.

If I have to use another library for VR, it will be more interesting for me to switch to Unity or Unreal Engine instead of using a JMonkey user library.

Moreover, from my point of view, it is more interesting to make existing jme3 module to be enhanced to new capabilities (even if it implies more devs) and keeping backward comptability for a little time.

1 Like