image/svg+xml
Advanced Gradients
SVG Open 2011
Tavmjong Bah
Advanced Gradients
Tavmjong Bah
SVG Open 2011
Advanced Gradients
Tavmjong Bah
SVG Open 2011BostonOctober 18th
* Needs and Requirements.* Types of Advanced Gradients.* Why Coons-Patch Meshes?* Proposed Syntax.* Examples.* Remaining issues.
Overview
Need for Advanced Gradients
* To create life-like vector art.* 3D lighting effects.* Fills that follow curves.
Desire for smooth color variations alongcurved paths.
One can simulate this with linear and radialgradients, and Gaussian Blurs... but it's hard.
Requirements
A more completed discussion can be found inan SVG working group document:
http://dev.w3.org/SVG/modules/advancedgradients/SVGAdvancedGradientReqs.html
* Able to render life-like objects.* Easy for content creators to use.* Straight forward to implement.
Most important requirements:
Types of Advance Gradients
Gourand-shaded triangle meshes:* Free Form* Lattice-Form
Types of Advanced Gradients
Coons Patch Defined by 4 cubic Bézier curves and 4 corner colors. Can simulate conical gradients as well as triangle meshes.Tensor-Product Coons Patch plus four extra contol points that control color spread.
Types of Advanced Gradients
Delaunay Triangulation Create a triangle mesh by only defining the color at a set of points. The triangles are then constructed to satisfy the Delaunay condition. Problems with discontinuities in shading. Curved edges require many small triangles.Diffusion Curves Use color along a curved path to define a gradient. See Jasper's talk for an example. This is a rather new idea and problems with rendering and color control need to be further studied.
Why Coons Patch Mesh Gradients?
* Life-like shadings.* Easy for content creators to use.* Straight forward to implement... mature technology. (PostScript, PDF, Poppler, Cairo)
I am not an artist!
Proposed Syntax
* Each patch requires: - 4 Bézier paths: 4 corner points 8 “handle” points - Four colors.* Adjacent patches share one path and two colors. - In PostScript/PDF, each patch can share one edge definition with the immediately preceeding defined patch.
<linearGradient x1="100" y1="100" x2="200" y2="200"><stop offset="0" stop-color="#000000">...<stop offset="1" stop-color="#ff0000"></linearGradient><radialGradient cx="100" cy="100" r="100" fx="150" fy="150"><stop offset="0" stop-color="#000000">...<stop offset="1" stop-color="#ff0000"></radialGradient>
Proposed Syntax 2
* Existing gradients:
<linearGradient x1="100" y1="100" x2="200" y2="200"> <stop offset="0" stop-color="#000000"> ... <stop offset="1" stop-color="#ff0000"></linearGradient><radialGradient cx="100" cy="100" r="100" fx="150" fy="150"> <stop offset="0" stop-color="#000000"> ... <stop offset="1" stop-color="#ff0000"></radialGradient>
Adapt for mesh gradients by associatingone stop per patch side.
Proposed Syntax 3
* Use rectangular grid: - Easy to create (or delete) rows and columns. - Compact data by sharing sides and corners.
1
2
3
4
5
6
7
8
9
10
11
12
Row 1
Row 2
Row 3
Proposed Syntax 4
* Rectangle grid is conceptial only. Actual mesh can be distorted in any way possible.
A single rowcan be usedto producea conicialgradient
1
2
3
4
5
8
6
7
Proposed Syntax 5
<meshGradient x="100" y="100" id="example"> x, y used for initial moveto. <meshRow> No attributes, used only to define begin/end of row. <meshPatch> <stop path="c 25,-25 75, 25 100,0" stop-color="blue" /> <stop path="c 25, 25 -25, 75 0,100" stop-color="green" /> <stop path="c -25, 25 -75,-25 -100,0" stop-color="orange" /> <stop path="c -25,-25, 25,-75" stop-color="red" /> No final point (closed path). </meshPatch> <meshPatch> <stop path="c 25,-25 75, 25 100,0" /> stop-color from previous patch. <stop path="c 25, 25 -25, 75 0,100" stop-color="green" /> <stop path="c -25, 25 -75,-25" stop-color="orange" /> Last point not needed. Last path (left side) taken from right side of previous path (with points reversed). </meshPatch> ... </meshRow> <meshRow> New row. <meshPatch> First path (top side) taken from bottom path of patch above. <stop path="c 25, 25 -25, 75 0,100" /> stop-color from patch above. <stop path="c -25, 25 -75,-25 -100,0" stop-color="orange" /> <stop path="c -25,-25, 25,-75" stop-color="red" /> </meshPatch> ....
Proposed Syntax 6
The following rules apply: * Allowed path elements are: closepath: 'Z', 'z'. lineto: 'L', 'l' curveto (cubic): 'C', 'c' * A 'Z' or 'z' path closes the path to the nominal end point for a given patch. * Each 'L' or 'l' path consists of one point, using the last node of the previous path as the first node of the current path, except if the path is the last path in a patch, in which case no point is given. * Each 'C' or 'c' path consists of three points or two if last path in patch. * A missing path is equivalent to a 'Z' or 'z' path. * The stop-color and stop-opacity are assigned to the corner at the start of the path. This follows the Cairo conventions (which follows the PDF convention).
Tested with modified version of Inkscape.
Examples
I am not an artist!
Examples 2
I am not an artist!
Outstanding Issues
* Tensor Meshes? - Requires adding a "handle" for each patch corner. - Would allow importing PDF Tensor meshes. How common? - Spread of color already depends on Bézier curve handle placement so may be somewhat redundant.
Outstanding Issues 2
* Different colors or paths at patch boundaries? - Would allow creating sharp color changes or holes in mesh. - Complicates syntax and editing somewhat.
Outstanding Issues 3
* Additional Path Elements?- lineto shortcuts: H, h, V, v --- Minimal savings.- curveto (cubic) shortcuts: S, s --- Possibly useful.- curveto (quadratic) Q, q, T, t --- Not so useful.- elliptical arc --- would require renderers to convert to cubic Bézier. For arcs of 90 degree error is ~0.02% but increase rapidly for larger angles.
Summary
* SVG Working group has approved adding Coons-Patch Mesh Gradients to standard.* Working on final syntax.* Syntax being tested with Inkscape.