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
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 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);
scales the maximum depth slope of the polygon, and
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 . The
values , , and may each be positive,
negative, or zero. Calling the command PolygonOffset is equivalent
to calling the command PolygonOffsetClamp with equal to
zero."
Replace the 6th paragraph...
"The offset value o for a polygon is
_
| m x + r x , if = 0 or NaN;
|
o = < min(m x + r x , ), if > 0;
|
|_ max(m x + r x , ), if < 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
parameter, or should it specify all three of the parameters
, , and ?
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
and values at the same time it sets the 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 value were to be
defined.
RESOLVED: This extension defines a new command that specifies
the , , and parameters.
2) What happens if is infinity or NaN?
As per Section 2.1, the result of providing an infinity or NaN
is unspecified. However, if 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 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 is infinity or NaN, then no clamping is
applied to the polygon offset.
3) What happens if 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