Re: [css-transforms] SVG WG Review of CSS Transform Proposal

On 03/03/2009, at 6:59 PM, Doug Schepers wrote:

> As you know, the SVG WG has also been working on a 3D/2.5D/ 
> Perspective Transforms specification to extend the existing SVG  
> transforms, based on the implementation experience some of the SVG  
> implementers have reported in making their own custom extensions.   
> This seems like an area of much interest and value to authors.  We  
> have modified our own proposal to match the CSS 3D Transfrom spec  
> where possible, and have prepared it for publication;

I sent in some comments on SVG transforms:

http://lists.w3.org/Archives/Public/public-svg-wg/2009JanMar/0148.html

Did I miss a reply? Or is this it?

Most importantly, 3d could be a significant change to SVG's rendering  
model. Has this been described?

> to make sure that content authors are not confused, we would like to  
> publish the FPWD of our spec on the same day as the CSS Transforms  
> specs, with a news item explaining that we are working together to  
> ensure mutual compatibility.  We propose March 11, 2009.
>
> Below are some questions and comments about the proposed CSS  
> Transform specifications.  Please feel free to break them down into  
> individual emails for discussion.
>
> We would like to know if there are any published use cases and  
> requirements for the proposed modules.

There is nothing published.

I'll assume the use cases for 2d transforms are obvious to the SVG  
WG :) Similarly for requirements, these would mostly be shared between  
CSS and SVG.

>  It would help us if we could review the proposals from a better  
> understanding of the particular use cases and requirements you wish  
> to support.  In particular, as discussed below, we would like to  
> know what are the use cases for supporting general 4x4 3D  
> transformation matrices, as opposed to affine 3D plus perspective  
> projection.
>
>
> Are translateX/Y/Z and scaleX/Y/Z necessary, given that the proposal  
> includes translate3d and scale3d? There seems to be little benefit  
> to this redundancy.

These are not necessary - just convenient, and this is a language for  
authors. There isn't a huge cost in adding them, so there seems to be  
little benefit from removing this redundancy :)

I could ask the same thing about most SVG shape primitives, especially  
polygon/polyline/path. It's hard to measure author convenience.


>  In response to minutes from our F2F where we were discussing CSS  
> Transforms, Dean said[3]:
>
>> While these might shortcuts look like syntactic sugar, they allow for
>> something important - which is the ability to break a transform  
>> list into
>> components that can manipulated individually. This is especially  
>> important
>> when you're animating between transforms (not necessarily with CSS
>> Animations, even JS gets the benefit). Flattening all the transform
>> operations is a lossy process (not in the final matrix result, but  
>> you lose
>> the list).
>
> This seems to be an argument against removing translateX/Y/Z etc.  
> and requiring authors to use matrix3d(), rather than an argument  
> against 'translate' etc, taking optional arguments.

My point was that rotate(360deg) != matrix(1, 0, 0, 0, 1, 0) !=  
rotate(0deg) != translate(0, 0)
even though they all evaluate to the same 3x2 (or 4x4) matrix value.

Meanwhile, optional arguments are sometimes confusing. I would predict  
that half the population expect translate(10) to be translate(10, 10)  
rather than translate(10, 0).

>  We understand that flattening the matrix is a lossy process,  
> however isn't translateZ(40) = translate3d(0 0 40)?  You can still  
> get that individual translation component out of the list.
>
>> In general I'm not sure there is benefit in minimising the syntax.  
>> What is
>> the cost?
>
> The cost is minimal by itself, but these things add up, and it seems  
> the benefit is minimal too.  To do y-translation in SVG, you just do  
> translate(0 40); it doesn't seem particularly onerous to specify the  
> 0.

So, other than the extremely important examples I give above  
(rotation), I think this is a pretty minor point, and I'm not sure  
there is any way to choose the "right" answer.

I understand this isn't a great argument for a standards body, but  
WebKit (desktop and phone) and Firefox support the existing syntax for  
transforms, so I'm tempted to leave it unless there is a good reason  
to break interoperability.

> The SVG Working Group appreciates that the CSS 3D Transforms  
> proposal tries to use naming consistent with SVG Transforms.  
> Regarding this, has the CSS Working Group considered extending the  
> 'scale', 'translate' and 'rotate' SVG transform items to allow for  
> both 2D and 3D transforms to be applied based on the values passed  
> in (as opposed to creating extra scale3d et. al. properties)?
>
> For example:
> * scale(<sx> [<sy> [<sz>]])
> * translate(<tx> [<ty> [<tz>]])
> * rotate(<rotate-angle> <nx> <ny> <nz> [<cx> <cy> <cx>])

I'd like to avoid optional arguments if possible. We have the  
opportunity to provide clear authoring, why not take it?


> Since backward compatibility is important we tested current  
> browsers. In most, the entire transform attribute is ignored if it  
> contains a transform item that is invalid under the limitations of  
> SVG 1.1 transforms (such as a scale() with three values). In Opera,  
> all of the transform items up to the invalid transform item are  
> applied, and only the invalid item and those that follow are ignored.
>
>
> In SVG and the CSS 2D Transforms proposal, 'translate' and 'scale'  
> both contain optional parameters so that both symmetric and  
> asymmetric transformation of all axes are possible.

This is in CSS transforms because it is part of SVG. If I had a  
choice, I would not have allowed optional parameters.

> Has the CSS Working Group considered optional parameters for  
> scale3d, translate3d and rotate3d as well?

I do not believe the WG has considered it.

>
> For example:
> * scale3d(<sx> [<sy> <sz>])
> * translate3d(<tx> [<ty> <tz>])
> * rotate3d(<angle> <nx> <ny> <nz> [<cx> <cy> <cz>])
>
>
> Is there any reason a 4x4 transformation model was chosen? OpenVG  
> uses a 3x3 matrix interface and SVG devices that implement CSS 3D  
> Transforms as currently specified will not be able to take advantage  
> of the OpenVG API.

OpenVG is a 2d vector graphics interface. All the 2d vector calls use  
a 2x3 affine matrix (similar to SVG). OpenVG also allows for  
perspective effects on images (and only images, not paths) using a 3x3  
matrix, which is really a homogeneous matrix equivalent to the 2x3  
with a third column that provides the perspective (it would be the  
fourth column in CSS's 4x4 matrix). This enables OpenVG to do a  
rendering effect that looks like perspective, but doesn't really  
change the object in 3d space.

So, yes, OpenVG is not a 3d library, and therefore not completely able  
to implement CSS 3D transforms.  At the same time, it's not completely  
able to implement what SVG is proposing (or at least, what I assume  
authors will expect).

> There exist implementations of SVG on top of OpenVG (such as AlexVG)  
> which otherwise would need to implement their own transform  
> pipeline.  One of the advantages of using OpenVG is existing  
> implementations get hardware acceleration.

This is true. At the same time, OpenGL allows for hardware  
acceleration and is many times more widely deployed. And again, OpenVG  
accelerates the 2d primitives and allows for some 3d effects, but it  
not 3d.

>  Note that the current proposed SVG Transforms Module model is  
> compatible with OpenVG and OpenGL.
>  We would like to see use cases for specifying 4x4 matrices which  
> aren't simply affine 3D transformations plus a single point  
> projection transformation.

What are the use cases for restricting the specification away from 4x4  
homogeneous matrices? I've already described a few features you've  
disabled by restricting to OpenVG (it isn't really 3d, applies only to  
images, etc). But it's not clear to me if you want to be compatible  
with OpenVG, or if you want a 14 value matrix?

I'll assume you want the 14-value matrix because you want 3d.

Now, what are the advantages of using the full 16 (4x4) over the  
slightly simpler 14 (4x4 minus the two perspective values you don't  
want)? Admittedly they are obscure, but not necessarily useless. One  
is the ability to position the view (lens) at a non-parallel angle to  
the viewport - or to allow perspective in more than one direction.  
We've used it internally to help map planes onto the surface of a  
sphere.

But to return to my argument, why choose 14 values over the standard  
16? Obviously there is slightly less computation work, but given the  
speed of today's processors and the fact that you can usually  
accelerate arithmetic operations in multiples of 4, it doesn't really  
matter.

Ultimately (ignoring the fringe use cases), the proposals are not  
hugely different. However, I don't see why it is so important to  
restrict the definition of the "matrix" method - which might  
ultimately be the only effect. Let's stick to the simple and obvious  
case of a regular homogeneous 4x4 matrix.

> Dean in his mail said:
>> I suggest you stick with 4x4 matrices over 3x3. I wouldn't let the  
>> fact
>> that OpenVG is 3x3 (is it? I read this in the minutes but didn't  
>> check)
>> impact the decision.
>
> We believe so.  On http://www.khronos.org/openvg/ it states "Image  
> drawing uses a 3x3 perspective transformation matrix".

As I've said above, this isn't a "real" 3d matrix, and it only applies  
to image rendering. I think you need to clearly state whether you're  
trying to provide a syntax for OpenVG (which is not 3d) or to do 3d  
transformations. If you're doing the latter, then compatibility with  
OpenVG isn't going to be as important.

>> Cameron says that "general 3d effects are not useful" - maybe I
>> misunderstood that?
>
> The intent of Cameron's comment was more along the lines of  
> wondering what effects that you can achieve with a general 4x4  
> matrix that aren't supported by affine 3D plus perspective projection.
>
>
> Is there a reason for allowing perspective to be part of the  
> transform list as well as being a separate property?  Authors could  
> specify multiple perspective transformations (and possibly also the  
> perspective property), which would produce odd results.
>
> For example:
> transform="translate(...) perspective(...) scale(...) rotate3d(...)  
> perspective(...)"
>
>
> The SVG Working Group thinks that 'transform-origin' is a really  
> good property; however, it has the following issues:
>
> * Its initial value is "50% 50% 0", which is incompatible with how  
> SVG transforms work in the absence of transform-origin (i.e., SVG  
> behaves as if "0 0 0" is the default value).  Anne suggested on  
> IRC[4] that SVG elements could have an initial value of "0 0 0"  
> while other elements have "50% 50% 0", but this might be confusing  
> for authors.

Yes, this will be confusing. In fact, we have a choice of confusions.  
Our (apple's) original implementation had the origin at 0,0 (like  
SVG), but it was extremely annoying to author. Reluctantly we moved it  
to 50%,50%, breaking from SVG but making authoring much easier.

Anne's suggestion is nice, and something we already do for other  
properties (like pointer-events, which have default values that do not  
make sense in HTML land). I'm tempted to follow it and see what happens.

> * The property appears to be overloaded in that it seems that the  
> coordinate space that the property operates in depends on the  
> values. Is this correct?

Yes.

> * If lengths are specified for transform-origin is the length  
> measurement taken from the origin of the current coordinate system  
> or from the top left hand corner of the object's bounding box?

It is relative to the object.

>  What if the property was broken up into transform-origin-bbox and  
> transform-origin-userspace or something similar?

What is the benefit? You can already specify origins outside the  
element.

> We discussed 'transform-style' which automatically orders rendering  
> of objects based on Z position of the object when set to  
> "preserve-3d". As Dean mentions, rendering of the content may be  
> difficult for SVG UAs given that SVG uses the painter's algorithm.  
> One possibility is to only allow re-ordering of objects based on  
> their Z position when inside a container with the transform-style  
> property set.

This is something we've been considering recently too. It turns 3d  
into more of a rendering effect than a positioning effect. It has the  
benefit of simplifying hit testing, avoiding intersections, etc. The  
negative is that it doesn't work as many people would expect, in that  
things "closer" to the viewer do not necessarily draw after things  
that are further away. Also, changes in appearance may require changes  
in document order (rather than style).

Authors would have the ability to choose a "full" 3d world by turning  
preserve-3d on. In other words, the complex use cases are still  
possible.

The big question is how useful the simplification is. We're playing  
with in internally now.


> A similar option is to introduce a container element <layeredG>,  
> <g3d>, or <layer> where the order of rendering the child elements is  
> based on their Z position and not the document order. This would  
> help restrict the complexity when rendering objects with 3D  
> transforms in SVG. The SVG Working Group believes this is one  
> possible solution which helps reduce the complexities involved in  
> implementing SVG Transforms. Any comments the CSS Working Group has  
> regarding this would be greatly appreciated.

I'd be tempted to stick to properties, rather than adding new  
elements, especially since HTML requires the property approach.


> Objects with depth may not always be parallel to the screen (as a  
> result of rotations). Two problems can occur as a result of this.  
> Firstly, what is the Z position when an object is not parallel to  
> the screen (e.g. if it has a rotateY applied to it)? Is it the  
> "closest" appearing Z point, the "furthest" appearing Z point, the  
> center of the object, the top left point, or the 4th column 3rd row  
> of the transform matrix?

Our implementation uses the centre of the object, but this needs to be  
specified.

>  Secondly, if two objects have the same Z position, are both not  
> parallel to the screen and intersect, are the objects clipped or is  
> one rendered on top of the other in document order?

This is currently undefined. It would be nice to be able to specify  
that document order wins, but floating point math doesn't always allow  
this easily (and you don't always want order to win). I see this as  
one of the (probably) unavoidable drawbacks of going into 3d. Of  
course, if we choose the simplified approach above, then at least this  
will not happen in some cases.

Note that this problem is why we have a backface visibility property.  
It's pretty common to "flip" an element, which would be implemented by  
having the two faces drawing back to back. Since you can't always know  
which is in front (technically, neither is) you author it so that each  
only draws when it is facing forward.

> The CSS Transform proposal says in the introduction
> [[
> Any value other than ‘none’ for the transform results in the  
> creation of both a stacking context and a containing block. The  
> object acts as though position: relative has been specified, but  
> also acts as a containing block for fixed positioned descendants.  
> The position on the Z axis of a transformed element does not affect  
> the order within a stacking context. With elements at the same z- 
> index, objects are drawn in order of increasing z position.
> ]]
>
> z-index is only mentioned once in the proposal. We assume that this  
> is z-index as defined in the CSS 2.1 specification[5]   and uses a  
> stacking context as described in Appendix E. How would this work  
> with documents that do not establish a stacking context (or  
> alternatively, put everything in one stacking context) such as SVG?

Things get easier without a stacking context. However, what happens in  
SVG land is up to you, and is what you'll need to describe in your  
rendering model :)

My suggestion:

- by default (without preserve-3d): 3d transforms are a rendering  
effect. Drawing order is still document-based painters algorithm.
- in 3d land (preserve-3d on): 3d transforms are really 3d. Drawing  
order happens by depth sorting. 2d flatting happens at the ancestor  
without 3d.


> In CSS Transforms, rotate() takes an <angle> value, which must have  
> a unit.  In SVG, this takes a unitless number (assumed to be in  
> degrees).  The SVG WG is open to exploring the addition of units in  
> transform values, including angle units, into SVG.  We would expect  
> to allow 'deg', 'grad', and 'rad' as units, as already supported in  
> some other SVG attributes, and perhaps to allow for the 'turn' unit  
> also.  For backwards compatibility, we would want both SVG and CSS  
> Transforms to allow unitless values as well, with degrees as the  
> default if no unit is provided.

I'm generally open to this suggestion, but I believe the CSS crowd are  
strongly against unitless values.

> Finally, the CSS list syntax states that "If a function takes more  
> than one argument, the arguments are separated by a comma (‘,’) with  
> optional whitespace before and after the comma."  The SVG  
> specification allows as a list-delimiter token a non-zero-length  
> string consisting of an optional comma and any number of whitespace  
> characters, (\s+|\s*,\s*) in perl regex syntax.  The SVG WG intends  
> to allow this as a general rule in any SVG attributes, to make  
> authoring and implementing easier and more consistent.  We would  
> like for CSS Transforms to allow this as well.

Sure, agreed.

Dean

Received on Tuesday, 3 March 2009 23:31:41 UTC