W3C home > Mailing lists > Public > public-fx@w3.org > July to September 2016

Re: [css-transforms] CSS3D breaks with opacity flattening

From: Matt Woodrow <mwoodrow@mozilla.com>
Date: Mon, 19 Sep 2016 10:38:00 +1200
To: "Tab Atkins Jr." <jackalmage@gmail.com>, Rik Cabanier <cabanier@gmail.com>
Cc: /#!/JoePea <trusktr@gmail.com>, Chris Harrelson <chrishtr@google.com>, Simon Fraser <simon.fraser@apple.com>, "public-fx@w3.org" <public-fx@w3.org>
Message-ID: <429adeb7-ef63-6685-400e-bbd1aa6e9f2d@mozilla.com>
> Yes. This is not a spec bug, it's a natural and unavoidable
> consequence of doing a "group effect", which opacity, filters, and a
> few other effects are.  These types of effects require the group to be
> rendered as a unit, then have the effect applied; in 3d space, this
> has the effect of flattening them. (If you didn't flatten, then other
> items could get between the individual pieces in 3d order, and there's
> no consistent or sensible way to render that. This is identical to how
> z-index is "flattened" by opacity and other group effects, so you
> can't sandwich elements elsewhere in the page between the elements in
> the group.)
>
> If you want to sandwich things, you need to push the effect further
> down into the leaves, so it doesn't group as many things together.
> This lets you do more re-ordering, but has a different visual effect -
> if one item occludes another in a group, when they're made transparent
> they still occlude; if they're made individually transparent, you'll
> be able to see the second item behind the first.  Similar differences
> exist for other group effects - if you're doing a gaussian blur,
> blurring two boxes as a group can look quite different than blurring
> them individually.
Can we instead solve this by applying the opacity to the group in the 
final coordinate space (at the root of the 3d context) rather than at 
the local coordinate space where the opacity is set?

An example:

<div id="a" style="transform-style:preserve-3d; transform:rotateY(20deg)">
   <div id="b" style="transform-style:preserve-3d; 
transform:rotateY(20deg)">
     <div id="c" style="transform:rotateY(20deg)"></div>
     <div id="d" style="transform:rotateY(15deg)"></div>
   </div>
   <div id="e"></div>
</div>

This tree is roughly handled internally as if it were:

<div id="c" style="transform:rotateY(60deg)"></div>
<div id="d" style="transform:rotateY(55deg)"></div>
<div id="e" style="transform:rotateY(20deg)"></div>

If we then apply opacity:0.5 to 'b', then can't we make the internal 
representation:


<div id="b" style="opacity:0.5">
   <div id="c" style="transform:rotateY(60deg)"></div>
   <div id="d" style="transform:rotateY(55deg)"></div>
</div>
<div id="e" style="transform:rotateY(20deg)"></div>

This doesn't involve flatten at an intermediate stage, but still 
preserves the 'group' nature of opacity.

Obviously this would prevent depth sorting occurring between elements 
inside and outside of 'b', and we need to figure out how to depth sort 
'b' itself (given that it is an atomic entry for sorting, but isn't a 2d 
plane), but those seem solvable.

I think the logical concept of wanting to apply group opacity to a set 
of elements (an 'object') before positioning that object into the higher 
level 3d scene is a reasonable one, and we should try support it if 
possible.

- Matt
Received on Sunday, 18 September 2016 22:38:35 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 19:49:57 UTC