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
|
//
// TODO:
// - what to do with ftransform? can it stay in the current form?
// - implement texture1DLod, texture2DLod, texture3DLod, textureCubeLod,
// - implement shadow1DLod, shadow2DLod,
//
//
// From Shader Spec, ver. 1.051
//
// Some OpenGL operations still continue to occur in fixed functionality in between the vertex
// processor and the fragment processor. Other OpenGL operations continue to occur in fixed
// functionality after the fragment processor. Shaders communicate with the fixed functionality
// of OpenGL through the use of built-in variables.
//
// The variable gl_Position is available only in the vertex language and is intended for writing
// the homogeneous vertex position. All executions of a well-formed vertex shader must write
// a value into this variable. It can be written at any time during shader execution. It may also
// be read back by the shader after being written. This value will be used by primitive assembly,
// clipping, culling, and other fixed functionality operations that operate on primitives after
// vertex processing has occurred. Compilers may generate a diagnostic message if they detect
// gl_Position is not written, or read before being written, but not all such cases are detectable.
// Results are undefined if a vertex shader is executed and does not write gl_Position.
//
// The variable gl_PointSize is available only in the vertex language and is intended for a vertex
// shader to write the size of the point to be rasterized. It is measured in pixels.
//
// The variable gl_ClipVertex is available only in the vertex language and provides a place for
// vertex shaders to write the coordinate to be used with the user clipping planes. The user must
// ensure the clip vertex and user clipping planes are defined in the same coordinate space. User
// clip planes work properly only under linear transform. It is undefined what happens under
// non-linear transform.
//
// These built-in vertex shader variables for communicating with fixed functionality are
// intrinsically declared with the following types:
//
vec4 gl_Position; // must be written to
float gl_PointSize; // may be written to
vec4 gl_ClipVertex; // may be written to
//
// If gl_PointSize or gl_ClipVertex are not written to, their values are undefined. Any of these
// variables can be read back by the shader after writing to them, to retrieve what was written.
// Reading them before writing them results in undefined behavior. If they are written more than
// once, it is the last value written that is consumed by the subsequent operations.
//
// These built-in variables have global scope.
//
//
// The following attribute names are built into the OpenGL vertex language and can be used from
// within a vertex shader to access the current values of attributes declared by OpenGL. All page
// numbers and notations are references to the OpenGL 1.4 specification.
//
//
// Vertex Attributes, p. 19.
//
attribute vec4 gl_Color;
attribute vec4 gl_SecondaryColor;
attribute vec3 gl_Normal;
attribute vec4 gl_Vertex;
attribute vec4 gl_MultiTexCoord0;
attribute vec4 gl_MultiTexCoord1;
attribute vec4 gl_MultiTexCoord2;
attribute vec4 gl_MultiTexCoord3;
attribute vec4 gl_MultiTexCoord4;
attribute vec4 gl_MultiTexCoord5;
attribute vec4 gl_MultiTexCoord6;
attribute vec4 gl_MultiTexCoord7;
attribute float gl_FogCoord;
//
// Unlike user-defined varying variables, the built-in varying variables don’t have a strict
// one-to-one correspondence between the vertex language and the fragment language. Two sets are
// provided, one for each language. Their relationship is described below.
//
// The following built-in varying variables are available to write to in a vertex shader.
// A particular one should be written to if any functionality in a corresponding fragment shader
// or fixed pipeline uses it or state derived from it. Otherwise, behavior is undefined.
//
varying vec4 gl_FrontColor;
varying vec4 gl_BackColor;
varying vec4 gl_FrontSecondaryColor;
varying vec4 gl_BackSecondaryColor;
varying vec4 gl_TexCoord[]; // at most will be gl_MaxTextureCoordsARB
varying float gl_FogFragCoord;
//
// For gl_FogFragCoord, the value written will be used as the “c” value on page 160 of the
// OpenGL 1.4 Specification by the fixed functionality pipeline. For example, if the z-coordinate
// of the fragment in eye space is desired as “c”, then that's what the vertex shader should write
// into gl_FogFragCoord.
//
// As with all arrays, indices used to subscript gl_TexCoord must either be integral constant
// expressions, or this array must be re-declared by the shader with a size. The size can be
// at most gl_MaxTextureCoordsARB. Using indexes close to 0 may aid the implementation
// in preserving varying resources.
//
//
// The OpenGL Shading Language defines an assortment of built-in convenience functions for scalar
// and vector operations. Many of these built-in functions can be used in more than one type
// of shader, but some are intended to provide a direct mapping to hardware and so are available
// only for a specific type of shader.
//
// The built-in functions basically fall into three categories:
//
// • They expose some necessary hardware functionality in a convenient way such as accessing
// a texture map. There is no way in the language for these functions to be emulated by a shader.
//
// • They represent a trivial operation (clamp, mix, etc.) that is very simple for the user
// to write, but they are very common and may have direct hardware support. It is a very hard
// problem for the compiler to map expressions to complex assembler instructions.
//
// • They represent an operation graphics hardware is likely to accelerate at some point. The
// trigonometry functions fall into this category.
//
// Many of the functions are similar to the same named ones in common C libraries, but they support
// vector input as well as the more traditional scalar input.
//
// Applications should be encouraged to use the built-in functions rather than do the equivalent
// computations in their own shader code since the built-in functions are assumed to be optimal
// (e.g., perhaps supported directly in hardware).
//
// User code can replace built-in functions with their own if they choose, by simply re-declaring
// and defining the same name and argument list.
//
//
// Geometric Functions
//
// These operate on vectors as vectors, not component-wise.
//
//
// For vertex shaders only. This function will ensure that the incoming vertex value will be
// transformed in a way that produces exactly the same result as would be produced by OpenGL’s
// fixed functionality transform. It is intended to be used to compute gl_Position, e.g.,
// gl_Position = ftransform()
// This function should be used, for example, when an application is rendering the same geometry in
// separate passes, and one pass uses the fixed functionality path to render and another pass uses
// programmable shaders.
//
vec4 ftransform () {
return gl_ModelViewProjectionMatrix * gl_Vertex;
}
//
// Texture Lookup Functions
//
// Texture lookup functions are available to both vertex and fragment shaders. However, level
// of detail is not computed by fixed functionality for vertex shaders, so there are some
// differences in operation between vertex and fragment texture lookups. The functions in the table
// below provide access to textures through samplers, as set up through the OpenGL API. Texture
// properties such as size, pixel format, number of dimensions, filtering method, number of mip-map
// levels, depth comparison, and so on are also defined by OpenGL API calls. Such properties are
// taken into account as the texture is accessed via the built-in functions defined below.
//
// If a non-shadow texture call is made to a sampler whose texture has depth comparisons enabled,
// then results are undefined. If a shadow texture call is made to a sampler whose texture does not
// have depth comparisions enabled, the results are also undefined.
//
// In all functions below, the bias parameter is optional for fragment shaders. The bias parameter
// is not accepted in a vertex shader. For a fragment shader, if bias is present, it is added to
// the calculated level of detail prior to performing the texture access operation. If the bias
// parameter is not provided, then the implementation automatically selects level of detail:
// For a texture that is not mip-mapped, the texture is used directly. If it is mip-mapped and
// running in a fragment shader, the LOD computed by the implementation is used to do the texture
// lookup. If it is mip-mapped and running on the vertex shader, then the base texture is used.
//
// The built-ins suffixed with “Lod” are allowed only in a vertex shader. For the “Lod” functions,
// lod is directly used as the level of detail.
//
//
// Use the texture coordinate coord to do a texture lookup in the 1D texture currently bound
// to sampler. For the projective (“Proj”) versions, the texture coordinate coord.s is divided by
// the last component of coord.
//
// XXX
vec4 texture1DLod (sampler1D sampler, float coord, float lod) {
return vec4 (0.0);
}
vec4 texture1DProjLod (sampler1D sampler, vec2 coord, float lod) {
return texture1DLod (sampler, coord.s / coord.t, lod);
}
vec4 texture1DProjLod (sampler1D sampler, vec4 coord, float lod) {
return texture1DLod (sampler, coord.s / coord.q, lod);
}
//
// Use the texture coordinate coord to do a texture lookup in the 2D texture currently bound
// to sampler. For the projective (“Proj”) versions, the texture coordinate (coord.s, coord.t) is
// divided by the last component of coord. The third component of coord is ignored for the vec4
// coord variant.
//
// XXX
vec4 texture2DLod (sampler2D sampler, vec2 coord, float lod) {
return vec4 (0.0);
}
vec4 texture2DProjLod (sampler2D sampler, vec3 coord, float lod) {
return texture2DLod (sampler, vec2 (coord.s / coord.p, coord.t / coord.p), lod);
}
vec4 texture2DProjLod (sampler2D sampler, vec4 coord, float lod) {
return texture2DLod (sampler, vec2 (coord.s / coord.q, coord.t / coord.q), lod);
}
//
// Use the texture coordinate coord to do a texture lookup in the 3D texture currently bound
// to sampler. For the projective (“Proj”) versions, the texture coordinate is divided by coord.q.
//
// XXX
vec4 texture3DLod (sampler3D sampler, vec3 coord, float lod) {
return vec4 (0.0);
}
vec4 texture3DProjLod (sampler3D sampler, vec4 coord, float lod) {
return texture3DLod (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.s / coord.q),
lod);
}
//
// Use the texture coordinate coord to do a texture lookup in the cube map texture currently bound
// to sampler. The direction of coord is used to select which face to do a 2-dimensional texture
// lookup in, as described in section 3.8.6 in version 1.4 of the OpenGL specification.
//
// XXX
vec4 textureCubeLod (samplerCube sampler, vec3 coord, float lod) {
return vec4 (0.0);
}
//
// Use texture coordinate coord to do a depth comparison lookup on the depth texture bound
// to sampler, as described in section 3.8.14 of version 1.4 of the OpenGL specification. The 3rd
// component of coord (coord.p) is used as the R value. The texture bound to sampler must be a
// depth texture, or results are undefined. For the projective (“Proj”) version of each built-in,
// the texture coordinate is divide by coord.q, giving a depth value R of coord.p/coord.q. The
// second component of coord is ignored for the “1D” variants.
//
// XXX
vec4 shadow1DLod (sampler1DShadow sampler, vec3 coord, float lod) {
return vec4 (0.0);
}
// XXX
vec4 shadow2DLod (sampler2DShadow sampler, vec3 coord, float lod) {
return vec4 (0.0);
}
vec4 shadow1DProjLod(sampler1DShadow sampler, vec4 coord, float lod) {
return shadow1DLod (sampler, vec3 (coord.s / coord.q, 0.0, coord.p / coord.q), lod);
}
vec4 shadow2DProjLod(sampler2DShadow sampler, vec4 coord, float lod) {
return shadow2DLod (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q),
lod);
}
|