Name

    NV_path_rendering_shared_edge

Name Strings

    GL_NV_path_rendering_shared_edge

Contact

    Mark Kilgard, NVIDIA (mjk 'at' nvidia.com)
    Jeff Bolz, NVIDIA (jbolz 'at' nvidia.com)

Contributors

    Michael Chock, NVIDIA (mchock 'at' nvidia.com)

Status

    Shipping

Version

    Last Modified Date:  March 27, 2015
    Version:             2

Number

    OpenGL Extension #471
    OpenGL ES Extension #234

Dependencies

    This extension is written against the OpenGL 4.3 (Compatibility)
    Specification but can apply to OpenGL 1.1 and OpenGL ES 2.0 and up.

    This extension requires NV_path_rendering.

Overview

    This extension introduces a new path command modifier to the
    NV_path_rendering extension to indicate that a path command represents an
    edge (either straight or curved) that is shared with another path.

    When used in conjunction with NV_framebuffer_mixed_samples, a shared edge
    (or a whole path including shared edges) will use modified rasterization
    rules in order to ensure that groups of raster samples associated with a
    given coverage sample will all produce consistent coverage results, in
    order to avoid artifacts described further in the issues section at the
    end of this document.

New Procedures and Functions

    None.

New Tokens

    Allowed to be added to command tokens in elements of the <commands>
    array parameter of PathCommandsNV and PathSubCommandsNV:

        SHARED_EDGE_NV                                  0xC0


Modify Section 5.X "Path Rendering" from the NV_path_rendering extension:

    Add to the end of Section 5.X.1 (Path Specification)

    When the value of SHARED_EDGE_NV is bitwise exclusive-ORed with any of the
    path command tokens in Table 5.pathCommands (but not the character
    aliases), the path outline generated by this path command is considered a
    "shared" version of the original command. When such paths are stenciled
    (see section 5.X.2.1), coverage for groups of raster samples corresponding
    to the same color sample must be produce the same result (i.e. must all be
    covered or all be uncovered) with respect to this particular path command's
    contour edge. Depending on the implementation, this modified coverage
    determination may be applied to all edges in a path if that path contains
    any shared edges. When such paths are covered, groups of raster samples
    may also be treated the same way (i.e. altering properties of some samples
    in order to produce the same coverage for all samples in the group).


Additions to the AGL/GLX/WGL Specifications

    None

Additions to the OpenGL Shading Language

    None

GLX Protocol

    None

Errors

    None

Issues

    1.  What is the GL_SHARED_EDGE_NV value for?

        RESOLVED:  Path rendering sometimes requires subregions of two
        paths to be drawn such that they are "watertight".  This means
        that the color samples along this shared contour should not have
        any coverage gaps or double hits.

        The problem with mixed sample frequencies is that fractional
        coverage is computed as a result of the stencil test.  A color
        sample might be 25% covered by one path command edge of path X
        and then 75% covered by the identical path command edge of path
        Y such that path X covers the "righthand" side of the color
        sample and path Y covers the "lefthand" side of the color sample.
        Such situations can cause an artifact known as "conflation"
        that allows a background color to "leak through" the edge when
        the edge is intended by the content creator (often an artist or
        perhaps a path preprocessing tools) to allow no such leakage.

        Consider the watertight edge when the background color is RED
        (1,0,0,1), path X's color is GREEN (0,1,0,1), and path Y's
        color is BLUE (0,0,1,1).  If we draw path X first, we get 25%
        GREEN and 75% RED (the background color) composited into the
        framebuffer assuming a GL_ONE,GL_ONE_MINUS_SRC_ALPHA blend mode
        with the GL_RGBA coverage modulation mode.  The result is
        (0.75,0.25,0.0,1.0).  Now if we draw path Y first, we get
        75% BLUE and 25% of (0.75,0.25,0.0,1.0).  This result is
        (0.1875,0.0625,0.75,1).

        However the arguably "correct" watertight result is
        (0,0.25,0.75,1).  The problem is if we process path X and path Y
        in separate passes, we risk "blending" in some of the background
        color.  The source of this artifact is the assumption that we
        can translate boolean per-sample coverage into a "fractional"
        coverage value.

        Note that this situation occurs even when the paths being rendered
        (X and Y in this example) are 100% opaque.

        At the cost of losing some sub-color sample coverage determination
        accuracy, we can avoid this artifact by marking as a "shared
        edge" path commands that are intended to be watertight with
        edges of the identical path command in another path object.
        When such commands are encountered, coverage computations done
        by NV_path_rendering can be careful to decide the coverage of
        secondary samples with respect to this path edge identically to
        their respective primary sample.  This ensures the coverage (at
        least with respect to this particular edge) is either 0% or 100%.

        Note that unshared edges from path commands not marked as shared
        by the addition of the GL_SHARED_EDGE_NV value are processed
        at the effective raster sample rate.  This ensures that edges of
        the path retain a high level of antialiasing quality.

        This capability is most interesting to path rendering standards
        such as Flash.

    2.  Should the GL_SHARED_EDGE_NV value be bit that can be bitwise
        ORed into a path command?

        RESOLVED:  No.  Instead the GL_SHADED_EDGE_NV value of 0xC0
        (192) should be exclusive-ORed (^) to construct path commands
        with a shared edge.

        Rationale:  The NV_path_rendering assignment of 8-bit token
        values is arranged to match OpenVG for commands OpenVG supports
        and numbers the non-OpenVG commands downward from 255 so there is
        not a bit value to bitwise OR (or even add) that guarantees
        unique values, particularly considering the character alias values
        (such as 'C' for GL_CUBIC_CURVE_TO_NV).

        Bitwise exclusive-ORing with 0xC0 does provide unique values
        for all current (and expected future) path command tokens.


     3. The SVG and PostScript path string grammars don't have a way to
        express shared edges.  Is this a problem?

        RESOLVED:  No.  We support these grammars "as is" from SVG and
        PostScript.  These standards don't really have a way to convey
        shared edges in paths as Flash shapes allow.

     4. What does GL_MOVE_TO_NV^GL_SHARED_EDGE_NV mean?

        RESOLVED:  Bitwise exclusive-ORing GL_SHARED_EDGE_NV works for
        any legal path token.

        GL_MOVE_TO_NV+GL_SHARED_EDGE_NV means the same as GL_MOVE_TO_NV
        because the GL_MOVE_TO_NV don't really generate an edge (and
        likewise for its variant GL_RELATIVE_MOVE_TO_NV).

        Yes, it is legal.

     5. What about 'C'+GL_SHARED_EDGE_NV?  Are these allowed?

        RESOLVED:  No.

        Character aliases don't support the bitwise exclusive-ORing of
        GL_SHARED_EDGE_NV.  This is to reduce the risk of collisions
        with character aliases and future path commands.


Revision History

    Revision 2, 2015/03/27
      - Add ES interactions

    Revision 1
      - Internal revisions.
