mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 06:48:06 +02:00
conform to shader spec 1.10.59
This commit is contained in:
parent
cfb62331bc
commit
f459b9f9c0
3 changed files with 2037 additions and 1916 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -1,354 +1,366 @@
|
|||
|
||||
//
|
||||
// TODO:
|
||||
// - implement texture1D, texture2D, texture3D, textureCube,
|
||||
// - implement shadow1D, shadow2D,
|
||||
// - implement dFdx, dFdy,
|
||||
//
|
||||
|
||||
//
|
||||
// From Shader Spec, ver. 1.051
|
||||
//
|
||||
// The output of the fragment shader goes on to be processed by the fixed function operations at
|
||||
// the back end of the OpenGL pipeline. Fragment shaders interface with the back end of the OpenGL
|
||||
// pipeline using the built-in variables gl_FragColor and gl_FragDepth, or by executing the discard
|
||||
// keyword.
|
||||
//
|
||||
// These variables may be written more than once within a fragment shader. If so, the last value
|
||||
// assigned is the one used in the subsequent fixed function pipeline. The values written to these
|
||||
// variables may be read back after writing them. Reading from these variables before writing them
|
||||
// results in an undefined value. The fixed functionality computed depth for a fragment may be
|
||||
// obtained by reading gl_FragCoord.z, described below.
|
||||
//
|
||||
// Writing to gl_FragColor specifies the fragment color that will be used by the subsequent fixed
|
||||
// functionality pipeline. If subsequent fixed functionality consumes fragment color and an
|
||||
// execution of a fragment shader does not write a value to gl_FragColor then the fragment color
|
||||
// consumed is undefined.
|
||||
//
|
||||
// If the frame buffer is configured as a color index buffer then behavior is undefined when using
|
||||
// a fragment shader.
|
||||
//
|
||||
// Writing to gl_FragDepth will establish the depth value for the fragment being processed. If
|
||||
// depth buffering is enabled, and a shader does not write gl_FragDepth, then the fixed function
|
||||
// value for depth will be used as the fragment’s depth value. If a shader statically assigns
|
||||
// a value to gl_FragDepth, and there is an execution path through the shader that does not set
|
||||
// gl_FragDepth, then the value of the fragment’s depth may be undefined for some executions of
|
||||
// the shader. That is, if a shader statically writes gl_FragDepth, then it is responsible for
|
||||
// always writing it. There is also no guarantee that a shader can compute the same depth value
|
||||
// as the fixed function value; an implementation will provide invariant results within shaders
|
||||
// computing depth with the same source-level expression, but invariance is not provided between
|
||||
// shaders and fixed functionality.
|
||||
//
|
||||
// Writes to gl_FragColor and gl_FragDepth need not be clamped within a shader. The fixed
|
||||
// functionality pipeline following the fragment shader will clamp these values.
|
||||
//
|
||||
// If a shader executes the discard keyword, the fragment is discarded, and the values of
|
||||
// gl_FragDepth and gl_FragColor become irrelevant.
|
||||
//
|
||||
// The variable gl_FragCoord is available as a read-only variable from within fragment shaders
|
||||
// and it holds the window relative coordinates x, y, z, and 1/w values for the fragment. This
|
||||
// value is the result of the fixed functionality that interpolates primitives after vertex
|
||||
// processing to generate fragments. The z component is the depth value that would be used for
|
||||
// the fragment’s depth if a shader contained no writes to gl_FragDepth. This is useful for
|
||||
// invariance if a shader conditionally computes gl_FragDepth but otherwise wants the fixed
|
||||
// functionality fragment depth.
|
||||
//
|
||||
// The fragment shader has access to the read-only built-in variable gl_FrontFacing whose value
|
||||
// is true if the fragment belongs to a front-facing primitive. One use of this is to emulate
|
||||
// two-sided lighting by selecting one of two colors calculated by the vertex shader.
|
||||
//
|
||||
// The built-in variables that are accessible from a fragment shader are intrinsically given types
|
||||
// as follows:
|
||||
//
|
||||
|
||||
vec4 gl_FragCoord;
|
||||
bool gl_FrontFacing;
|
||||
vec4 gl_FragColor;
|
||||
float gl_FragDepth;
|
||||
|
||||
//
|
||||
// However, they do not behave like variables with no qualifier; their behavior is as described
|
||||
// above. These built-in variables have global scope.
|
||||
//
|
||||
|
||||
//
|
||||
// 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 varying variables are available to read from in a fragment shader. The gl_Color
|
||||
// and gl_SecondaryColor names are the same names as attributes passed to the vertex shader.
|
||||
// However, there is no name conflict, because attributes are visible only in vertex shaders
|
||||
// and the following are only visible in a fragment shader.
|
||||
//
|
||||
|
||||
varying vec4 gl_Color;
|
||||
varying vec4 gl_SecondaryColor;
|
||||
varying vec4 gl_TexCoord[]; // at most will be gl_MaxTextureCoordsARB
|
||||
varying float gl_FogFragCoord;
|
||||
|
||||
//
|
||||
// The values in gl_Color and gl_SecondaryColor will be derived automatically by the system from
|
||||
// gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor, and gl_BackSecondaryColor based on which
|
||||
// face is visible. If fixed functionality is used for vertex processing, then gl_FogFragCoord will
|
||||
// either be the z-coordinate of the fragment in eye space, or the interpolation of the fog
|
||||
// coordinate, as described in section 3.10 of the OpenGL 1.4 Specification. The gl_TexCoord[]
|
||||
// values are the interpolated gl_TexCoord[] values from a vertex shader or the texture coordinates
|
||||
// of any fixed pipeline based vertex functionality.
|
||||
//
|
||||
// Indices to the fragment shader gl_TexCoord array are as described above in the vertex shader
|
||||
// text.
|
||||
//
|
||||
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
//
|
||||
// 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 texture1D (sampler1D sampler, float coord, float bias) {
|
||||
return vec4 (0.0);
|
||||
}
|
||||
vec4 texture1DProj (sampler1D sampler, vec2 coord, float bias) {
|
||||
return texture1D (sampler, coord.s / coord.t, bias);
|
||||
}
|
||||
vec4 texture1DProj (sampler1D sampler, vec4 coord, float bias) {
|
||||
return texture1D (sampler, coord.s / coord.q, bias);
|
||||
}
|
||||
|
||||
//
|
||||
// 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 texture2D (sampler2D sampler, vec2 coord, float bias) {
|
||||
return vec4 (0.0);
|
||||
}
|
||||
vec4 texture2DProj (sampler2D sampler, vec3 coord, float bias) {
|
||||
return texture2D (sampler, vec2 (coord.s / coord.p, coord.t / coord.p), bias);
|
||||
}
|
||||
vec4 texture2DProj (sampler2D sampler, vec4 coord, float bias) {
|
||||
return texture2D (sampler, vec2 (coord.s / coord.q, coord.s / coord.q), bias);
|
||||
}
|
||||
|
||||
//
|
||||
// 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 texture3D (sampler3D sampler, vec3 coord, float bias) {
|
||||
return vec4 (0.0);
|
||||
}
|
||||
vec4 texture3DProj (sampler3D sampler, vec4 coord, float bias) {
|
||||
return texture3DProj (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q),
|
||||
bias);
|
||||
}
|
||||
|
||||
//
|
||||
// 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 textureCube (samplerCube sampler, vec3 coord, float bias) {
|
||||
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 shadow1D (sampler1DShadow sampler, vec3 coord, float bias) {
|
||||
return vec4 (0.0);
|
||||
}
|
||||
// XXX
|
||||
vec4 shadow2D (sampler2DShadow sampler, vec3 coord, float bias) {
|
||||
return vec4 (0.0);
|
||||
}
|
||||
vec4 shadow1DProj (sampler1DShadow sampler, vec4 coord, float bias) {
|
||||
return shadow1D (sampler, vec3 (coord.s / coord.q, 0.0, coord.p / coord.q), bias);
|
||||
}
|
||||
vec4 shadow2DProj (sampler2DShadow sampler, vec4 coord, float bias) {
|
||||
return shadow2D (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q), bias);
|
||||
}
|
||||
|
||||
//
|
||||
// Fragment processing functions are only available in shaders intended for use on the fragment
|
||||
// processor. Derivatives may be computationally expensive and/or numerically unstable. Therefore,
|
||||
// an OpenGL implementation may approximate the true derivatives by using a fast but not entirely
|
||||
// accurate derivative computation.
|
||||
//
|
||||
// The expected behavior of a derivative is specified using forward/backward differencing.
|
||||
//
|
||||
// Forward differencing:
|
||||
//
|
||||
// F(x+dx) - F(x) ~ dFdx(x) * dx 1a
|
||||
// dFdx(x) ~ (F(x+dx) - F(x)) / dx 1b
|
||||
//
|
||||
// Backward differencing:
|
||||
//
|
||||
// F(x-dx) - F(x) ~ -dFdx(x) * dx 2a
|
||||
// dFdx(x) ~ (F(x) - F(x-dx)) / dx 2b
|
||||
//
|
||||
// With single-sample rasterization, dx <= 1.0 in equations 1b and 2b. For multi-sample
|
||||
// rasterization, dx < 2.0 in equations 1b and 2b.
|
||||
//
|
||||
// dFdy is approximated similarly, with y replacing x.
|
||||
//
|
||||
// A GL implementation may use the above or other methods to perform the calculation, subject
|
||||
// to the following conditions:
|
||||
//
|
||||
// 1) The method may use piecewise linear approximations. Such linear approximations imply that
|
||||
// higher order derivatives, dFdx(dFdx(x)) and above, are undefined.
|
||||
//
|
||||
// 2) The method may assume that the function evaluated is continuous. Therefore derivatives within
|
||||
// the body of a non-uniform conditional are undefined.
|
||||
//
|
||||
// 3) The method may differ per fragment, subject to the constraint that the method may vary by
|
||||
// window coordinates, not screen coordinates. The invariance requirement described in section
|
||||
// 3.1 of the OpenGL 1.4 specification is relaxed for derivative calculations, because
|
||||
// the method may be a function of fragment location.
|
||||
//
|
||||
// Other properties that are desirable, but not required, are:
|
||||
//
|
||||
// 4) Functions should be evaluated within the interior of a primitive (interpolated, not
|
||||
// extrapolated).
|
||||
//
|
||||
// 5) Functions for dFdx should be evaluated while holding y constant. Functions for dFdy should
|
||||
// be evaluated while holding x constant. However, mixed higher order derivatives, like
|
||||
// dFdx(dFdy(y)) and dFdy(dFdx(x)) are undefined.
|
||||
//
|
||||
// In some implementations, varying degrees of derivative accuracy may be obtained by providing
|
||||
// GL hints (section 5.6 of the OpenGL 1.4 specification), allowing a user to make an image
|
||||
// quality versus speed tradeoff.
|
||||
//
|
||||
|
||||
//
|
||||
// Returns the derivative in x using local differencing for the input argument p.
|
||||
//
|
||||
// XXX
|
||||
float dFdx (float p) {
|
||||
return 0.0;
|
||||
}
|
||||
// XXX
|
||||
vec2 dFdx (vec2 p) {
|
||||
return vec2 (0.0);
|
||||
}
|
||||
// XXX
|
||||
vec3 dFdx (vec3 p) {
|
||||
return vec3 (0.0);
|
||||
}
|
||||
// XXX
|
||||
vec4 dFdx (vec4 p) {
|
||||
return vec4 (0.0);
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the derivative in y using local differencing for the input argument p.
|
||||
//
|
||||
// These two functions are commonly used to estimate the filter width used to anti-alias procedural
|
||||
// textures.We are assuming that the expression is being evaluated in parallel on a SIMD array so
|
||||
// that at any given point in time the value of the function is known at the grid points
|
||||
// represented by the SIMD array. Local differencing between SIMD array elements can therefore
|
||||
// be used to derive dFdx, dFdy, etc.
|
||||
//
|
||||
// XXX
|
||||
float dFdy (float p) {
|
||||
return 0.0;
|
||||
}
|
||||
// XXX
|
||||
vec2 dFdy (vec2 p) {
|
||||
return vec2 (0.0);
|
||||
}
|
||||
// XXX
|
||||
vec3 dFdy (vec3 p) {
|
||||
return vec3 (0.0);
|
||||
}
|
||||
// XXX
|
||||
vec4 dFdy (vec4 p) {
|
||||
return vec4 (0.0);
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the sum of the absolute derivative in x and y using local differencing for the input
|
||||
// argument p, i.e.:
|
||||
//
|
||||
// return = abs (dFdx (p)) + abs (dFdy (p));
|
||||
//
|
||||
|
||||
float fwidth (float p) {
|
||||
return abs (dFdx (p)) + abs (dFdy (p));
|
||||
}
|
||||
vec2 fwidth (vec2 p) {
|
||||
return abs (dFdx (p)) + abs (dFdy (p));
|
||||
}
|
||||
vec3 fwidth (vec3 p) {
|
||||
return abs (dFdx (p)) + abs (dFdy (p));
|
||||
}
|
||||
vec4 fwidth (vec4 p) {
|
||||
return abs (dFdx (p)) + abs (dFdy (p));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// TODO:
|
||||
// - implement texture1D, texture2D, texture3D, textureCube,
|
||||
// - implement shadow1D, shadow2D,
|
||||
// - implement dFdx, dFdy,
|
||||
//
|
||||
|
||||
//
|
||||
// From Shader Spec, ver. 1.10, rev. 59
|
||||
//
|
||||
// The output of the fragment shader is processed by the fixed function operations at the back end
|
||||
// of the OpenGL pipeline. Fragment shaders output values to the OpenGL pipeline using the built-in
|
||||
// variables gl_FragColor, gl_FragData and gl_FragDepth, unless the discard keyword is executed.
|
||||
//
|
||||
// These variables may be written more than once within a fragment shader. If so, the last value
|
||||
// assigned is the one used in the subsequent fixed function pipeline. The values written to these
|
||||
// variables may be read back after writing them. Reading from these variables before writing them
|
||||
// results in an undefined value. The fixed functionality computed depth for a fragment may be
|
||||
// obtained by reading gl_FragCoord.z, described below.
|
||||
//
|
||||
// Writing to gl_FragColor specifies the fragment color that will be used by the subsequent fixed
|
||||
// functionality pipeline. If subsequent fixed functionality consumes fragment color and an
|
||||
// execution of a fragment shader does not write a value to gl_FragColor then the fragment color
|
||||
// consumed is undefined.
|
||||
//
|
||||
// If the frame buffer is configured as a color index buffer then behavior is undefined when using
|
||||
// a fragment shader.
|
||||
//
|
||||
// Writing to gl_FragDepth will establish the depth value for the fragment being processed. If
|
||||
// depth buffering is enabled, and a shader does not write gl_FragDepth, then the fixed function
|
||||
// value for depth will be used as the fragment’s depth value. If a shader statically assigns
|
||||
// a value to gl_FragDepth, and there is an execution path through the shader that does not set
|
||||
// gl_FragDepth, then the value of the fragment's depth may be undefined for executions of the
|
||||
// shader that take that path. That is, if a shader statically contains a write gl_FragDepth, then
|
||||
// it is responsible for always writing it.
|
||||
//
|
||||
// (A shader contains a static assignment to a variable x if, after pre-processing, the shader
|
||||
// contains statement that would write x, whether or not run-time flow of control will cause
|
||||
// that statement to be executed.)
|
||||
//
|
||||
// The variable gl_FragData is an array. Writing to gl_FragData[n] specifies the fragment data
|
||||
// that will be used by the subsequent fixed functionality pipeline for data n. If subsequent
|
||||
// fixed functionality consumes fragment data and an execution of a fragment shader does not
|
||||
// write a value to it, then the fragment data consumed is undefined.
|
||||
//
|
||||
// If a shader statically assigns a value to gl_FragColor, it may not assign a value to any element
|
||||
// of gl_FragData. If a shader statically writes a value to any element of gl_FragData, it may not
|
||||
// assign a value to gl_FragColor. That is, a shader may assign values to either gl_FragColor or
|
||||
// gl_FragData, but not both.
|
||||
//
|
||||
// If a shader executes the discard keyword, the fragment is discarded, and the values of
|
||||
// gl_FragDepth, gl_FragColor and gl_FragData become irrelevant.
|
||||
//
|
||||
// The variable gl_FragCoord is available as a read-only variable from within fragment shaders
|
||||
// and it holds the window relative coordinates x, y, z, and 1/w values for the fragment. This
|
||||
// value is the result of the fixed functionality that interpolates primitives after vertex
|
||||
// processing to generate fragments. The z component is the depth value that would be used for
|
||||
// the fragment’s depth if a shader contained no writes to gl_FragDepth. This is useful for
|
||||
// invariance if a shader conditionally computes gl_FragDepth but otherwise wants the fixed
|
||||
// functionality fragment depth.
|
||||
//
|
||||
// The fragment shader has access to the read-only built-in variable gl_FrontFacing whose value
|
||||
// is true if the fragment belongs to a front-facing primitive. One use of this is to emulate
|
||||
// two-sided lighting by selecting one of two colors calculated by the vertex shader.
|
||||
//
|
||||
// The built-in variables that are accessible from a fragment shader are intrinsically given types
|
||||
// as follows:
|
||||
//
|
||||
|
||||
vec4 gl_FragCoord;
|
||||
bool gl_FrontFacing;
|
||||
vec4 gl_FragColor;
|
||||
vec4 gl_FragData[gl_MaxDrawBuffers];
|
||||
float gl_FragDepth;
|
||||
|
||||
//
|
||||
// However, they do not behave like variables with no qualifier; their behavior is as described
|
||||
// above. These built-in variables have global scope.
|
||||
//
|
||||
|
||||
//
|
||||
// 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 varying variables are available to read from in a fragment shader. The gl_Color
|
||||
// and gl_SecondaryColor names are the same names as attributes passed to the vertex shader.
|
||||
// However, there is no name conflict, because attributes are visible only in vertex shaders
|
||||
// and the following are only visible in a fragment shader.
|
||||
//
|
||||
|
||||
varying vec4 gl_Color;
|
||||
varying vec4 gl_SecondaryColor;
|
||||
varying vec4 gl_TexCoord[]; // at most will be gl_MaxTextureCoords
|
||||
varying float gl_FogFragCoord;
|
||||
|
||||
//
|
||||
// The values in gl_Color and gl_SecondaryColor will be derived automatically by the system from
|
||||
// gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor, and gl_BackSecondaryColor based on which
|
||||
// face is visible. If fixed functionality is used for vertex processing, then gl_FogFragCoord will
|
||||
// either be the z-coordinate of the fragment in eye space, or the interpolation of the fog
|
||||
// coordinate, as described in section 3.10 of the OpenGL 1.4 Specification. The gl_TexCoord[]
|
||||
// values are the interpolated gl_TexCoord[] values from a vertex shader or the texture coordinates
|
||||
// of any fixed pipeline based vertex functionality.
|
||||
//
|
||||
// Indices to the fragment shader gl_TexCoord array are as described above in the vertex shader
|
||||
// text.
|
||||
//
|
||||
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
//
|
||||
// 8.7 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 that represents a depth texture with depth
|
||||
// comparisons turned on, then results are undefined. If a shadow texture call is made to a sampler
|
||||
// that represents a depth texture with depth comparisions turned off, the results are undefined.
|
||||
// If a shadow texture call is made to a sampler that does not represent a depth texture, then
|
||||
// results are 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 texture1D (sampler1D sampler, float coord, float bias) {
|
||||
return vec4 (0.0);
|
||||
}
|
||||
vec4 texture1DProj (sampler1D sampler, vec2 coord, float bias) {
|
||||
return texture1D (sampler, coord.s / coord.t, bias);
|
||||
}
|
||||
vec4 texture1DProj (sampler1D sampler, vec4 coord, float bias) {
|
||||
return texture1D (sampler, coord.s / coord.q, bias);
|
||||
}
|
||||
|
||||
//
|
||||
// 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 texture2D (sampler2D sampler, vec2 coord, float bias) {
|
||||
return vec4 (0.0);
|
||||
}
|
||||
vec4 texture2DProj (sampler2D sampler, vec3 coord, float bias) {
|
||||
return texture2D (sampler, vec2 (coord.s / coord.p, coord.t / coord.p), bias);
|
||||
}
|
||||
vec4 texture2DProj (sampler2D sampler, vec4 coord, float bias) {
|
||||
return texture2D (sampler, vec2 (coord.s / coord.q, coord.s / coord.q), bias);
|
||||
}
|
||||
|
||||
//
|
||||
// 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 texture3D (sampler3D sampler, vec3 coord, float bias) {
|
||||
return vec4 (0.0);
|
||||
}
|
||||
vec4 texture3DProj (sampler3D sampler, vec4 coord, float bias) {
|
||||
return texture3DProj (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q),
|
||||
bias);
|
||||
}
|
||||
|
||||
//
|
||||
// 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 textureCube (samplerCube sampler, vec3 coord, float bias) {
|
||||
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 shadow1D (sampler1DShadow sampler, vec3 coord, float bias) {
|
||||
return vec4 (0.0);
|
||||
}
|
||||
// XXX
|
||||
vec4 shadow2D (sampler2DShadow sampler, vec3 coord, float bias) {
|
||||
return vec4 (0.0);
|
||||
}
|
||||
vec4 shadow1DProj (sampler1DShadow sampler, vec4 coord, float bias) {
|
||||
return shadow1D (sampler, vec3 (coord.s / coord.q, 0.0, coord.p / coord.q), bias);
|
||||
}
|
||||
vec4 shadow2DProj (sampler2DShadow sampler, vec4 coord, float bias) {
|
||||
return shadow2D (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q), bias);
|
||||
}
|
||||
|
||||
//
|
||||
// 8.8 Fragment Processing Functions
|
||||
//
|
||||
// Fragment processing functions are only available in shaders intended for use on the fragment
|
||||
// processor. Derivatives may be computationally expensive and/or numerically unstable. Therefore,
|
||||
// an OpenGL implementation may approximate the true derivatives by using a fast but not entirely
|
||||
// accurate derivative computation.
|
||||
//
|
||||
// The expected behavior of a derivative is specified using forward/backward differencing.
|
||||
//
|
||||
// Forward differencing:
|
||||
//
|
||||
// F(x+dx) - F(x) ~ dFdx(x) * dx 1a
|
||||
// dFdx(x) ~ (F(x+dx) - F(x)) / dx 1b
|
||||
//
|
||||
// Backward differencing:
|
||||
//
|
||||
// F(x-dx) - F(x) ~ -dFdx(x) * dx 2a
|
||||
// dFdx(x) ~ (F(x) - F(x-dx)) / dx 2b
|
||||
//
|
||||
// With single-sample rasterization, dx <= 1.0 in equations 1b and 2b. For multi-sample
|
||||
// rasterization, dx < 2.0 in equations 1b and 2b.
|
||||
//
|
||||
// dFdy is approximated similarly, with y replacing x.
|
||||
//
|
||||
// A GL implementation may use the above or other methods to perform the calculation, subject
|
||||
// to the following conditions:
|
||||
//
|
||||
// 1) The method may use piecewise linear approximations. Such linear approximations imply that
|
||||
// higher order derivatives, dFdx(dFdx(x)) and above, are undefined.
|
||||
//
|
||||
// 2) The method may assume that the function evaluated is continuous. Therefore derivatives within
|
||||
// the body of a non-uniform conditional are undefined.
|
||||
//
|
||||
// 3) The method may differ per fragment, subject to the constraint that the method may vary by
|
||||
// window coordinates, not screen coordinates. The invariance requirement described in section
|
||||
// 3.1 of the OpenGL 1.4 specification is relaxed for derivative calculations, because
|
||||
// the method may be a function of fragment location.
|
||||
//
|
||||
// Other properties that are desirable, but not required, are:
|
||||
//
|
||||
// 4) Functions should be evaluated within the interior of a primitive (interpolated, not
|
||||
// extrapolated).
|
||||
//
|
||||
// 5) Functions for dFdx should be evaluated while holding y constant. Functions for dFdy should
|
||||
// be evaluated while holding x constant. However, mixed higher order derivatives, like
|
||||
// dFdx(dFdy(y)) and dFdy(dFdx(x)) are undefined.
|
||||
//
|
||||
// In some implementations, varying degrees of derivative accuracy may be obtained by providing
|
||||
// GL hints (section 5.6 of the OpenGL 1.4 specification), allowing a user to make an image
|
||||
// quality versus speed tradeoff.
|
||||
//
|
||||
|
||||
//
|
||||
// Returns the derivative in x using local differencing for the input argument p.
|
||||
//
|
||||
// XXX
|
||||
float dFdx (float p) {
|
||||
return 0.0;
|
||||
}
|
||||
// XXX
|
||||
vec2 dFdx (vec2 p) {
|
||||
return vec2 (0.0);
|
||||
}
|
||||
// XXX
|
||||
vec3 dFdx (vec3 p) {
|
||||
return vec3 (0.0);
|
||||
}
|
||||
// XXX
|
||||
vec4 dFdx (vec4 p) {
|
||||
return vec4 (0.0);
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the derivative in y using local differencing for the input argument p.
|
||||
//
|
||||
// These two functions are commonly used to estimate the filter width used to anti-alias procedural
|
||||
// textures.We are assuming that the expression is being evaluated in parallel on a SIMD array so
|
||||
// that at any given point in time the value of the function is known at the grid points
|
||||
// represented by the SIMD array. Local differencing between SIMD array elements can therefore
|
||||
// be used to derive dFdx, dFdy, etc.
|
||||
//
|
||||
// XXX
|
||||
float dFdy (float p) {
|
||||
return 0.0;
|
||||
}
|
||||
// XXX
|
||||
vec2 dFdy (vec2 p) {
|
||||
return vec2 (0.0);
|
||||
}
|
||||
// XXX
|
||||
vec3 dFdy (vec3 p) {
|
||||
return vec3 (0.0);
|
||||
}
|
||||
// XXX
|
||||
vec4 dFdy (vec4 p) {
|
||||
return vec4 (0.0);
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the sum of the absolute derivative in x and y using local differencing for the input
|
||||
// argument p, i.e.:
|
||||
//
|
||||
// return = abs (dFdx (p)) + abs (dFdy (p));
|
||||
//
|
||||
|
||||
float fwidth (float p) {
|
||||
return abs (dFdx (p)) + abs (dFdy (p));
|
||||
}
|
||||
vec2 fwidth (vec2 p) {
|
||||
return abs (dFdx (p)) + abs (dFdy (p));
|
||||
}
|
||||
vec3 fwidth (vec3 p) {
|
||||
return abs (dFdx (p)) + abs (dFdy (p));
|
||||
}
|
||||
vec4 fwidth (vec4 p) {
|
||||
return abs (dFdx (p)) + abs (dFdy (p));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,260 +1,262 @@
|
|||
|
||||
//
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 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.10, rev. 59
|
||||
//
|
||||
// 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_MaxTextureCoords
|
||||
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 an integral constant
|
||||
// expressions, or this array must be re-declared by the shader with a size. The size can be
|
||||
// at most gl_MaxTextureCoords. 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;
|
||||
}
|
||||
|
||||
//
|
||||
// 8.7 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 that represents a depth texture with depth
|
||||
// comparisons turned on, then results are undefined. If a shadow texture call is made to a sampler
|
||||
// that represents a depth texture with depth comparisions turned off, the results are undefined.
|
||||
// If a shadow texture call is made to a sampler that does not represent a depth texture, then
|
||||
// results are 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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue