- From: <bugzilla@jessica.w3.org>
- Date: Mon, 19 Aug 2013 22:00:54 +0000
- To: public-css-bugzilla@w3.org
https://www.w3.org/Bugs/Public/show_bug.cgi?id=23014 Bug ID: 23014 Summary: Backface-visibility cannot be tested by only looking at m33 Classification: Unclassified Product: CSS Version: unspecified Hardware: PC OS: All Status: NEW Severity: normal Priority: P2 Component: Transforms Assignee: smfr@me.com Reporter: shawnsingh@chromium.org QA Contact: public-css-bugzilla@w3.org CC: ayg@aryeh.name, cmarrin@apple.com, dino@apple.com, dschulze@adobe.com, eoconnor@apple.com, smfr@me.com Created attachment 1386 --> https://www.w3.org/Bugs/Public/attachment.cgi?id=1386&action=edit Example of a transform that needs to account for perspective for correct backface-visibility. According to the current spec, backface-visibility must be checked by testing whether the m33 element of the matrix is positive or negative. But the problem is that this only works without a perspective component. Actually, it seems like this is already acknowledged since the spec says "before accounting for perspective". However, backface-visibility will often need to be tested on matrices that have perspective in them: - by definition of the "accumulated 3d transformation matrix" the perspective will be included in that matrix - a user may use the matrix3d() transform function in their CSS to specify arbitrary perspective on an element, even if it is not in a 3d rendering context. I attached an example page with a layer rotated just more than 90 degrees. In this configuration, the layer's backface would be visible if there is an orthographic projection. Under perspective projection, if set up correctly, the layer's front side is actually visible. The accumulated 3d transformation matrix of that example is: [ +1.0574 +0.0000 +2.4037 +88.5277 +1.2310 +1.0000 +0.4341 +53.7981 -0.4924 +0.0000 -0.1736 +98.4808 +0.0025 +0.0000 +0.0009 +0.5076 ] The m33 element is negative, but because of perspective, we should interpret that the front side of the layer is facing the camera. Instead of checking m33, there are at least two ways to correctly implement backface visibility: (1) Inspect vertices of the element being drawn for clockwise / counter-clockwise, similar to how game engines often perform backface culling (2) Rigorously apply the transform the z normal, and check the transformed normal is still facing the camera (i.e. it's z value is positive or negative). However, we cannot just apply the transform to the z normal by doing a basic matrix*vector operation --> that is why checking m33 only is not correct. Instead, mathematically if we want to transform a surface normal, we must do inverseTranspose(matrix) * normalVector. Knowing that the normalVector is (0, 0, 1, 0), we don't have to compute a heavy full inverse, and the implementation can remain mostly lightweight. You can see chrome's implementation here: https://code.google.com/p/chromium/codesearch#chromium/src/ui/gfx/transform.cc&q=gfx::Transform::IsBackFaceVisible&sq=package:chromium&type=cs&l=219 I have not tested how the attached example works in IE. Firefox, Safari, and Chrome seem to get backface visibility correct on the attached example page -- which implies that no browser is checking for (m33 < 0) anyway. So, would it work just to change the spec to be mathematically correct and to reflect what browsers already implement? -- You are receiving this mail because: You are the QA Contact for the bug.
Received on Monday, 19 August 2013 22:00:56 UTC