Closed Bug 1175311 Opened 9 years ago Closed 7 years ago

[css3-3d-transforms] Elements not rendered in the proper Z order

Categories

(Core :: Layout, defect)

41 Branch
defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME
Tracking Status
firefox41 --- affected

People

(Reporter: dmarcos, Assigned: kip)

References

Details

(Whiteboard: [webvr][vrm2][css-vr])

When using the perspective attribute on the parent element the elements are properly rendered in the z axis order (from back to front). If I don't setup the perspective attribute but a 3dmatrix as projection matrix instead z order is not honored anymore. This is a test case that illustrate the problem: 

http://vr-components.github.io/vr-scene/examples/bugz.html

Unchecking the CSSPerspective box removes the perspective attribute from the parent element and it replaces it by a projection matrix. The slider moves the red square on the z axis
Assignee: nobody → kgilbert
Whiteboard: [webvr]
Blocks: 689498
My WIP patch depends on the refactoring done in Bug 1097464.  I have set it as a dependency.
Depends on: 1097464
Blocks: 1186575
Whiteboard: [webvr] → [webvr][vrm2]
See Also: → 1187209
Bug 1187209 identified a good test case for this:

http://codepen.io/thebabydino/pen/ZGqWGv/

This test case should be able to render correctly without plane splitting if the z order sorting is done correctly.
In order to sort correctly, we need not only to sort by the z-order, but rather determine what side an element is on relative to another when determining their sort order.  The sort order is determined by if the side the element on points towards or away from the viewer.
As not all projection matrices will result in consistent interpretation of the z position increasing towards or away from the viewer, a more reliable method is to sort by w component in homogenous clip-space.  Experiments show that this fixes Diego's case above and solve issues with projection matrices that always result in a fixed z value.

There are some issues with this approach; however:

- A larger w value indicates that an object will be reduced in size, which can be interpreted as farther away; however, this may be a dangerous assumption.

- When two different projection matrices are used in the same viewport, the w values may not be compatible for comparison, resulting in incorrect sorting when elements transformed by different projections overlap.

- We will need to use z values to populate depth buffers, which are essential to increasing performance, occluding CSS content with WebGL content, and enabling Oculus Asynchronous Time-warp for CSS WebVR.

Other browsers were unable to properly sort Diego's example, indicating that they may be sorting by z rather than w:

http://vr-components.github.io/vr-scene/examples/bugz.html

Examples such as Diego's could be updated to use a z-preserving projection matrix.

I suggest that the test case from Bug 1187209 be used for reference when selecting the correct sorting strategy:

http://codepen.io/thebabydino/pen/ZGqWGv/
(In reply to :kip (Kearwood Gilbert) from comment #4)
> As not all projection matrices will result in consistent interpretation of
> the z position increasing towards or away from the viewer, a more reliable
> method is to sort by w component in homogenous clip-space.  Experiments show
> that this fixes Diego's case above and solve issues with projection matrices
> that always result in a fixed z value.
> 
> There are some issues with this approach; however:
> 
> - A larger w value indicates that an object will be reduced in size, which
> can be interpreted as farther away; however, this may be a dangerous
> assumption.
> 
> - When two different projection matrices are used in the same viewport, the
> w values may not be compatible for comparison, resulting in incorrect
> sorting when elements transformed by different projections overlap.
> 
> - We will need to use z values to populate depth buffers, which are
> essential to increasing performance, occluding CSS content with WebGL
> content, and enabling Oculus Asynchronous Time-warp for CSS WebVR.
> 
> Other browsers were unable to properly sort Diego's example, indicating that
> they may be sorting by z rather than w:
> 
> http://vr-components.github.io/vr-scene/examples/bugz.html
> 
> Examples such as Diego's could be updated to use a z-preserving projection
> matrix.
> 
> I suggest that the test case from Bug 1187209 be used for reference when
> selecting the correct sorting strategy:
> 
> http://codepen.io/thebabydino/pen/ZGqWGv/

How do I create a z-preserving matrix?
Flags: needinfo?(kgilbert)
(In reply to Diego Marcos [:dmarcos] from comment #5)
> (In reply to :kip (Kearwood Gilbert) from comment #4)
> > As not all projection matrices will result in consistent interpretation of
> > the z position increasing towards or away from the viewer, a more reliable
> > method is to sort by w component in homogenous clip-space.  Experiments show
> > that this fixes Diego's case above and solve issues with projection matrices
> > that always result in a fixed z value.
> > 
> > There are some issues with this approach; however:
> > 
> > - A larger w value indicates that an object will be reduced in size, which
> > can be interpreted as farther away; however, this may be a dangerous
> > assumption.
> > 
> > - When two different projection matrices are used in the same viewport, the
> > w values may not be compatible for comparison, resulting in incorrect
> > sorting when elements transformed by different projections overlap.
> > 
> > - We will need to use z values to populate depth buffers, which are
> > essential to increasing performance, occluding CSS content with WebGL
> > content, and enabling Oculus Asynchronous Time-warp for CSS WebVR.
> > 
> > Other browsers were unable to properly sort Diego's example, indicating that
> > they may be sorting by z rather than w:
> > 
> > http://vr-components.github.io/vr-scene/examples/bugz.html
> > 
> > Examples such as Diego's could be updated to use a z-preserving projection
> > matrix.
> > 
> > I suggest that the test case from Bug 1187209 be used for reference when
> > selecting the correct sorting strategy:
> > 
> > http://codepen.io/thebabydino/pen/ZGqWGv/
> 
> How do I create a z-preserving matrix?
I have reviewed Diego's projection matrix and found that it does indeed preserve Z.  The resulting matrices when applying the CSS built-in perspective() function also result in a Z preserving matrix.

There must be another reason that the other browsers did not render Diego's example correctly.

A Z preserving matrix is one that does not result in the same Z value for all depths after converting from homogenous coordinates (dividing by W).

An example of creating a Z preserving matrix is described with OpenGL's gluPerspective function:

https://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml
Flags: needinfo?(kgilbert)
Blocks: 1225654
Whiteboard: [webvr][vrm2] → [webvr][vrm2][css-vr]
I just do a test for the example from Diego.  Just like what kip had mentioned, it's matrix is wrong.

Following a modification with a workable transformation.

  <div style="transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.0002, -0.001, 0, 0, 0, 1);" class="viewport">
    <div style="transform: translate3d(0px, 0px, 350px) rotateY(15deg);" class="threed world">
      <div class="threed square green"></div>
      <div style="transform: translate3d(0px, 0px, -300px);" class="threed square red"></div>
    </div>
  </div>
No longer blocks: 689498
I think this bug has been fixed on nightly.  Can anyone confirm it?
Kearwood, could you confirm it?  If this bug is no longer there, bug 689498 would not be blocked any
more.
Flags: needinfo?(kgilbert)
In the current nightly builds, the sort order is still the same as before for Diego's perspective test case.  Essentially, we are not necessarily breaking the rules of the spec, but are inconsistent with other browsers.  To be more consistent with other browsers, we could change the sort order to sort by "w".  I am not certain if the CSS transform spec explicitly specifies "w" or "z" sorting order.

If we don't encounter real-world sites affected by the inconsistency, then technically we are still aligned with the spec and may not need to do anything here.

This bug is not the only one that relates to transformed element sorting order.  In particular, Bug 1187209 illustrates z-sorting that could be correct without plane splitting that we fail to render correctly in current Nightly builds:

http://codepen.io/thebabydino/pen/ZGqWGv/

If the plane splitting allow our simpler sorting algorithm to work in these cases, then it may not be necessary to set these sort order bugs as a dependency to the plane splitting, but rather the other way around.
Flags: needinfo?(kgilbert)
Kip, is this bug still relevant now that the plane splitting / BSP tree layer sorting is completed?
Flags: needinfo?(kgilbert)
This bug may have been fixed with plane splitting.  I'd check the test case described in the description and ensure that it behaves consistently with other browsers with and without the checkbox enabled.
Flags: needinfo?(kgilbert)
Diego: any word on if this still happens?
Flags: needinfo?(dmarcos)
It seems that the original test case above works as expected now. Thanks!
Flags: needinfo?(dmarcos)
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.