Re: [3d-transforms] Behavior of intersecting layers with transform-style: preserve-3d is undefined and inconsistent across implementations

On Oct 6, 2011, at 10:59 PM, Simon Fraser wrote:

> On Oct 6, 2011, at 5:48 pm, James Robinson wrote:
> 
>> (note: this is an offshoot of the www-style thread "[css-shaders] subdivision for transparency" http://lists.w3.org/Archives/Public/www-style/2011Oct/0117.html - please refer to that thread for the original context)
>> 
>> CSS 3D Transforms defines a transform-style property preserve-3d defines the behavior of its children to "maintain their position in 3D space".  (I'm referring to the Editor's Draft http://dev.w3.org/csswg/css3-3d-transforms/ dated March 21, 2011).  This property is used extensively in demos - for example the Poster Circle demo (http://www.webkit.org/blog-files/3d-transforms/poster-circle.html) uses it - but the rendering and interactive behavior is not well defined and implementations today differ considerably in how they interpret this property.  For example, in this demo made by Gregg there are 3 rotating intersecting semitransparent <div>s inside a preserve-3d ancestor:
>> 
>> http://greggman.com/downloads/examples/intersecting-elements-3d-css.html
>> 
>> The rendering produced by Safari is:
>> http://greggman.com/downloads/examples/correct-3d-css-polygon-sorting-subdivisions-safari.png
>> 
>> In Google Chrome:
>> http://greggman.com/downloads/examples/correct-3d-css-polygon-sorting-subdivisions-safari.png
>> 
>> Recent Firefox nightlies produce a rendering that is closer to Google Chrome's.  The Safari rendering implies that they are subdividing each layer into two portions and rendering the rearmost portions first.  A related behavior is hit testing - in Safari or Google Chrome, the portion of the <div>s that appear visual closer in the Safari rendering are selectable.  In Firefox, the hit testing order appears to ignore the preserve-3d style and is the same regardless of the rotation state.
>> 
>> I think the Safari behavior makes the most sense here for both rendering and hit testing, but this should be clearly defined in the specification so that vendors can produce interoperable implementations and developers can know what to expect.  This would be somewhat novel for CSS in that instead of having a global paint / hit testing order of CSS boxes we would have an order of convex polygons within CSS boxes, but there isn't any real alternative for this feature.  This feature also complicates implementations and requires more computation effort, but again I don't think there is a valid alternative.  We also need to define this behavior in relation to the CSS shaders proposal (https://dvcs.w3.org/hg/FXTF/raw-file/tip/custom/index.html).  From the www-style thread it sounds like the consensus there is to treat transformations within a shader as if that element were isolated in its own transform-style: flat section, which seems fine at first glance, but it needs to be clearly defined.
>> 
>> I do not think it is acceptable to leave this behavior implementation-defined.  Having objects share a 3d space and thus having their paint order defined by their position in that space is the point of having transform-style: preserve-3d, if that behavior is undefined then we might as well not have the feature in the spec at all.
> 
> All good valid points. I'll be the first to admit that 3D rendering is poorly defined in the CSS 3D transforms spec (and I've had a action item to fix up the spec with more details for way too long).
> 
> I think the main points related to 3D transforms are the following:
> 
> 1. Intersection behavior is left undefined in the spec. This was done deliberately because, as you state above, it's hard to implement. Safari relies on Core Animation for this behavior. The algorithm used is Newell's algorithm <http://en.wikipedia.org/wiki/Newell's_algorithm>. Perhaps the spec should refer to this.

I think it's reasonable to make a non-normative reference to this algorithm. But I still think we should leave the required rendering of intersecting elements undefined. The reason is that subdivision can't solve all problems. There are edge cases where you'll get different ordering based on different implementation choices. These tend to be rare and involve several intersecting faces, but I don't think we can require a certain subdivision and rendering order in all cases of intersecting elements. If an implementation makes a reasonable attempt at implementing Newell's algorithm, I think the browsers will have the same appearance in most cases.

> 
> 2. Whether 3d-transformed elements intersect with other elements (including each other and their parent element) in the absence of transform-style: preserve-3d. Current Safari behavior is that they do, but an alternative proposal would be that they do not, and that 3D transforms are simply a painting effect (in other words they'd behave just like 2D transforms). However, we'd have to decide whether 3D-transformed elements continue to paint in document order, or whether front-to-back order is affected by position on the z-axis. If the latter, then you either have to depth-sort by some arbitrary point (like the element center point), or you have to buy into allowing intersection.

Seems reasonable to let flattened layer behave like 2D, and leave the preservation of 3D rendering and picking order to the preserves-3d case.

> 
> 3. If an element has transform-style: preserve-3d, then I think intersection between its transformed children should always occur. It seems reasonable to also allow intersection between children and other non-transformed elements (i.e. everything else rendering into the z=0 plane, including the parent).
> 
> 4. When transform-style: preserve-3d is applied to a nested set of elements, all transformed elements in that subtree live in a common 3D space and intersect with each other.

I think we should specify rendering order for preserve-3d element which do not intersect. Then we should leave the rendering of intersecting elements undefined, but recommend subdivision for more accurate rendering.

> 
> 5. When considering hierarchies with some transform-style: preserve-3d elements, I'm not sure how to specify which elements cause flattening and which don't, especially when combined with positioning, and properties that can create stacking context. I suspect that something based on containing blocks is appropriate, but haven't thought it through. Safari's behavior here is inconsistent.
> 
> In all cases, hit testing should match rendering.

That might be hard if we leave some of the intersection cases undefined. Again, with intersection, I  think we should make recommendations but not require a certain rendering order, or that rendering and picking match. I know that ties authors' hands some, but what it really says is that you should avoid intersection if you want consistent results.

-----
~Chris
cmarrin@apple.com

Received on Friday, 7 October 2011 16:23:55 UTC