GithubHelp home page GithubHelp logo

immersive-web / layers Goto Github PK

View Code? Open in Web Editor NEW
89.0 33.0 19.0 3.05 MB

A feature repo for working on multi-layer support in WebXR. Feature leads: Rik Cabanier and Artem Bolgar (Oculus)

Home Page: https://immersive-web.github.io/layers/

License: Other

Makefile 0.02% Bikeshed 14.47% HTML 85.50%
webxr

layers's Introduction

WebXR Layers Specification

Build Status

The WebXR Layers Specification exposes WebGL and media layers for WebXR

Taking Part

  1. Read the code of conduct
  2. See if your issue is being discussed in the issues, or if your idea is being discussed in the proposals repo.
  3. We will be publishing the minutes from the bi-weekly calls.
  4. You can also join the working group to participate in these discussions.

Specifications

Related specifications

  • WebXR Device API - Level 1: Main specification for JavaScript API for accessing VR and AR devices, including sensors and head-mounted displays.

See also list of all specifications with detailed status in Working Group and Community Group.

Relevant Links

Communication

Maintainers

To generate the spec document (index.html) from the index.bs Bikeshed document:

bikeshed spec

Tests

For normative changes, a corresponding web-platform-tests PR is highly appreciated. Typically, both PRs will be merged at the same time. Note that a test change that contradicts the spec should not be merged before the corresponding spec change. If testing is not practical, please explain why and if appropriate file a web-platform-tests issue to follow up later. Add the type:untestable or type:missing-coverage label as appropriate.

License

Per the LICENSE.md file:

All documents in this Repository are licensed by contributors under the W3C Software and Document License.

Summary

For more information about this proposal, please read the explainer and issues/PRs.

layers's People

Contributors

adarosecannon avatar artyom17 avatar cabanier avatar cwilso avatar dontcallmedom avatar elchi3 avatar foolip avatar himorin avatar manishearth avatar mrxz avatar tidoust avatar toji avatar trevorfsmith avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

layers's Issues

API allows creating more than one projection layer

The API currently allows content to create more than one projection layer, and to decide which one to render at any point, for example:

   let layer1 = glLayerFactory.createProjectionLayer("texture");
   let layer2 = glLayerFactory.createProjectionLayer("texture");
   ... render into the layers ...
   if (something) {
      xrSession.updateRenderState({ layers: [layer1] });
   } else {
      xrSession.updateRenderState({ layers: [layer2] });
   }

This is problematic on devices where the device has a swap chain that content is expected to render into. If the API only allowed one projection layer for each session, then we could arrange for that layer to be backed by the device swap chain, but since there may be more than one, it is not obvious what to do.

Define default values for all layers' properties

The spec should define default values for all the properties of the layers which user does not change. For example, width / height for Quad layer, default pose, default angle, aspect ratio, radius for Cylinder, etc.

Consider adding a layer creation factory to XRSession

XRWebGLLayer currently:

  • Takes an XRSession in its constructor
  • Has a static method getNativeFramebufferScaleFactor() that takes an XRSession as its only parameter - and thus only source of variability in the value returned

Given the importance of an XRSession to the creation of XRWebGLLayer (see immersive-web/webxr#693) and the result returned by getNativeFramebufferScaleFactor(), one may wonder why createXRWebGLLayer() and getNativeFramebufferScaleFactor() are not methods on XRSession.

Even if that made sense, this wouldn't scale well as more layers are added because each layer type might require adding two methods to XRSession. One possible solution to this would be to expose a session-specific layer factory from XRSession. The XRLayerFactory could then have pairs of methods to create and getNativeFramebufferScaleFactor for each layer type. The presence of these methods would also allow support by the user agent to be detectable should the layers effort not provide another mechanism.

For example:

partial interface XRSession {
  XRLayerFactory XRSession::layerFactory()
};

interface XRLayerFactory {
  XRWebGLLayer createXRWebGLLayer(XRWebGLRenderingContext context, optional XRWebGLLayerInit layerInit);
  double getXRWebGLLayerNativeFramebufferScaleFactor();
};

/cc @toji @NellWaliczek in case there's anything they'd like to consider now in the base spec.

Content in immersive session should need not be search around

When user enter into immersive session, general expectation is that the immersive content is shown in the direction where the user is looking. Thats not what is happening now. What happens now is that origin of the local reference space points to the device boot up direction. If i have few object in my immersive session, i would have to turn around to search where the content is. This does not feel right. It's the same behavior on Magic Leap, Oculus and Day Dreamer as confirm by @cabanier and Ravi.

Add 'layout' hint for quad, cylinder, equirect stereo layers

Displaying pre-rendered stereo images or videos will require specification of stereo layout, which is currently mentioned for video quad layer. However, for stereo photos, stereo 180/360 panoramas it is also required WHEN texture2D is used. For texture arrays it will be ignored.

Layers shouldn't have a `transform`

We already support origin offset spaces, layers don't need to have a "transform"

interface XRCylinderLayer : XRLayer {
  attribute XRReferenceSpace referenceSpace;
  attribute XRRigidTransform transform;
}

Should the requestxxx APIs use promises?

Currently the APIs to create layers all return a promise.
This means that the promise for the layers is fulfilled outside a Raf. I think this is confusing because the author won't be allowed to use the layers there.
Moreover, XRWebGLLayer can just be constructed so why can't we have immediate layer creation?

I think we should get rid of the promises and return the layer object directly.

Create a concept of "image source" for layers

Current design of XRWebGLLayer allows only to use an opaque framebuffer. This approach won't work well with the layering system, or even with multiview (where texture array is required). Need to create a a concept of the "image source", the abstract base and then introduce specific implementations of it, for example ImageSourceFramebuffer, ImageSourceTextureArray, ImageSourceTexture, etc. The similar concept exists in OpenXR.

Extra blit required on XR devices with one framebuffer per eye?

The XRWebGLLayer interface https://immersive-web.github.io/webxr/#xrwebgllayer-interface provides a single framebuffer, with one viewport for each eye. When implementing this API for devices (e.g HoloLens or MagicLeap) which have a framebuffer for each eye, this means there's an extra blit where the WebXR framebuffer is copied into each device framebuffer.

Are there plans for an API which can be implemented on such devices without an extra blit? For example by having a method getFramebuffer(view) similar to getViewport(view) rather than a single framebuffer property?

Add init objects for all layers? Or put all possible props to XRLayerInit?

Currently XRLayerInit contains only a subset of properties common for all layers. However, Quad, Cylinder, Equirect, Cube layers will need to have their own specific properties to be initialized. For example, Cylinder layer has { aspectRatio, radius, centralAngle }, Quad - { width, height }, Equirect - { bias, scale }.
Should the spec define XRQuadLayerInit, XRCylinderLayerInit, etc?
Or, put all of these properties into XRLayerInit (which I am not fond of)?
Or, do not let init these props via init obj at all?

Must all layers use the same WebGL context?

Seems like currently it is possible to use different WebGL contexts for different layers within the same session. This may significantly complicate implementation. Shouldn't we limit all layers to use the same WebGL context explicitly?

Need to provide bias / scale for both eyes for stereo Equirect, Quad, Cylinder layers

This issue is related to #46

When a single texture is used, it is necessary to provide bias / scale for both eyes. Currently, only Equirect layer has that and only one pair of bias / scale.

How I see the Equirect layer:

dictionary XRTextureTransform {
  float scaleX = 1.0;
  float scaleY = 1.0;
  float biasX = 0.0;
  float biasY = 0.0;
};

interface XREquirectLayer : XRLayer {
  readonly attribute boolean stereo;
  //? readonly attribute XRStereoLayout layout;
  attribute XRReferenceSpace referenceSpace;
  attribute XRRigidTransform transform;

  attribute float radius;

  XRTextureTransform? getTextureTransform(XREye eye);
  setTextureTransform(XREye eye, XRTextureTransform? texture_transform);
};

If we agree on stereo layout then getTextureTransform will return the actual texture transform for the selected layout.
Otherwise, the setTextureTransform can be used to specify the transform for each eye. This method can be used to define custom layouts.

Same stuff should be added into Quad and Cylinder layers. Or, maybe we can add directly to the base XRLayer? ProjectionLayer may just return null and ignore setTextureTransform.

Determine the shape of Multiview support

We've known for a while that we want to have support for multiview graphics extensions, but the previous attempt at it wasn't super well defined and the associated WebGL extension has yet to solidify. Additionally, we haven't yet come up with a concrete plan for antialiasing with multiview rendering, which is more-or-less a hard requirement for XR.

Planting this issue down as a way to indicate these problems still need to be solved while I remove the multiview stub from the explainer.

Define XRProjectionLayer as a replacement for XRWebGLLayer

The new XRProjectionLayer should be using XRImageSource (issue #10 ) and must be constructed by the XRLayerFactory (issue #5 ). The main benefit will be higher flexibility in terms of how rendering is done (i.e. into a framebuffer, texture or texture array). Theoretically, even WebGPU image sources could be made available.

Video layer transport controls?

Is the intention that the HTMLVideoElement is just used to manage the video to be displayed, or is it expected to render UA-provided transport controls on top of the video?

I would presume that any built-in UA video transport controls would be always hidden here, as supporting them would pull in lots of open questions around input focus of one or more controllers/hands within the scene. If that's the case, we should write it down in the spec explicitly.

Some remaining references to promises in README

There are still some references to promises in the README, for example "The method will return a promise that will resolve to the associated XRLayer type once the graphics resources have been created and the layer is ready to be displayed."

In the text "If a layer type isn't supported the returned Promise will reject," this will probably be replaced by throwing an exception - which exception?

Define how input is handled

Only the UA really knows where layers are placed in 3D space.
The author (or JS framework) can guess where they are but this might be brittle.

What is the best way to provide input events? Should non-projection layers become event targets?

Use Texture Arrays directly with WebGL 2

This idea originated with an email that @RafaelCintron sent me a couple of days ago which was then discussed on the last WebXR call. In short, he proposed having a XR layer type that was WebGL 2.0-only that provided Texture Array's rather than the opaque framebuffer of our current XRWebGLLayer. (XRWebGLLayer would stick around for WebGL 1.0 compatibility.) Then the WebGL multiview extensions could use the texture array directly, which would more directly mirror the underlying native extensions like OVR_multiview.

I'm in favor of this approach, as it solves a couple of problems. Primary among them is that it would give developers the ability to mix geometry that is rendered via multiview techniques with geometry that is rendered one eye at a time. I believe that this is necessary because otherwise any single technique that a library uses that has not been converted to be multiview compatible would disqualify an app from using multiview at all (this is likely to be common, as the web ecosystem delights in mashing code from a variety of sources together.)

Note: Even if we introduce a new layer type the plan would still be to only allow one layer at a time to be presented in the initial version of WebXR.

One point of misunderstanding in our initial discussion: I had assumed that this proposal was meant to wholly replace the previously planned method of multiview compatibility which was via the opaque framebuffer and could potentially support WebGL 1.0. I'm personally OK with the tradeoff of saying that multiview is a WebGL 2.0-only feature (this is the state of native OpenGL ES anyway.) @RafaelCintron and others apparently weren't ready to go that far and appear to be in favor of supporting both the Texture Array method and the opaque framebuffer method. That would lead to broader compatibility at the expense of complexity, both in WebXR and WebGL. (And again, the opaque framebuffer route is an all-or-nothing affair as currently specced.) In any case, I would be very interested in hearing from a variety of sources how big of a hurdle a WebGL 2.0 requirement for this feature would represent.

To kick off the discussion, here's a quick stab at the IDL to support this feature, all subject to copious bikeshedding. This variant omits multiview on the XRWebGLLayer, but that's ultimately dependent on the groups feelings on the above points.

// I think it's important (and easy) to retain WebGL 2.0 compatibility on the "basic" layer type.
typedef (WebGLRenderingContext or
         WebGL2RenderingContext) XRWebGLRenderingContext;

dictionary XRWebGLLayerInit {
  boolean antialias = true;
  boolean depth = true;
  boolean stencil = false;
  boolean alpha = true;
  boolean multiview = false;
  double framebufferScaleFactor;
};

[SecureContext, Exposed=Window,
 Constructor(XRSession session,
             XRWebGLRenderingContext context,
             optional XRWebGLLayerInit layerInit)]
interface XRWebGLLayer : XRLayer {
  readonly attribute XRWebGLRenderingContext context;
  readonly attribute boolean antialias;
  readonly attribute boolean depth;
  readonly attribute boolean stencil;
  readonly attribute boolean alpha;

  readonly attribute unsigned long framebufferWidth;
  readonly attribute unsigned long framebufferHeight;
  readonly attribute WebGLFramebuffer framebuffer;

  void requestViewportScaling(double viewportScaleFactor);
  XRViewport getViewport(XRView view);
};

dictionary XRWebGLArrayLayerInit {
  boolean alpha = true;
  double arrayTextureScaleFactor; // Same as the framebufferScaleFactor
};

[SecureContext, Exposed=Window,
 Constructor(XRSession session,
             WebGL2RenderingContext context,
             optional XRWebGLArrayLayerInit layerInit)]
interface XRWebGLArrayLayer : XRLayer {
  readonly attribute WebGL2RenderingContext context;
  readonly attribute boolean alpha;

  readonly attribute unsigned long arrayTextureWidth;
  readonly attribute unsigned long arrayTextureHeight;
  readonly attribute unsigned long arrayTextureDepth;
  readonly attribute WebGLTexture arrayTexture;

  void requestViewportScaling(double viewportScaleFactor);
  XRViewport getViewport();
  int getLevel(XRView view);
};

A few things to point out in relation to the IDL:

  • We would want the arrayTexture to be immutable, the same way the framebuffer is in XRWebGLLayer. I think we can get this by saying that it should be treated as if it were created with texStorage3D, which will naturally restrict the dimensions and format but not the texture parameters. Not sure if that's restrictive enough. If it is, though, it's much better than inventing Yet Another Opaque Type.
  • As specced above this would be somewhat harder to use than the XRWebGLLayer because it makes the developer responsible for the framebuffer and all of it's attachments. That's generally a good thing for flexibility, but I'm curious if there's a good reason why we may still want user agent control of the depth or stencil buffers?
  • In the IDL above I've moved getViewport off of XRView and onto the individual layer types for a couple of reasons: They're interpreted differently for each layer (all levels of the array share a single viewport, so you don't need to pass the view) and there may be other values that need to be queried only for that layer type (like the array texture level). To me it makes sense to group these queries on the layers themselves for flexibility, and it would help simplify some of the spec langauge to boot!
  • I did add getLevel to the XRWebGLArrayLayer but it's not clear to me if that's useful or if we just want to say "texture level N is always associated with view N".

Let's hear everyone's thoughts on this!

Are WebGLFramebuffers needed for layer types other than projection?

Something of a continuation of a comment thread from #14. For the sake of simplification, I'd like to examine whether or not it's possible for us to only use the current opaque framebuffer surfaces for projection layers, and force everything else to use textures in their respective APIs.

The primary benefit of doing so would be allowing the layer creation implementation and use to be significantly simpler and reduce the amount of layer factories needed.

The primary downside would be that any non-projection layers in WebGL 1.0 would not have antialiasing, and in WebGL 2.0 they would need to rely on blitting from multisampled framebuffers for antialiasing until multisample render to texture extensions are available. (WebGPU will have multisampled textures as a core feature.)

If this was an acceptable compromise, the way I see it working is like this: Either we'd drop the XRWebGLFramebufferLayerFactory entirely, and rely solely on the current XRWebGLLayer interface to provide framebuffer-backed projection layers OR we'd add a special-case framebuffer projection layer creation function to the XRWebGLTextureLayerFactory (which could probably be renamed to something simpler because we no longer have to differentiate.) Then the remaining factory would take a GLenum for the texture type desired in the Projection, Quad, Cylinder, and Equirect factory methods. This would allow the developer to choose between gl.TEXTURE_2D or (if they created the factory with a WebGL 2.0 context) gl.TEXTURE_2D_ARRAY as the backing texture type. (Cube layers would always return gl.TEXTURE_CUBE_MAP textures) The fact that the user specifies it means that there's less confusion about the internal format and what framebuffer binding methods they need to use.

Possible IDL:

interface XRWebGLLayerFactory {
  constructor(XRSession session, XRWebGLRenderingContext context);

  double getNativeProjectionScaleFactor();

  Promise<XRProjectionLayer> requestProjectionLayer(GLenum textureTarget, XRProjectionLayerInit init); // Note different dictionary
  Promise<XRQuadLayer> requestQuadLayer(GLenum textureTarget, XRLayerInit init);
  Promise<XRCylinderLayer> requestCylinderLayer(GLenum textureTarget, XRLayerInit init);
  Promise<XREquirectLayer> requestEquirectLayer(GLenum textureTarget, XRLayerInit init);
  Promise<XRCubeLayer> requestCubeLayer(XRLayerInit init);

  XRWebGLTextureSubImage? getViewSubImage(XRLayer layer); // for mono layers
  XRWebGLTextureSubImage? getViewSubImage(XRLayer layer, XRView view); // for stereo layers
}

The XRLayer types don't need to change to accommodate this, but we do get to drop the XRWebGLFramebufferSubImage interface. We'd also maybe want a new XRProjectionLayerInit dictionary because the existing XRWebGLLayerInit dictionary explicitly mentions framebuffer scale, which would no longer be an accurate term, and antialiasing, which is not applicable to the texture layers.

Whether or not this works for us is largely based on what kind of content we expect developers to put into non-projection layers and how willing we believe them to be to use WebGL 2.0 when antialiasing is a must. In my experience quad and cylinder layers are frequently populated with pre-rendered images or videos, for which hardware multisampling won't matter. (Equirect/Cube layers seem to be almost exclusively used with prerendered content.) UIs seem to be the other primary use, and so that would hit some limitations, but they may be largely mitigated by finding a way to enable DOM content in layers, at which point the browser's renderer is expected to do any antialiasing for us. The remaining cases can treat antialiasing of those layers as a quality enhancement that can be provided by using WebGL 2.0.

Thoughts?

Question on the high level goals of immersive web layers

I have a question as to the higher level goals of layers (I'd likely develop layers via Threejs and Aframe) -

Would layers allow "holographic" or volumetric applications to share a common skybox(or lack of) and environment safely?

Example -
Music streaming player presented as a 3d interactable.
A user sizeable .25 meter collision sphere, moving a 6 axis controller into this sphere copies user inputs into the streaming applications "iframe" for manipulating the 3d interface of the streaming application.
The application has minimal needed knowledge of the user when the collision sphere isn't activated.
The application is subject to scaling/translation/opacity/et al. by the user.

This exists alongside other active web based applications like -

a 2d chat stream that might have 3d "emojis" inline in its 2d plane.

a 3d model editor with 2d and 3d objects and control surfaces embedded.

I realize layers probably lacks all the necessary moving parts but is it designed with this as an eventual goal? I see XRCubeLayer XRCylinderLayer...

Should each layer's referenceSpace just be space?

A common use-case for a world-locked quad layer is to display a UI slate or video at a fixed point in the world selected by the user. On devices that operate beyond room-scale, like a HoloLens, the app is likely to use the "unbounded" reference space and then make an XRAnchor on which to place their quad.

Apps should be able to specify an anchor space or any other space as the underlying space for their world-locked quad. That then prevents the need to recompute and set the quad's location in the reference space every frame.

Should layer support be requested at session creation time?

The current proposal doesn't specify if there are limits when an author can use layers.
This implies that a session can switch from a regular WebXR session to one that uses layers and vice versa.

Is this something that we want to support? I can see that this would be difficult to implement so it would be nice to avoid.

How to mark layers as dirty?

Non-projection layers don't have to be updated at the device's refresh rate.
What is the best way to indicate if a layer needs to be updated after a Raf?

Is createProjectionLayer sync or async?

In the README, createProjectionLayer is called as an async function:

const layer = await glLayerFactory.createProjectionLayer("texture");

but in the WebIDL it's a sync function:

  XRProjectionLayer createProjectionLayer(XRTextureType textureType, XRProjectionLayerInit init);

Replace isLayerSupported by more sophisticated approach

Klaus wrote:
I'm not sure about the boolean "isLayerSupported" - that's a hard question for the implementation to answer if it doesn't yet know what flags will be set on the layer and what size they'll be.

Alternatively, would it make sense to have a layer configuration attribute set that's provided to both the query function and the layer initializer? That way, there's less risk of inconsistency, and the implementation could potentially respond with "I could do this, but it's unlikely to hit target framerates". That could either be on a layer-by-layer basis, or potentially as a "here's my proposed overall layer configuration" all-at-once call.

Behavior of getSubImage() with non-mono layers?

The getSubImage() method is proposed to make rendering to mono layers more straightforward. I view this as a positive thing, but it leaves the question of what the behavior of the method should be for layers that aren't mono (projection layers or stereo non-projection layers.)

The two most viable options that come to mind are:

  • Report the subImage of xrViewerPose.views[0].
  • Throw an error.

Reporting the 0th view's image has the benefit of allowing developers to get at the texture quickly in the case of a single subdivided TEXTURE_2D or a TEXTURE_2D_ARRAY, allowing them to bind resources or viewports once in some cases. On the other hand, it could also contribute to bad assumptions if we allow different textures per view for TEXTURE_2D, or allow some developers to accidentally use a mono rendering path for non-mono layers. (Hard to fully prevent that type of developer error, though.)

Why does requestQuadLayer and requestProjection layer require a GL target?

Examples from the explainer:

const layer = await glLayerFactory.requestProjectionLayer(gl.TEXTURE_2D_ARRAY, { alpha: false });
const layer = await glLayerFactory.requestQuadLayer(gl.TEXTURE_2D, { pixelWidth: 1024, pixelHeight: 768, stereo: true });

Why do requestProjectionLayer and requestQuadLayer require a GL target? Are we intending to expand these to be more than TEXTURE_2D and TEXTURE_2D_ARRAY in the future?

If the intent is to communicate whether the developer wants a single texture vs an array of textures, seems straightforward to add this as an item to the dictionary passed as the second parameter: texturearray: true.

As an aside, how many XR runtimes prefer side-by-side rendering these days? If there aren't any, my preference would be to have new APIs like these always return texture arrays.

WebIDL for treating `XRWebGLLayer` as an `XRLayer`

The README says "XRWebGLLayer functions as an XRProjectionLayer, but they are kept as distinct types for better forwards compatibility," but this isn't reflected in the WebIDL.

Is the intention that there should be a rype:

typedef (XRWebGLLayer or XRProjectionLayer) XRBaseLayer;

and then use this in the places that a base layer is used? That is in the defn of dictionary XRRenderStateInit (https://www.w3.org/TR/webxr/#dictdef-xrrenderstateinit), the baseLayer field would become:

  XRBaseLayer? baseLayer;

and in the defn of XRRenderState (https://www.w3.org/TR/webxr/#xrrenderstate):

 readonly attribute XRBaseLayer? baseLayer;

Issues with "determine the layout attribute"?

There are a number of issues with https://immersive-web.github.io/layers/#determine-the-layout-attribute

  1. It's not used in the rest of the document.
  2. It uses a"WebGL2RenderingContext context" but later says "If context is a WebGL2RenderingContext..."
  3. It looks like upgrading from WebGL to WebGL2 can cause this to fail, which users may not expect, and may cause friction upgrading.
  4. It took me quite a bit of reading to realize that WebGL1 contexts can use "stereo".

Provide native support for video layers

Equirect and possible cylinder and quad layers should be contructable with a video element for efficient decoding of video streams.
What is the best API surface for this?

What does "a session with layers enabled" mean?

In https://immersive-web.github.io/layers/#updaterenderstatechanges, there is reference to a "session with layers enabled," with a link to https://immersive-web.github.io/layers/#dom-xrrenderstate-layers, which seems to imply it means a session whose render state has a non-null layers attribute.

Is this what's meant? Or does it mean a session created with the layers feature? If so, the link should be to https://immersive-web.github.io/layers/#layers

new interface for `updateRenderState'

We want to pass in an array of layers into XRRenderStateInit.
What would be the best way to express this in IDL?

Should we extend the existing dictionary or should we create a new one?

dictionary XRRenderStateInit {
  double depthNear;
  double depthFar;
  double inlineVerticalFieldOfView;
  XRWebGLLayer? baseLayer;
  FrozenArray<XRWebGLLayer or XRLayer> layers;
}; 

@Manishearth what are your thoughts?

Should layer's init structure have all the attributes?

Currently, only non-changeable parameters are part of the init structure.
@thetuvix and @Manishearth believe that the space and the transform should be part of that init.
@Manishearth argued that all attributes for a layer should also be in that structure.

I think the current API design is more consistent and it's easy for authors to change the attributes after the layer structure.

Hint 'static' for static layers?

There are layers which are not changing at all, for example 360 photos. In this case, compositor may save on GPU memory by allocating only one texture instead of full swapchain, which could be quite significant considering high resolution of such textures (4K x 4K). Would be great to have a hint 'static : true' provided at layer creation.

Should `getSubImage()` take an XRFrame?

I've been assuming that, much like the framebuffer attribute of an XRWebGLLayer is only complete during an animation frame callback that our new layer's sub images would only be retrievable during an animation frame. getViewSubImage() is already well designed for this, since we can validate that the XRView being passed in is for active XRFrame before returning an image, but getSubImage() (the mono variant) only takes the XRLayer right now. Passing in an XRFrame would help reinforce what context the API is intended to be used in and make the validation logic simpler.

Inline sessions with layers

What should happen when we create an inline session with layers?
Should we support a single projection layers or should we reject creation if layers are requested?

More general layer quality hints. (AKA: Enabling Oculus Go-style fixed foveation)

Currently today we have one hint that can be supplied to an XRWebGLLayer after it's creation to adjust performance: The viewport size for each view can be adjusted using requestViewportScaling(). As the name implies, this is only a request and the system is free to ignore, clamp, or otherwise tweak the requested values.

This pattern seems like it could be made more general, and in doing so provide some overall guidance for ways that vendors can safely experiment with similar features that may not be supported everywhere. A concrete example is the fixed foveation technique used by the Oculus Go (and enabled via OpenGL extensions on similar hardware). This is a feature which could probably be safely turned on by default at it's lowest level with close to no visual impact and a minor performance boost, but developers can get more out of it by intentionally opting-in to higher levels of foveation knowing that there's a quality/performance tradeoff being made that will only be appropriate for certain kinds of content.

Ideally we'd like to allow browser/hardware vendors to enable developers to make that tradeoff while having as little impact on the API surface as possible and clearly communicating that invoking the functionality is a hint to the system, not a guarantee. To that end, I'd propose the following API change:

dictionary XRWebGLLayerHints {
  double viewportScale = 1.0;
  // In the near future: XRFoveationLevel foveatedRendering = "low"; ?
};

partial interface XRWebGLLayer {
 // Remove requestViewportScaling();
  void setLayerHints(XRWebGLLayerHints hints);
};

Which would turn the current viewport scaling logic into:

xrLayer.setLayerHints({ viewportScale: 0.75 });

The benefit here is that we've now established a clear place for these kinds of hints to happen, in a form that allows vendors to experiment with hardware-specific features without disrupting the core API much. Taking that notion further, we may want to institute a pattern in the spec that anything which is not guaranteed to take effect is appropriately labeled as a "hint". (For example, maybe framebufferScaleFactor is better described as framebufferScaleHint since we know that systems like Windows Mixed Reality can't honor it.)

I'm curious what the other CG members think of this approach, and also if there are features that you would have in mind to apply such a system to (or, perhaps more importantly, features that this model doesn't accommodate well.)

Can webxr layers be used with WebGL1?

Looking over the examples in the explainer, it doesn't look like there's much coupling with WebGL2, just the use of the constant gl.TEXTURE_2D_ARRAY in glLayerFactory.requestProjectionLayer(gl.TEXTURE_2D_ARRAY) and the call to gl.framebufferTextureLayer for binding stereo layers. Should the API be usable in WebGL1?

VRLayer.type, VRLayer.srcBlend / dstBlend, VRLayer.flags in 2.0?

As far as I can tell, currently there is no way to distinguish one layer from another in terms of their types, all of them seem to be equal. This doesn't make much sense for Oculus, because we have several layer types (such as eye buffer, cylinder layer, loading icon layer, etc). Moreover, each layer may have its own srcBlend / dstBlend settings, it could have flags (head-locked, Chromatic Aberration correction on/off, spinning on/off, etc). How this supposed to be handled in 2.0?

Can the XR___LayerFactory names be more general purpose?

I've suggested this before, but felt at the time it was more important to get some of the basic usage patterns nailed down first. Now that we've established the broad strokes of the API and I've got a concrete use case outside of layers to point at as an example I'd like to revisit it.

In the Lighting Estimation API we need to deliver a cube map in an API-appropriate texture format. In order to make the WebXR/WebGL/(Eventual WebGPU) interaction easier the current explainer IDL proposes using the XRWebGLLayerFactory as the method of surfacing that texture, since it's already well positioned to serve up WebGL-specific resources for the session.

The only real issue with this route is that it makes the name XRWebGLLayerFactory a misnomer, since it would provide more than just layers. @kearwood and I would both prefer to see the name changes to something more generic as a result.

I'm really flexible on what that name is, as long as it suggests that it handles more WebGL resources than just layers. A few suggestions in no particular order of preference.

  • XRWebGLInterface (may be confused with the IDL "interface" concept)
  • XRWebGLBinding
  • XRWebGLGraphicsBinding
  • XRWebGLSessionBinding
  • XRWebGLResourceProvider

Should the depth stencil buffer be optional

I updated the layers proposal so on platforms that don't use the depth buffer for reprojection, the depth/stencil texture is always null.
Was that the right thing to do?
/agenda

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.