Name

    ARB_polygon_offset_clamp

Name Strings

    GL_ARB_polygon_offset_clamp

Contact

    Piers Daniell (pdaniell 'at' nvidia.com)

Contributors

    Eric Lengyel, Terathon Software
    Tobias Hector, Imagination Technologies

Notice

    Copyright (c) 2017 The Khronos Group Inc. Copyright terms at
        http://www.khronos.org/registry/speccopyright.html

Specification Update Policy

    Khronos-approved extension specifications are updated in response to
    issues and bugs prioritized by the Khronos OpenGL Working Group. For
    extensions which have been promoted to a core Specification, fixes will
    first appear in the latest version of that core Specification, and will
    eventually be backported to the extension document. This policy is
    described in more detail at
        https://www.khronos.org/registry/OpenGL/docs/update_policy.php

Status

    Draft

Version

    Last Modified Date: April 3, 2017
    Revision: 1

Number

    ARB Extension #193

Dependencies

    OpenGL 3.3 (either core or compatibility profiles).

    This extension is written against the OpenGL 4.5 (Compatibility Profile)
    Specification (October 24, 2016).

Overview

    This extension adds a new parameter to the polygon offset function
    that clamps the calculated offset to a minimum or maximum value.
    The clamping functionality is useful when polygons are nearly
    parallel to the view direction because their high slopes can result
    in arbitrarily large polygon offsets. In the particular case of
    shadow mapping, the lack of clamping can produce the appearance of
    unwanted holes when the shadow casting polygons are offset beyond
    the shadow receiving polygons, and this problem can be alleviated by
    enforcing a maximum offset value.

IP Status

    No known IP claims.

New Procedures and Functions

    void PolygonOffsetClamp(float factor, float units, float clamp);

New Tokens

    Accepted by the <pname> parameters of GetBooleanv, GetIntegerv,
    GetInteger64v, GetFloatv, and GetDoublev:

        POLYGON_OFFSET_CLAMP                    0x8E1B

Additions to Chapter 14 of the OpenGL 4.5 (Compatibility Profile) Specification
(Fixed-Function Primitive Assembly and Rasterization)

 -- Modify Open GL section 14.6.5 "Depth Offset"

    Replace the 1st paragraph...

    "The depth values of all fragments generated by the rasterization of
    a polygon may be offset by a single value that is computed for that
    polygon. The function that determines this value is specified with
    the commands

     void PolygonOffsetClamp(float factor, float units, float clamp);
     void PolygonOffset(float factor, float units);

    <factor> scales the maximum depth slope of the polygon, and <units>
    scales an implementation-dependent constant that relates to the
    usable resolution of the depth buffer. The resulting values are
    summed to produce the polygon offset value, which may then be
    clamped to a minimum or maximum value specified by <clamp>. The
    values <factor>, <units>, and <clamp> may each be positive,
    negative, or zero. Calling the command PolygonOffset is equivalent
    to calling the command PolygonOffsetClamp with <clamp> equal to
    zero."

    Replace the 6th paragraph...

    "The offset value o for a polygon is
          _
         |   m x <factor> + r x <units>,          if <clamp> = 0 or NaN;
         |
    o = <    min(m x <factor> + r x <units>, <clamp>),   if <clamp> > 0;
         |
         |_  max(m x <factor> + r x <units>, <clamp>),   if <clamp> < 0.

    m is computed as described above. If the depth buffer uses a fixed-
    point representation, m is a function of depth values in the range
    [0, 1], and o is applied to depth values in the same range."

Additions to the AGL/EGL/GLX/WGL Specifications

    None

GLX Protocol

    A new GL rendering command is added. The following command is sent
    to the server as part of a glXRender request:

        PolygonOffsetClamp
            2           16              rendering command length
            2           4225            rendering command opcode
            4           FLOAT32         factor
            4           FLOAT32         units
            4           FLOAT32         clamp

Errors

    None

New State (OpenGL)

    Get Value                Type  Get Command  Initial Value  Description           Sec     Attrib
    ------------------------ ----  -----------  -------------  --------------------  -----   -------
    POLYGON_OFFSET_CLAMP      R    GetFloatv          0        Polygon offset clamp  14.6.5  polygon

New Implementation Dependent State

    None

Issues

    1)  Should the PolygonOffsetClamp command specify only the <clamp>
        parameter, or should it specify all three of the parameters
        <factor>, <units>, and <clamp>?

        Defining a new command that specifies new state in addition to
        state that can be specified with an existing command has a
        precedent in the BlendFuncSeparate command. The argument can be
        made that an application would usually want to set the <factor>
        and <units> values at the same time it sets the <clamp> value,
        and making one GL call is better than making two GL calls.
        Furthermore, requiring that a call to PolygonOffset sets
        POLYGON_OFFSET_CLAMP to zero insulates applications unaware
        of the new state from failures to restore it to its initial
        value in separate libraries, and this cannot be done if an
        orthogonal command specifying only the <clamp> value were to be
        defined.

        RESOLVED: This extension defines a new command that specifies
        the <factor>, <units>, and <clamp> parameters.

    2)  What happens if <clamp> is infinity or NaN?

        As per Section 2.1, the result of providing an infinity or NaN
        is unspecified. However, if <clamp> is positive or negative
        infinity, then Equation (3.13), in the literal mathematical
        sense, is effectively reduced to the case in which no clamping
        occurs, and this should be the defined behavior.

        If <clamp> is a floating-point NaN, then we could leave the
        result undefined, but that could lead to application code
        working correctly with one implementation and then inexplicably
        failing with another. It would be better to define the behavior
        such that no clamping occurs. If this is not the behavior
        exhibited by the hardware, then the implementation can turn all
        infinites and NaNs into zero using the following code:

            int32_t clampBits = *(int32_t *) &clamp;
            clampBits &= (((clampBits >> 23) & 0xFF) - 0xFF) >> 31;

        This ANDs with all one bits if and only if the floating-point
        exponent is less than 255. Otherwise, it ANDs with all zero
        bits. (This assumes a well-defined right shift of negative
        integers.)

        RESOLVED: If <clamp> is infinity or NaN, then no clamping is
        applied to the polygon offset.

    3)  What happens if <clamp> is a denormalized floating-point value?

        As per Section 2.1, the result of providing a denormalized value
        must yield predictable results. However, some implementations
        may treat denormalized values as equal to zero, and other
        implementations may treat them as greater than or less than
        zero. To ensure uniform behavior across all implementations, we
        can require that denormalized values not be equal to zero. This
        may necessitate that implementations convert denormalized values
        to the smallest representable normalized value with the same
        sign.

        RESOLVED: Denormalized values are not considered equal to zero
        in Equation (3.13).

Revision History

    Rev.    Date      Author     Changes
    ----  ---------- ---------  -----------------------------------------------
    1     2017-04-03 pdaniell   Initial draft for OpenGL 4.6 forked from
                                GL_EXT_polygon_offset_clamp rev. 4