Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenXR composition layer example #1080

Merged

Conversation

BastiaanOlij
Copy link
Contributor

@BastiaanOlij BastiaanOlij commented Jun 25, 2024

This new example project demonstrates the new composition layer feature in Godot 4.3.

It's a direct companion to https://docs.godotengine.org/en/latest/tutorials/xr/openxr_composition_layers.html, once this is merged I'll update the documentation to reference this project.

xr_composition_layer_demo

@BastiaanOlij BastiaanOlij added this to the 4.3 milestone Jun 25, 2024
@BastiaanOlij BastiaanOlij self-assigned this Jun 25, 2024
@BastiaanOlij
Copy link
Contributor Author

Working out some last wrinkles, but nearly got this working.

# See if we have a better refresh rate available.
var new_rate := current_refresh_rate
var available_rates: Array[float]
available_rates.assign(xr_interface.get_available_display_refresh_rates())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this method actually doesn't return an array of floats (it should though) I'm not if we shouldn't just use Array, because either the array is valid, and contains valid types, and in that case it doesn't matter, or it doesn't, in that case both versions of this script, with Array and no assign, with type checking below, and the version here, will fail because the assignment or types are incompatible

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally I would want get_available_display_refresh_rates to return a proper typed array as it will return an array of floats, but it was written before we had support for those types and I don't know if that would be too much of a breaking change to introduce so late in the 4.3 dev cycle.

I'm happy to just change it to var available_rates: Array = xr_interface.get_available_display_refresh_rates(), yes it's not doing type checking but in this case it's dependable enough.

@surreal6
Copy link

Thanks for the example project!

I was testing this and found some different behaviour in compositionLayerQuad and compositionLayerEquirect.

In pcvr i can't make Hole Punch work with compLayerQuad, but when exporting to quest2 it works. When using compLayerEquirect it works fine both in pcvr and standalone.

To reproduce, i used this sample project, duplicated the UIViewport, duplicated the Equirect, and change node type to Quad. Also duplicated the handle_pointers.gd to extend from Quad class, and assigned the duplicated viewport to the quad layer.

Here are some screenshots:

This is a Quest2 screenshot:
quest2_screenshot

This is a SteamVR screenshot (valve index hmd)
steamvr_screenshot

But what happens inside the valve index hmd is this:
valve_index_hmd_1
valve_index_hmd_2

@BastiaanOlij
Copy link
Contributor Author

@surreal6 interesting, that seems to be more a problem on the XR runtime though. On the SteamVR side we can see that the equirect on the left is using our build in fallback and only the quad is being rendered on the headset. It's showing up black because of the hole punch logic.

It looks like its doing additive blending, not alpha blending, I'm also guessing the viewport isn't setup with transparency (seeing we also have a sky) and the hole punch logic needs that. It's why I didn't add hole punch to the demo.

Interesting that on Quest the transparency isn't working, though that could be a side effect of the hole punch.

In the end, not directly applicable to this demo as I'm only showing using this feature in VR, but definitely worth raising an issue on the main Godot repo to further investigate the platform differences and whether we need to make clearer instructions or detail out the platform differences here.

Also cc @dsnopek

@BastiaanOlij
Copy link
Contributor Author

Just renamed the folder so it uses underscores instead of dashes and be consistent with naming of other projects.

@dsnopek
Copy link
Contributor

dsnopek commented Jul 2, 2024

@surreal6 I don't entirely follow the screenshots above: Can you explain in my detail what you're trying to accomplish, or share a project that's fully setup?

EDIT: Nevermind! I didn't see the new issue with MRP that you uploaded. I'll check it out when I have a chance.

Interesting that on Quest the transparency isn't working, though that could be a side effect of the hole punch.

When using hole punching, you move the composition layer behind the projection layer (ie set the sort order to a negative value). This means if you make the layer transparent, then it'll show what's behind it, which is probably just black, unless you placed another composition layer even further back behind it (ie with a sort order value that was lower). One option is using an equirect layer to draw the sky, rather than Godot's sky rendering, but that's something you'd only want to do if you were 100% sure that the device supported equirect layers.

Copy link
Contributor

@dsnopek dsnopek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested on the Meta Quest 3 with Godot 4.3-beta2 and it worked great! I skimmed the code, and that looks good to me too.

I also tested on the HTC Vive XR Elite, just to see how it works on at least one other headset, and other than the lower visual fidelity and the issue already fixed by PR godotengine/godot#93678, it also worked great!

@BastiaanOlij
Copy link
Contributor Author

Ping, would be nice to get this merged as this functionality is now out in the wild with the 4.3 release.

Surreals issue is not related to the demo and something we're looking into separately.

@akien-mga akien-mga merged commit 6c635fe into godotengine:master Aug 22, 2024
1 check passed
@akien-mga
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants