• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    NV_clip_space_w_scaling
4
5Name Strings
6
7    GL_NV_clip_space_w_scaling
8
9Contact
10
11    Kedarnath Thangudu, NVIDIA Corporation (kthangudu 'at' nvidia.com)
12
13Contributors
14
15    Eric Werness, NVIDIA Corporation
16    Ingo Esser, NVIDIA Corporation
17    Pat Brown, NVIDIA Corporation
18    Mark Kilgard, NVIDIA Corporation
19    Jason Schmidt, NVIDIA Corporation
20
21Status
22
23    Shipping in NVIDIA release 367.XX drivers and up.
24
25Version
26
27    Last Modified Date:         November 25, 2017
28    Revision:                   4
29
30Number
31
32    OpenGL Extension #486
33    OpenGL ES Extension #295
34
35Dependencies
36
37    This extension is written against OpenGL 4.5 Specification
38    (Compatibility Profile).
39
40    This extension interacts with the OpenGL ES 3.1 Specification.
41
42    This extension requires NV_viewport_array2.
43
44    If implemented in OpenGL ES, one of NV_viewport_array or OES_viewport_array
45    is required.
46
47Overview
48
49    Virtual Reality (VR) applications often involve a post-processing step to
50    apply a "barrel" distortion to the rendered image to correct the
51    "pincushion" distortion introduced by the optics in a VR device. The
52    barrel distorted image has lower resolution along the edges compared to
53    the center.  Since the original image is rendered at high resolution,
54    which is uniform across the complete image, a lot of pixels towards the
55    edges do not make it to the final post-processed image.
56
57    This extension also provides a mechanism to render VR scenes at a
58    non-uniform resolution, in particular a resolution that falls linearly
59    from the center towards the edges.  This is achieved by scaling the "w"
60    coordinate of the vertices in the clip space before perspective divide.
61    The clip space "w" coordinate of the vertices may be offset as of a
62    function of "x" and "y" coordinates as follows:
63
64            w' = w + Ax + By
65
66    In the intended use case for viewport position scaling, an application
67    should use a set of 4 viewports, one for each of the 4 quadrants of a
68    Cartesian coordinate system.  Each viewport is set to the dimension of the
69    image, but is scissored to the quadrant it represents.  The application
70    should specify A and B coefficients of the w-scaling equation above,
71    that have the same value, but different signs, for each of the viewports.
72    The signs of A and B should match the signs of X and Y for the quadrant
73    that they represent such that the value of "w'" will always be greater
74    than or equal to the original "w" value for the entire image. Since the
75    offset to "w", (Ax + By), is always positive and increases with the
76    absolute values of "x" and "y", the effective resolution will fall off
77    linearly from the center of the image to its edges.
78
79New Procedures and Functions
80
81    void ViewportPositionWScaleNV(uint index, float xcoeff, float ycoeff)
82
83New Tokens
84
85    Accepted by the <cap> parameter of Enable, Disable, IsEnabled:
86
87        VIEWPORT_POSITION_W_SCALE_NV            0x937C
88
89    Accepted by the <pname> parameter of GetBooleani_v, GetDoublei_v,
90    GetIntegeri_v, GetFloati_v, and GetInteger64i_v:
91
92        VIEWPORT_POSITION_W_SCALE_X_COEFF_NV    0x937D
93        VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV    0x937E
94
95Additions to Chapter 13 of the OpenGL 4.5 (Compatibility Profile)
96Specification (Fixed-Function Vertex Post-Processing)
97
98    Modify Section 13.2 (Transform Feedback), p. 453 [section 12.1 in OpenGL ES]
99
100    Modify the first paragraph:
101
102    ...The vertices are fed back after vertex color clamping, but before
103    viewport mask expansion, w coordinate warping, flat-shading, and clipping...
104
105    Add a new Section 13.X (Viewport W Coordinate Scaling)
106
107    If VIEWPORT_POSITION_W_SCALE_NV is enabled, the w coordinates for each
108    primitive sent to a given viewport will be scaled as a function of
109    its x and y coordinates using the following equation:
110
111        w' = xcoeff * x + ycoeff * y + w;
112
113    The coefficients for "x" and "y" used in the above equation depend on the
114    viewport index, and are controlled by the command
115
116        void ViewportPositionWScaleNV(uint index, float xcoeff, float ycoeff);
117
118    The viewport specified by <index> has its coefficients for "x" and "y"
119    set to the <xcoeff> and <ycoeff> values.  Specifying these coefficients
120    enables rendering images at a non-uniform resolution, in particular a
121    resolution that falls off linearly from the center towards the edges,
122    which is useful for VR applications. VR applications often involve a
123    post-processing step to apply a "barrel" distortion to the rendered image
124    to correct the "pincushion" distortion introduced by the optics in a VR
125    device. The barrel distorted image, has lower resolution along the edges
126    compared to the center.  Since the original image is rendered at high
127    resolution, which is uniform across the complete image, a lot of pixels
128    towards the edges do not make it to the final post-processed image.
129    VR applications may use the w-scaling to minimize the processing of unused
130    fragments. To achieve the intended effect, applications should use a set of
131    4 viewports one for each of the 4 quadrants of a Cartesian coordinate
132    system.  Each viewport is set to the dimension of the image, but is
133    scissored to the quadrant it represents.  The application should specify
134    the x and y coefficients of the w-scaling equation above, that have the
135    same value, but different signs, for each of the viewports.  The signs of
136    <xcoeff> and <ycoeff> should match the signs of X and Y for the quadrant
137    that they represent such that the value of "w'" will always be greater
138    than or equal to the original "w" value for the entire image. Since the
139    offset to "w", (Ax + By), is always positive and increases with the
140    absolute values of "x" and "y", the effective resolution will fall off
141    linearly from the center of the image to its edges.
142
143    Errors:
144
145    - The error INVALID_VALUE is generated if <index> is greater than or equal
146      to the value of MAX_VIEWPORTS.
147
148New Implementation Dependent State
149
150    None.
151
152New State
153
154                                                                 Initial
155    Get Value                             Get Command    Type    Value     Description                  Sec.    Attribute
156    ------------------------------------  -----------    ----    -------   -----------                  ----    ---------
157    VIEWPORT_POSITION_W_SCALE_NV          IsEnabled      B       FALSE     Enable W coordinate Scaling  13.X    enable
158    VIEWPORT_POSITION_W_SCALE_X_COEFF_NV  GetFloati_v    R       0         x coefficient for the w      13.X    viewport
159                                                                           coordinate scaling equation
160    VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV  GetFloati_v    R       0         y coefficient for the w      13.X    viewport
161                                                                           coordinate scaling equation
162
163Additions to the AGL/GLX/WGL/EGL Specifications
164
165    None.
166
167GLX Protocol
168
169    None.
170
171Errors
172
173    None.
174
175Interactions with OpenGL ES 3.1
176
177    If implemented in OpenGL ES, remove all references to GetDoublei_v.
178    If NV_viewport_array is supported, replace all references to MAX_VIEWPORTS
179    and GetFloati_v with MAX_VIEWPORTS_NV and GetFloati_vNV respectively.
180    If OES_viewport_array is supported, replace all references to MAX_VIEWPORTS
181    and GetFloati_v with MAX_VIEWPORTS_OES and GetFloati_vOES respectively.
182
183Issues
184
185    (1) Does this extension provide any functionality to convert the w-scaled
186        image to the barrel distorted image used in VR?
187
188      RESOLVED: No. VR applications would still require a post-processing step to
189      generate a barrel distorted image to compensate for the lens distortion.
190      The following vertex and fragment shader pair un-warps a w-scaled image.
191      It can be incorporated into an existing post-processing shader to directly
192      convert a w-scaled image to the barrel distorted image.
193
194        // Vertex Shader
195        // Draw a triangle that covers the whole screen
196        const vec4 positions[3] = vec4[3](vec4(-1, -1, 0, 1),
197                                          vec4( 3, -1, 0, 1),
198                                          vec4(-1,  3, 0, 1));
199        out vec2 uv;
200        void main()
201        {
202          vec4 pos = positions[ gl_VertexID ];
203          gl_Position = pos;
204          uv = pos.xy;
205        }
206
207        // Fragment Shader
208        uniform sampler2D tex;
209        uniform float xcoeff;
210        uniform float ycoeff;
211        out vec4 Color;
212        in vec2 uv;
213
214        void main()
215        {
216          // Handle uv as if upper right quadrant
217          vec2 uvabs = abs(uv);
218
219          // unscale: transform w-scaled image into an unscaled image
220          //   scale: transform unscaled image int a w-scaled image
221          float unscale = 1.0 / (1 + xcoeff * uvabs.x + xcoeff * uvabs.y);
222          //float scale = 1.0 / (1 - xcoeff * uvabs.x - xcoeff * uvabs.y);
223
224          vec2 P = vec2(unscale * uvabs.x, unscale * uvabs.y);
225
226          // Go back to the right quadrant
227          P *= sign(uv);
228
229          Color = texture(tex, P * 0.5 + 0.5);
230        }
231
232    (2) In the standard use case a application sets up 4 viewports, one for
233        each quadrant. Does each primitive have to be broadcast to all the 4
234        viewports?
235
236      RESOLVED: No. Applications may see a better performance if the viewport
237      mask for each primitive is limited to the viewports corresponding
238      to the quadrants it falls in.
239
240
241Revision History
242
243    Revision 1
244      - Internal revisions.
245    Revision 2
246      - Add _NV suffixes to _COEFF tokens
247    Revision 3
248      - Add ES interactions.
249      - Add requirement for NV_viewport_array2
250    Revision 4, 2017/11/25 (pbrown)
251      - Add to the OpenGL ES Extension Registry
252