-
Notifications
You must be signed in to change notification settings - Fork 98
/
GLSL_EXT_fragment_shader_barycentric.txt
307 lines (216 loc) · 11.5 KB
/
GLSL_EXT_fragment_shader_barycentric.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
Name
EXT_fragment_shader_barycentric
Name Strings
GL_EXT_fragment_shader_barycentric
Contact
Pat Brown, NVIDIA (pbrown 'at' nvidia.com)
Stu Smith, AMD
Contributors
Ashwin Lele, NVIDIA
Jeff Bolz, NVIDIA
Graeme Leese, Broadcom
Status
Complete
Version
Last Modified: June 1, 2022
Revision: 2
Dependencies
This extension can be applied to OpenGL GLSL versions 4.50
(#version 450) and higher.
This extension can be applied to OpenGL ES ESSL versions 3.20
(#version 320) and higher.
This extension is written against the OpenGL Shading Language
Specification, version 4.60, dated July 23, 2017.
Overview
This extension provides two new OpenGL Shading Language (GLSL) fragment
shader built-in inputs (gl_BaryCoordEXT and gl_BaryCoordNoPerspEXT) that are
three-component vectors specifying the relative weights for each vertex in
the original primitive. Fragments located in the corners of a triangle
primitive will have weights of (1,0,0), (0,1,0), and (0,0,1), while a
fragment in the exact middle of a triangle will have weights of (1/3, 1/3,
1/3). Fragments located at the endpoints of a line primitive will have
weights of (1,0,0) and (0,1,0). The weights in the vector gl_BaryCoordEXT
are perspective-corrected and reflect the location of the fragment as
projected onto the original primitive. The weights in the vector
gl_BaryCoordNoPerspEXT are not perspective-corrected and reflect the
location of the fragment relative to the on-screen projection of the
original primitive. For both vectors, the values of the three components
should add to approximately 1.0.
This extension also allows fragment shaders to read the raw per-vertex
values of shader outputs from the last shader stage executed before
rasterization. This mechanism uses the same syntax used to read
per-vertex inputs in for tessellation and geometry shaders. The qualifier
"pervertexEXT" can be applied to fragment shader input blocks and
variables to specify that those inputs do not read interpolated
per-fragment values, but instead read raw per-vertex values from the
vertices of the original primitive. Like tessellation and geometry shader
inputs, such variables or blocks must be declared as arrays and indexed
with a vertex number (0, 1, or 2). For example, if a shader declares the
following input block:
pervertexEXT in Inputs {
float f;
float g;
} inputs[];
the expression "inputs[0].f" reads the value of <f> for the first vertex
of the original primitive, while "inputs[2].g" reads the value of <g> for
the third vertex.
While barycentric weights can be used to interpolate values by reading the
outputs of previous shaders (using "pervertexEXT" attributes), it can
also be used to interpolate values based in input values fetched directly
from memory, with no shader outputs involved. For example, in code like
the following:
pervertexEXT in int vertexIDs[];
buffer VertexData {
struct VertexAttributes {
vec3 normal;
} attrs[];
};
shaders can fetch the values of <normal> for the three vertices of a
triangle primitive using:
vec3 normal0 = attrs[vertexIDs[0]];
vec3 normal1 = attrs[vertexIDs[1]];
vec3 normal2 = attrs[vertexIDs[2]];
without reading or emitting any normal vectors in a vertex shader.
Mapping to SPIR-V
-----------------
For informational purposes (non-normative), the following is an
expected way for an implementation to map GLSL constructs to SPIR-V
constructs:
pervertexEXT auxiliary storage qualifier -> PerVertexKHR Decoration
gl_BaryCoordEXT -> BaryCoordKHR decorated OpVariable
gl_BaryCoordNoPerspEXT -> BaryCoordNoPerspKHR decorated OpVariable
Input variables decorated with "PerVertexKHR" are accessed with an extra
array dimension identifying a vertex number.
Modifications to the OpenGL Shading Language Specification, Version 4.60
Including the following line in a shader can be used to control the
language features described in this extension:
#extension GL_EXT_fragment_shader_barycentric : <behavior>
where <behavior> is as specified in section 3.3.
New preprocessor #defines are added to the OpenGL Shading Language:
#define GL_EXT_fragment_shader_barycentric 1
Modify Section 3.6, Keywords (p. 15)
(add to list of keywords, on the line with "centroid", "flat", "smooth",
and "noperspective")
pervertexEXT
Modify Section 4.3, Storage Qualifiers (p. 41)
(add to table of auxiliary storage qualifiers, p. 42)
Auxiliary Storage
Qualifier Meaning
------------------ ------------------------------------------
pervertexEXT no interpolation; fragment shader reads
previous-stage outputs with a vertex number
Modify Section 4.3.4, Input Variables (p. 45)
(modify third paragraph, p. 46, to document that fragment shader inputs
declared with "pervertexEXT" are treated similarly to tessellation and
geometry shader inputs and document that "pervertexEXT" has no effect in
non-fragment shaders)
Tessellation control input variables, tessellation evaluation input
variables, geometry shader input variables, and fragment shader input
variables qualified with "pervertexEXT" get the per-vertex values written
out by output variables of the same names in the previous active shader
stage. Since all of these inputs have separate values for each vertex
in the input primitive, each such input variable (or input block, see
interface blocks below) needs to be declared as an array. For tessellation
or geometry stage inputs, centroid, and interpolation qualifiers
are allowed, but have no effect. For example,
in float foo[]; // geometry shader input for vertex "out float foo"
(modify fourth paragraph, p. 46, to document how the array size for
"arrayed" inputs is obtained for tessellation shaders and per-vertex
fragment shader inputs)
... For geometry shaders, ... section 4.4.1 "Input Layout Qualifiers".
For tessellation control and evaluation shaders, the array size will be
set by (or if provided, must be consistent with) the maximum patch size
gl_MaxPatchVertices. For fragment shader inputs qualified with
"pervertexEXT", the array size will be set to (or if provided, must be
no more than) three.
(modify fifth paragraph, p. 46, to treat "pervertexEXT" inputs as
"arrayed" interfaces)
Some inputs and outputs are arrayed ... Geometry shader inputs,
tessellation control shader inputs and outputs, tessellation evaluation
inputs, and fragment shader inputs qualified with "pervertexEXT" all have
an additional level of arrayness relative to other shader inputs and
outputs. Component limits...
(modify second paragraph, p. 47, adding alternate language about the
handling of fragment shader inputs using "pervertexEXT")
Fragment shader inputs not declared with "pervertexEXT" get
per-fragment values, typically interpolated from a previous stage's
outputs. ... as well as the interpolation qualifiers flat, noperspective,
and smooth. Fragment shader inputs declared with "pervertexEXT" are
not interpolated. Such inputs are arrayed and may be used to directly
access the previous stage's outputs for one of the vertices of the
primitives producing the fragment, using a vertex number of 0, 1, or 2 as
an index. ...
(modify third paragraph, p. 47, allowing integer and double-precision
fragment shader inputs if qualified with "pervertexEXT")
Fragment shader inputs that are, or contain, signed or unsigned integers,
integer vectors, or any double-precision floating-point type must be
qualified with the qualifier "flat" or "pervertexEXT".
(modify the fourth paragraph, p. 48, adding an example)
Fragment inputs are declared as in the following examples:
...
pervertexEXT in vec4 perVertexAttr[];
Modify Section 4.3.9, Interface Blocks, p. 51
(update the fake grammar, p. 52, to clarify that you can use the
interpolation qualifier "pervertexEXT" on input blocks)
interface-qualifier:
...
pervertexEXT in
...
Modify Section 4.5, Interpolation Qualifiers, p. 83
(add to the table in first paragraph of the section)
Qualifier Meaning
---------------- --------------------------------------------
pervertexEXT no interpolation, values accessed per vertex
(add before the next-to-last paragraph, p. 83)
A variable or interface block qualified with "pervertexEXT" must be
declared as an array, where each array element corresponds to one of the
vertices of the primitive that produced the fragment. This array will
have a size of three if declared as unsized, and reads of per-vertex
values for missing vertices, such as the third vertex of a line primitive,
will return values from the valid vertex with the highest
index. The order of the vertices of the input primitive is
defined in the OpenGL or Vulkan API Specifications. No interpolated
per-fragment values are available for inputs qualified with
"pervertexEXT". For variables qualified with "pervertexEXT", it is a
compile-time error to also qualify the variable with either "centroid" or
"sample".
Modify Section 4.5.1, Redeclaring Built-In Interpolation Variables in the
Compatibility Profile, p. 84
(modify the first paragraph of the section to prohibit the use of
"pervertexEXT" on built-ins)
The following predeclared variables can be redeclared with an
interpolation qualifier other than "pervertexEXT" when using the
compatibility profile:
...
Modify Section 7.1, Built-In Language Variables, p. 122
(modify the list of fragment built-ins, p. 124)
In the fragment, language, built-in variables are intrinsically declared
as:
...
in vec3 gl_BaryCoordEXT;
in vec3 gl_BaryCoordNoPerspEXT;
(add description of the new built-ins to the list of descriptions, before
gl_PerVertex, p. 131)
The built-in fragment shader input variables gl_BaryCoordEXT and
gl_BaryCoordNoPerspEXT are three-component vectors providing barycentric
coordinates for the fragment. The values for these built-ins are derived
as described in the OpenGL or Vulkan API Specifications.
Issues
(1) What are the differences to NV_fragment_shader_barycentric?
Reads of missing per-vertex values return values from the
valid vertex with the highest index.
(2) What are the interactions with MSAA?
As with NV_fragment_shader_barycentric, this extension does not provide
extra "Centroid" and "Sample" variants of the gl_BaryCoord* built-in
inputs. Equivalent values can be obtained either by decorating the
gl_BaryCoordEXT or gl_BaryCoordNoPerspEXT inputs with the centroid
or sample interpolation qualifiers, or by using built-in interpolation
functions like:
vec3 bcCentroid = interpolateAtCentroid(gl_BaryCoordEXT);
vec3 bcNoPerspSample = interpolateAtSample(gl_BaryCoordNoPerspEXT, sample);
vec3 bcOffset = interpolateAtOffset(gl_BaryCoordEXT, offset);
Revision History
Revision 2, 2022/06/01 (ssmith)
- Add MSAA interaction note.
Revision 1
- Internal revisions.