Name
ATI_fragment_shader
Name Strings
GL_ATI_fragment_shader
Contributors
Dan Ginsburg
Evan Hart
Jason Mitchell
Contact
Benj Lipchak, ATI Research (blipchak 'at' ati.com)
Status
Shipping (version 1.0)
Version
Last Modified Date: August 21, 2002
Author Revision: 1.7
Number
245
Dependencies
ARB_multitexture is required by this extension.
ARB_shadow interacts with this extension.
The extension is written against the OpenGL 1.2.1 Specification.
Overview
This extension exposes a powerful fragment shading model which
provides a very general means of expressing fragment color blending
and dependent texture address modification. The programming is
a register-based model in which there is a fixed number of
instructions, texture lookups, read/write registers, and constants.
The fragment shader extension provides a unified instruction set
for operating on address or color data and eliminates the
distinction between the two. This extension provides all the
interfaces necessary to fully expose this programmable fragment
shader in GL.
Although conceived as a device-independent extension which would
expose the capabilities of future generations of hardware, changing
trends in programmable hardware have affected the lifespan of this
extension. For this reason you will now find a fixed set of
features and resources exposed, and the queries to determine this
set have been deprecated.
Issues
None
New Procedures and Functions
uint GenFragmentShadersATI (uint range);
void BindFragmentShaderATI (uint id);
void DeleteFragmentShaderATI (uint id);
void BeginFragmentShaderATI (void);
void EndFragmentShaderATI (void);
void PassTexCoordATI (uint dst, uint coord, enum swizzle);
void SampleMapATI (uint dst, uint interp, enum swizzle);
void ColorFragmentOp1ATI (enum op, uint dst, uint dstMask,
uint dstMod, uint arg1, uint arg1Rep,
uint arg1Mod);
void ColorFragmentOp2ATI (enum op, uint dst, uint dstMask,
uint dstMod, uint arg1, uint arg1Rep,
uint arg1Mod, uint arg2, uint arg2Rep,
uint arg2Mod);
void ColorFragmentOp3ATI (enum op, uint dst, uint dstMask,
uint dstMod, uint arg1, uint arg1Rep,
uint arg1Mod, uint arg2, uint arg2Rep,
uint arg2Mod, uint arg3, uint arg3Rep,
uint arg3Mod);
void AlphaFragmentOp1ATI (enum op, uint dst, uint dstMod,
uint arg1, uint arg1Rep, uint arg1Mod);
void AlphaFragmentOp2ATI (enum op, uint dst, uint dstMod,
uint arg1, uint arg1Rep, uint arg1Mod,
uint arg2, uint arg2Rep, uint arg2Mod);
void AlphaFragmentOp3ATI (enum op, uint dst, uint dstMod,
uint arg1, uint arg1Rep, uint arg1Mod,
uint arg2, uint arg2Rep, uint arg2Mod,
uint arg3, uint arg3Rep, uint arg3Mod);
void SetFragmentShaderConstantATI (uint dst, const float *value);
New Tokens
Accepted by the parameter of Enable, Disable, and IsEnabled,
and by the parameter of GetBooleanv, GetIntegerv, GetFloatv,
and GetDoublev:
FRAGMENT_SHADER_ATI 0x8920
Accepted by the and parameters of
ColorFragmentOp[1..3]ATI and AlphaFragmentOp[1..3]ATI, and by the
and parameters of PassTexCoordATI, and by the
and parameters of SampleMapATI:
REG_0_ATI 0x8921
REG_1_ATI 0x8922
REG_2_ATI 0x8923
REG_3_ATI 0x8924
REG_4_ATI 0x8925
REG_5_ATI 0x8926
Accepted by the parameter of SetFragmentShaderConstantATI and
the parameter of ColorFragmentOp[1..3]ATI and
AlphaFragmentOp[1..3]ATI:
CON_0_ATI 0x8941
CON_1_ATI 0x8942
CON_2_ATI 0x8943
CON_3_ATI 0x8944
CON_4_ATI 0x8945
CON_5_ATI 0x8946
CON_6_ATI 0x8947
CON_7_ATI 0x8948
Accepted by the parameter of ColorFragmentOp1ATI and
AlphaFragmentOp1ATI:
MOV_ATI 0x8961
Accepted by the parameter of ColorFragmentOp2ATI and
AlphaFragmentOp2ATI:
ADD_ATI 0x8963
MUL_ATI 0x8964
SUB_ATI 0x8965
DOT3_ATI 0x8966
DOT4_ATI 0x8967
Accepted by the parameter of ColorFragmentOp3ATI and
AlphaFragmentOp3ATI:
MAD_ATI 0x8968
LERP_ATI 0x8969
CND_ATI 0x896A
CND0_ATI 0x896B
DOT2_ADD_ATI 0x896C
Accepted by the parameter of ColorFragmentOp[1..3]ATI and
AlphaFragmentOp[1..3]ATI:
ZERO
ONE
PRIMARY_COLOR_ARB
SECONDARY_INTERPOLATOR_ATI 0x896D
Accepted by the parameter of SampleMapATI and the
parameter of PassTexCoordATI:
TEXTURE0_ARB
TEXTURE1_ARB
TEXTURE2_ARB
TEXTURE3_ARB
TEXTURE4_ARB
TEXTURE5_ARB
TEXTURE6_ARB
TEXTURE7_ARB
Accepted by the parameter of SampleMapATI and
PassTexCoordATI:
SWIZZLE_STR_ATI 0x8976
SWIZZLE_STQ_ATI 0x8977
SWIZZLE_STR_DR_ATI 0x8978
SWIZZLE_STQ_DQ_ATI 0x8979
Accepted by the parameter of ColorFragmentOp[1..3]ATI:
NONE
RED_BIT_ATI 0x00000001
GREEN_BIT_ATI 0x00000002
BLUE_BIT_ATI 0x00000004
Accepted by the parameter of ColorFragmentOp[1..3]ATI and
AlphaFragmentOp[1..3]ATI:
NONE
RED
GREEN
BLUE
ALPHA
Accepted by the parameter of ColorFragmentOp[1..3]ATI and
AlphaFragmentOp[1..3]ATI:
NONE
2X_BIT_ATI 0x00000001
4X_BIT_ATI 0x00000002
8X_BIT_ATI 0x00000004
HALF_BIT_ATI 0x00000008
QUARTER_BIT_ATI 0x00000010
EIGHTH_BIT_ATI 0x00000020
SATURATE_BIT_ATI 0x00000040
Accepted by the parameter of ColorFragmentOp[1..3]ATI and
AlphaFragmentOp[1..3]ATI:
2X_BIT_ATI 0x00000001
COMP_BIT_ATI 0x00000002
NEGATE_BIT_ATI 0x00000004
BIAS_BIT_ATI 0x00000008
Additions to Chapter 2 of the OpenGL 1.2.1 Specification (OpenGL
Operation)
None
Additions to Chapter 3 of the OpenGL 1.2.1 Specification (Rasterization)
Add New Subsection after 3.8.10, (p. 138)
3.8.11 Fragment Shaders
By default, the current texture environment is used to determine
how textures are combined for rasterization. However, by enabling
FRAGMENT_SHADER_ATI, the currently bound fragment shader is used to
determine how textures are combined. The fragment shader replaces
the traditional texture environment by exposing a fragment shading
model which provides a very general means of expressing fragment
color blending and dependent texture address modification. The
distinction between texture address and color data becomes
irrelevant in the fragment shader as the two can be used
interchangeably.
A shader is defined between a BeginFragmentShaderATI and
EndFragmentShaderATI block. These commands are defined as follows:
void BeginFragmentShaderATI(void);
void EndFragmentShaderATI(void);
Although there is no restriction as to which GL operations may be
specified between BeginFragmentShaderATI and EndFragmentShaderATI,
only the following operations will be compiled into a shader:
PassTexCoordATI, SampleMapATI, ColorFragmentOp[1..3]ATI,
AlphaFragmentOp[1..3]ATI, and SetFragmentShaderContantATI.
In addition to a default fragment shader, named shaders can be
created. The namespace for shaders is unsigned integers with zero
reserved by the GL. A shader is created by binding an unused name
using:
void BindFragmentShaderATI(uint id);
where is the unused name. Once a shader has been created it
can be rebound as the active shader by calling
BindFragmentShaderATI. A shader can be deleted, freeing the name,
by calling:
void DeleteFragmentShaderATI(uint id);
where is the name to be deleted. Unique names can be generated
using:
uint GenFragmentShadersATI(uint range);
where is the number of contiguous ids that should be
created. It returns an integer n such that contiguous empty
shader ids, with values n, n+1, ..., n+-1, are created. If
is 0, if there is no group of contiguous names
available, or if any error is generated, no shaders are generated,
and 0 is returned.
If FRAGMENT_SHADER_ATI is enabled, but the currently bound shader is
invalid, the results of drawing commands are undefined. A shader
may be invalid because it is currently being specified (i.e., a
drawing command within a Begin/EndFragmentShader pair), or due to
some error during the specification of a shader.
There are three types of data that can be in a fragment shader:
registers, constants, and interpolators. The 6 REG_x_ATI registers
can be used as source or destination in any color or alpha
instruction. The final result of the shader is whatever value is in
REG_0_ATI. This value will be the final color of the output
fragment passed.
There are 8 constant registers available, CON_0_ATI through
CON_7_ATI. CON_x_ATI constants can be used as source in any color
or alpha instruction, but at most 2 different constants may be used
as source arguments in each instruction.
Additionally, the primary and secondary color interpolators are
available as source in any color or alpha instruction, but only in
the last pass of the shader (i.e., the only pass of a one-pass
shader or the second pass of a two-pass shader).
Either one or two passes may be specified in a shader. Each pass
may use up to 8 pairs of instructions for a total of at most 16
pairs in the shader. A pair consists of one color instruction and
one alpha instruction.
The first instructions specified in each pass of a shader are "free"
instructions in that they don't count against the 8 instructions
available in each pass. They are routing instructions which specify
from where the contents of the registers come. The first occurance
of one of these free instructions marks the beginning of a pass in
the shader. They are specified with SampleMapATI and
PassTexCoordATI.
The entry point:
void PassTexCoordATI (uint dst, uint coord, enum swizzle);
specifies that the value present in is passed directly into
the contents of (one of the registers REG_x_ATI). This value
is then available for use as a source argument to subsequent color
and alpha instructions following in the same pass. may
either be the texture coordinates on a texture unit (TEXTUREx_ARB),
or in the case of a two-pass shader's second pass, it may be the
value of a register set in the first pass (REG_x_ATI).
Note that in order to preserve the contents of a register from the
first pass to the second, there must be a PassTexCoordATI
instruction in the setup for the second pass that assigns that
register to itself. For example:
PassTexCoordATI(REG_1_ATI, REG_1_ATI, SWIZZLE_STR_ATI);
will preserve the first 3 components of REG_1_ATI for use in the
second pass.
The entry point:
void SampleMapATI (uint dst, uint interp, enum swizzle);
specifies that the value present in the texture data bound on the
unit associated with will be written to that register. A
value for of REG_x_ATI means that TEXTUREx_ARB will be
sampled, and the result written to REG_x_ATI. The
parameter specifies which texture coordinate interpolator is used to
sample the map. A value of REG_x_ATI for in the second
pass of a two-pass shader will do dependent texture read sampling
using the value in register x. Otherwise, specifying TEXTUREx_ARB
will sample the map using the texture coordinates on unit x.
Only the first 3 components of or are used in
PassTexCoordATI and SampleMapATI, respectively. The swizzle
parameter is used to select which of the 4 original components of
the source register or texture coordinates will be mapped to the 3
available positions, and whether or not a projection will occur.
Table 3.20 shows the modes:
Coordinates Used for 1D or Coordinates Used for
Swizzle 2D SampleMap and PassTexCoord 3D or cubemap SampleMap
------- ----------------------------- -----------------------
SWIZZLE_STR_ATI (s, t, r, undefined) (s, t, r, undefined)
SWIZZLE_STQ_ATI (s, t, q, undefined) (s, t, q, undefined)
SWIZZLE_STR_DR_ATI (s/r, t/r, 1/r, undefined) (undefined)
SWIZZLE_STQ_DQ_ATI (s/q, t/q, 1/q, undefined) (undefined)
Table 3.20 Coordinate swizzles
Each texture coordinate source (TEXTUREx_ARB) used as a
and/or can only draw upon STR or STQ components throughout
the shader. For example, if TEXTURE2_ARB is used in a SampleMapATI
with SWIZZLE_STR_ATI, it cannot be used again later with a
of SWIZZLE_STQ_ATI. The projection, however, may vary.
It would be okay to later use TEXTURE2_ARB with a of
SWIZZLE_STR_DR_ATI.
Additionally, when the or is a register (in the
second pass of a two-pass shader), only SWIZZLE_STR_ATI and
SWIZZLE_STR_DR_ATI are allowed. Note that if this is a
PassTexCoord, the fourth component (alpha channel if the register
contains RGBA) is not passed along and the fourth component of
becomes undefined.
The color and alpha instructions performed in the shader are
specified with the following entry points:
void ColorFragmentOp1ATI (enum op, uint dst, uint dstMask, uint dstMod,
uint arg1, uint arg1Rep, uint arg1Mod);
void ColorFragmentOp2ATI (enum op, uint dst, uint dstMask, uint dstMod,
uint arg1, uint arg1Rep, uint arg1Mod,
uint arg2, uint arg2Rep, uint arg2Mod);
void ColorFragmentOp3ATI (enum op, uint dst, uint dstMask, uint dstMod,
uint arg1, uint arg1Rep, uint arg1Mod,
uint arg2, uint arg2Rep, uint arg2Mod,
uint arg3, uint arg3Rep, uint arg3Mod);
void AlphaFragmentOp1ATI (enum op, uint dst, uint dstMod,
uint arg1, uint arg1Rep, uint arg1Mod);
void AlphaFragmentOp2ATI (enum op, uint dst, uint dstMod,
uint arg1, uint arg1Rep, uint arg1Mod,
uint arg2, uint arg2Rep, uint arg2Mod);
void AlphaFragmentOp3ATI (enum op, uint dst, uint dstMod,
uint arg1, uint arg1Rep, uint arg1Mod,
uint arg2, uint arg2Rep, uint arg2Mod,
uint arg3, uint arg3Rep, uint arg3Mod);
A ColorFragmentOp[1..3]ATI followed by an AlphaFragmentOp[1..3]ATI
is considered to be an instruction pair, and 8 such pairs may be
specified per pass. The color and alpha instructions of a pair are
executed in parallel: the result of the color instruction cannot
affect the source arguments of the alpha instruction. Both a color
and an alpha instruction need not be specified for every pair; the
necessary color or alpha no-op is automatically inserted by the GL
to complete each instruction pair.
The parameter specifies the instruction to perform on the
sources.
Table 3.21 shows the effect of each . R(d), G(d), and B(d) are
the destination values when using the instruction on color and A(d)
is the destination value when using the instruction on alpha.
Op Result
-- ------
ADD_ATI R(d) = R(a1) + R(a2)
G(d) = G(a1) + G(a2)
B(d) = B(a1) + B(a2)
A(d) = A(a1) + A(a2)
SUB_ATI R(d) = R(a1) - R(a2)
G(d) = G(a1) - G(a2)
B(d) = B(a1) - B(a2)
A(d) = A(a1) - A(a2)
MUL_ATI R(d) = R(a1) * R(a2)
G(d) = G(a1) * G(a2)
B(d) = B(a1) * B(a2)
A(d) = A(a1) * A(a2)
MAD_ATI R(d) = R(a1) * R(a2) + R(a3)
G(d) = G(a1) * G(a2) + G(a3)
B(d) = B(a1) * B(a2) + B(a3)
A(d) = A(a1) * A(a2) + A(a3)
LERP_ATI*** R(d) = R(a1) * R(a2) + (1 - R(a1)) * R(a3)
G(d) = G(a1) * G(a2) + (1 - G(a1)) * G(a3)
B(d) = B(a1) * B(a2) + (1 - B(a1)) * B(a3)
A(d) = A(a1) * A(a2) + (1 - A(a1)) * A(a3)
MOV_ATI R(d) = R(a1)
G(d) = G(a1)
B(d) = B(a1)
A(d) = A(a1)
CND_ATI R(d) = (R(a3) > 0.5) ? R(a1) : R(a2)
G(d) = (G(a3) > 0.5) ? G(a1) : G(a2)
B(d) = (B(a3) > 0.5) ? B(a1) : B(a2)
A(d) = (A(a3) > 0.5) ? A(a1) : A(a2)
CND0_ATI R(d) = (R(a3) >= 0) ? R(a1) : R(a2)
G(d) = (G(a3) >= 0) ? G(a1) : G(a2)
B(d) = (B(a3) >= 0) ? B(a1) : B(a2)
A(d) = (A(a3) >= 0) ? A(a1) : A(a2)
DOT2_ADD_ATI* R(d) = G(d) = B(d) = A(d) = R(a1) * R(a2) +
G(a1) * G(a2) +
B(a3)
DOT3_ATI* R(d) = G(d) = B(d) = A(d) = R(a1) * R(a2) +
G(a1) * G(a2) +
B(a1) * B(a2)
DOT4_ATI* ** R(d) = G(d) = B(d) = A(d) = R(a1) * R(a2) +
G(a1) * G(a2) +
B(a1) * B(a2) +
A(a1) * A(a2)
Table 3.21 Color and Alpha Fragment Shader Instructions
Special Notes:
* - DOT2_ADD_ATI/DOT3_ATI/DOT4_ATI can only be specified as
an alpha instruction directly after being specified as
a color instruction. When specified as an alpha
instruction, the parameters are ignored, although they
should be valid enumerants in order to compile. The
result of the color instruction will simply be placed
in the alpha .
** - After a DOT4_ATI color instruction is specified, the
only alpha instruction that can immediately follow is a
DOT4_ATI. This is because the DOT4 color instruction
implicitely uses an alpha instruction to calculate the
result. If another type of alpha instruction is
desired after a DOT4_ATI color instruction is issued,
there are two choices: either issue another color
instruction first, or issue the DOT4_ATI alpha
instruction followed by the desired alpha instruction.
*** - The blend factor (a1) of LERP_ATI must be in the range
[0,1] or the results are undefined.
The parameter specifies to which register (REG_x_ATI) the
result of the instruction is written.
The parameter specifies which of the color components in
will be written (ColorFragmentOp[1..3]ATI only). This can
either be NONE, in which case there is no mask and everything is
written, or the bitwise-or of RED_BIT_ATI, GREEN_BIT_ATI, and
BLUE_BIT_ATI.
The parameter specifies which modifications are performed
on each component of the destination. The result can be modulated
by specifying either 2X_BIT_ATI, 4X_BIT_ATI, 8X_BIT_ATI,
HALF_BIT_ATI, QUARTER_BIT_ATI, or EIGHTH_BIT_ATI. These are all
mutually exclusive, and can optionally be bitwise-or'd with
SATURATE_BIT_ATI, which clamps the result after any modulation
occurs.
Table 3.22 shows the result of each modification.
Modifier Result
-------- ------
NONE d = d
2X_BIT_ATI d = 2 * d
4X_BIT_ATI d = 4 * d
8X_BIT_ATI d = 8 * d
HALF_BIT_ATI d = d / 2
QUARTER_BIT_ATI d = d / 4
EIGHTH_BIT_ATI d = d / 8
SATURATE_BIT_ATI d = clamp(d) to range [0, 1]
Table 3.22 Result of destination modification
Note that the internal precision of the fragment shader allows
values in the range [-8, 8].
The parameter specifies the source argument. The source can
come from REG_x_ATI, CON_x_ATI, ZERO, ONE, PRIMARY_COLOR_ARB, or
SECONDARY_INTERPOLATOR_ATI. Note that in a two-pass shader,
PRIMARY_COLOR_ARB and SECONDARY_INTERPOLATOR_ATI cannot be used in
the first pass of the shader.
Each argument has an parameter which specifies the
replication of each component.
Table 3.23 shows the result of each source replication.
Replication Result
----------- -----
NONE R(s) = R(s)
G(s) = G(s)
B(s) = B(s)
A(s) = A(s)
RED R(s) = R(s)
G(s) = R(s)
B(s) = R(s)
A(s) = R(s)
GREEN R(s) = G(s)
G(s) = G(s)
B(s) = G(s)
A(s) = G(s)
BLUE R(s) = B(s)
G(s) = B(s)
B(s) = B(s)
A(s) = B(s)
ALPHA R(s) = A(s)
G(s) = A(s)
B(s) = A(s)
A(s) = A(s)
Table 3.23 Result of source replication
Each argument also has an parameter which specifies
modifiers to each component. A value of NONE specifies that no
modifiers are present. Otherwise, the bitwise-or of NEGATE_BIT_ATI,
BIAS_BIT_ATI, and 2X_BIT_ATI can be specified as modifiers.
Table 3.24 shows the result of each source modifier.
Modifier Result
-------- ------
NONE s = s
NEGATE_BIT_ATI s = -s
COMP_BIT_ATI s = 1 - s
BIAS_BIT_ATI s = s - 0.5
2X_BIT_ATI s = 2 * s
Table 3.24 Result of source modification
If multiple source modifiers are applied, the order of operations is
COMP, BIAS, SCALE, then NEGATE. The following equation shows the
order of operations if all modifiers were to be applied:
s = -(2 * ((1.0 - s) - 0.5))
In order to set the constants that can be used by shader
instructions, the entry point:
void SetFragmentShaderConstantATI (uint dst, const float *value);
is used. The parameter specifies which of the constants
(CON_x_ATI) to set. The pointer must contain four floating
point values in the range [0, 1] to set the components of the
constant. Constant registers loaded with floating point values
outside of this range will have undefined values. Calls to this
function which occur inside a shader definition are automatically
bound when the shader is bound. This means that shader constants
have scope: if SetFragmentShaderConstantATI is called outside a
shader definition, it is bound globally. However, if that same
shader constant is set inside the shader, it overrides the global
definition when bound.
Additions to Chapter 4 of the OpenGL 1.2.1 Specification (Per-Fragment
Operations and the Framebuffer)
None
Additions to Chapter 5 of the OpenGL 1.2.1 Specification (Special
Functions)
Modify Section 5.4, Display Lists (p. 175)
(modify last paragraph, p. 178) ... These are: IsList, GenLists,
..., GenFragmentShadersATI, DeleteFragmentShadersATI,
BeginFragmentShaderATI, EndFragmentShaderATI, PassTexCoordATI,
SampleMapATI, ColorFragmentOp[1..3]ATI, AlphaFragmentOp[1..3]ATI,
as well as IsEnabled and all of the Get commands (see Chapter 6).
Additions to Chapter 6 of the OpenGL 1.2.1 Specification (State and
State Requests)
None
Additions to Appendix A of the OpenGL 1.2.1 Specification (Invariance)
None
Additions to the AGL/GLX/WGL Specifications
None
Interactions with ARB_shadow
The texture comparison introduced by ARB_shadow can be expressed in
terms of a fragment shader, and in fact use the same internal
resources on some implementations. Therefore, if fragment shader
mode is enabled, the GL behaves as if TEXTURE_COMPARE_MODE_ARB is
NONE.
Errors
The error INVALID_VALUE is generated if GenFragmentShadersATI is
called where is zero.
The error INVALID_OPERATION is generated if GenFragmentShadersATI,
BindFragmentShaderATI, DeleteFragmentShaderATI, or
BeginFragmentShaderATI are specified inside a
Begin/EndFragmentShaderATI pair.
The error INVALID_OPERATION is generated if EndFragmentShaderATI,
PassTexCoordATI, SampleMapATI, ColorFragmentOp[1..3]ATI, or
AlphaFragmentOp[1..3]ATI is specified outside a
Begin/EndFragmentShaderATI pair.
The error INVALID_OPERATION is generated by EndFragmentShaderATI if
passed to ColorFragmentOp[1..3]ATI or
AlphaFragmentOp[1..3]ATI is PRIMARY_COLOR_ARB or
SECONDARY_INTERPOLATOR_ATI on the first pass of a two-pass shader,
or if the shader cannot be compiled due to some other
implementation-dependent limitation. EndFragmentShaderATI will
still have a side-effect if this error is encountered: the
Begin/EndFragmentShaderATI pair will be closed, and the current
shader will be undefined.
The error INVALID_OPERATION is generated by PassTexCoordATI or
SampleMapATI if two shader passes have already been specified, or if
the same register is specified twice in the same pass.
The error INVALID_OPERATION is generated by PassTexCoordATI or
SampleMapATI if passed to PassTexCoordATI or passed
to SampleMapATI is a register in the first pass, or a register with
SWIZZLE_STQ_ATI or SWIZZLE_STQ_DQ_ATI in the second pass,
or if different parameters are specified for the same
or in the same pass.
The error INVALID_OPERATION is generated by ColorFragmentOp[1..3]ATI
or AlphaFragmentOp[1..3]ATI if more than 8 instructions have been
specified for a shader pass.
The error INVALID_OPERATION is generated by ColorFragmentOp[1..3]ATI
if is SECONDARY_INTERPOLATOR_ATI and is ALPHA, or
by AlphaFragmentOp[1..3]ATI if is SECONDARY_INTERPOLATOR_ATI
and is ALPHA or NONE, or by ColorFragmentOp2ATI if is
DOT4_ATI and is SECONDARY_INTERPOLATOR_ATI and is
ALPHA or NONE.
The error INVALID_OPERATION is generated by ColorFragmentOp3ATI or
AlphaFragmentOp3ATI if all three parameters are constants,
and all three are different.
The error INVALID_OPERATION is generated by AlphaFragmentOp[2..3]ATI
if is DOT3_ATI, DOT4_ATI, or DOT2_ADD_ATI and there was no
matching ColorFragmentOp[2..3]ATI immediately preceding, or if
is not DOT4_ATI and the immediately preceding ColorFragmentOp2ATI
specifies an of DOT4_ATI.
The error INVALID_ENUM is generated if passed to
PassTexCoordATI, SampleMapATI, ColorFragmentOp[1..3]ATI, or
AlphaFragmentOp[1..3]ATI is not a valid register or is greater than
the number of texture units available on the implementation.
The error INVALID_ENUM is generated if passed to
PassTexCoordATI or passed to SampleMapATI is not a valid
register or texture unit, or the register or texture unit is greater
than the number of texture units available on the implementation.
The error INVALID_ENUM is generated if passed to
ColorFragmentOp[1..3]ATI or AlphaFragmentOp[1..3]ATI is not a valid
constant, interpolator, or register.
The error INVALID_ENUM is generated if passed to
ColorFragmentOp[1..3]ATI or AlphaFragmentOp[1..3]ATI contains
multiple mutually exclusive modifier bits, not counting
SATURATE_BIT_ATI.
New State
Initial
Get Value Type Get Command Value Description Sec. Attribute
--------- ---- ----------- ------- ----------- ------ ---------
FRAGMENT_SHADER_ATI B IsEnabled False Fragment shader enable 3.8.11 enable
Table X.6. New Accessible State Introduced by ATI_fragment_shader.
Get Value Type Get Command Initial Value Description Sec Attribute
--------- ------ ----------- ------------- ------------------- ------ ---------
- 6xR4 - undefined temporary registers 3.8.11 -
Table X.9. Fragment Shader Per-fragment Execution State. All per-fragment
execution state registers are uninitialized at the beginning of program
execution.
New Implementation Dependent State
None
Deprecated Functionality
The following queryable implementation-dependent constants are
described here for backward-compatibility. They are now specified
to always return fixed values on all implementations, and are thus
obsolete.
The number of available registers can be queried by doing a glGet on
NUM_FRAGMENT_REGISTERS_ATI. This refers to the number of
REG_x_ATI's, and is now fixed at 6.
The number of available constants can be queried by doing a glGet on
NUM_FRAGMENT_CONSTANTS. This refers to the number of CON_x_ATI's,
and is now fixed at 8.
The number of passes, instructions per pass, and total instructions
available to a shader can be queried using glGet. Querying for
NUM_PASSES_ATI returns the maximum number of passes that the shader
can perform, now fixed at 2. Querying for
NUM_INSTRUCTIONS_PER_PASS_ATI returns the maximum number of
instructions available on a given pass, now fixed at 8. Finally,
NUM_INSTRUCTIONS_TOTAL_ATI returns the maximum number of total
instructions available to a shader, now fixed at 16 (2 per pass).
COLOR_ALPHA_PAIRING_ATI can be queried by glGet to determine if each
ColorFragmentOp[1..3]ATI/AlphaFragmentOp[1..3]ATI pair counts as one
instruction against the limit, or if each color and alpha
instruction is counted individually (i.e., each pair counts as two
instructions). This query now always returns TRUE: each pair counts
as one instruction against the 8 instructions allowed per pass.
The number of components available in a coordinate interpolator,
passed in as to SampleMapATI or to PassTexCoord,
can be queried using NUM_INTERPOLATOR_COMPONENTS_ATI. This query
now always returns 3, meaning the fourth component is ignored.
The number of components passed in the registers via PassTexCoord
from the first pass to the second can be queried using
NUM_LOOPBACK_COMPONENTS_ATI. This query now always returns 3,
meaning the fourth component of is undefined.
Sample Usage
The following is an example that simulates a chrome surface:
shadername = glGenFragmentShadersATI(1);
glBindFragmentShaderATI(shadername);
glBeginFragmentShaderATI();
// Pass 1
glPassTexCoordATI(GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI); // N
glPassTexCoordATI(GL_REG_2_ATI, GL_TEXTURE2_ARB, GL_SWIZZLE_STR_ATI); // light to vertex vector in light space
glPassTexCoordATI(GL_REG_3_ATI, GL_TEXTURE3_ARB, GL_SWIZZLE_STR_ATI); // H
glSampleMapATI(GL_REG_4_ATI, GL_TEXTURE4_ARB, GL_SWIZZLE_STR_ATI); // L (sample cubemap normalizer)
// reg4 = N.L
glColorFragmentOp2ATI(GL_DOT3_ATI, GL_REG_4_ATI, GL_NONE, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE,
GL_REG_4_ATI, GL_NONE, GL_2X_BIT_ATI|GL_BIAS_BIT_ATI);
// reg1 = N.H
glColorFragmentOp2ATI(GL_DOT3_ATI, GL_REG_1_ATI, GL_NONE, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE,
GL_REG_3_ATI, GL_NONE, GL_NONE);
// reg1(green) = H.H (aka |H|^2)
glColorFragmentOp2ATI(GL_DOT3_ATI, GL_REG_1_ATI, GL_GREEN_BIT_ATI, GL_NONE,
GL_REG_3_ATI, GL_NONE, GL_NONE,
GL_REG_3_ATI, GL_NONE, GL_NONE);
// reg2 = |light to vertex|^2
glColorFragmentOp2ATI(GL_DOT3_ATI, GL_REG_2_ATI, GL_NONE, GL_NONE,
GL_REG_2_ATI, GL_NONE, GL_NONE,
GL_REG_2_ATI, GL_NONE, GL_NONE);
// Pass 2
glSampleMapATI(GL_REG_0_ATI, GL_TEXTURE5_ARB, GL_SWIZZLE_STR_ATI); // sample enviroment map using eye vector
glSampleMapATI(GL_REG_2_ATI, GL_REG_2_ATI, GL_SWIZZLE_STR_ATI); // sample attenuation map
glSampleMapATI(GL_REG_3_ATI, GL_REG_1_ATI, GL_SWIZZLE_STR_ATI); // sample specular NHHH map = (N.H)^256
glPassTexCoordATI(GL_REG_4_ATI, GL_REG_4_ATI, GL_SWIZZLE_STR_ATI); // pass N.L through
// reg3 = (N.H)^256 * (N.L)
// this ensures a pixel is only lit if facing the light (since the specular exponent
// makes negative N.H positive we must do this)
glColorFragmentOp2ATI(GL_MUL_ATI, GL_REG_3_ATI, GL_NONE, GL_NONE,
GL_REG_3_ATI, GL_NONE, GL_NONE,
GL_REG_4_ATI, GL_NONE, GL_NONE);
// reg3 = specular * environment map
glColorFragmentOp2ATI(GL_MUL_ATI, GL_REG_3_ATI, GL_NONE, GL_NONE,
GL_REG_0_ATI, GL_NONE, GL_NONE,
GL_REG_3_ATI, GL_NONE, GL_NONE);
// reg4 = diffuse * environment map
glColorFragmentOp2ATI(GL_MUL_ATI, GL_REG_4_ATI, GL_NONE, GL_NONE,
GL_REG_0_ATI, GL_NONE, GL_NONE,
GL_REG_4_ATI, GL_NONE, GL_NONE);
// reg0 = (specular * environment map) + (diffuse * environment map)
glColorFragmentOp2ATI(GL_ADD_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE,
GL_REG_3_ATI, GL_NONE, GL_NONE,
GL_REG_4_ATI, GL_NONE, GL_NONE);
// apply point light attenuation
glColorFragmentOp2ATI(GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
GL_REG_0_ATI, GL_NONE, GL_NONE,
GL_REG_2_ATI, GL_RED, GL_NONE);
glEndFragmentShaderATI();
Revision History
Date: 8/21/2002
Revision: 1.7
- Fixed lack of comma typo in glAlphaFragmentOp2ATI prototypes.
Date: 8/1/2002
Revision: 1.6
- Changed DeleteFragmentShaderATI behavior to silently ignore the
deletion of non-existent or default shaders.
Date: 6/5/2002
Revision: 1.5
- Added interaction with ARB_shadow.
Date: 5/30/2002
Revision: 1.4
- Specified that LERP's blend factor must be in the range [0,1].
- Added error condition when trying to use secondary color in DOT4
color instruction when replication is GL_NONE or GL_ALPHA.
Date: 5/21/2002
Revision: 1.3
- Made number of registers (REG_x_ATI) explicit: 6.
- Changed CND0_ATI definition from >0 to >=0.
- Added wording to emphasize [0,1] range for constants.
- Added wording to reflect that EndFragmentShaderATI will close
Begin/End pair even if error is encountered.
- Added wording to reflect parallelism of color/alpha pairs.
- Added error condition when trying to use secondary color alpha.
- Added error condition when generating shader IDs with 0.
- Added display list exclusion for everything except
BindFragmentShaderATI and SetFragmentShaderConstantATI.
- Cleaned up, fixed typos, and reformatted.
- Added New State section.
- Replaced sample code.
Date: 4/19/2002
Revision: 1.2
- Updated swizzle table to indicate that projected texcoords are
undefined when used in conjunction with cubemaps or 3D textures.
Date: 3/20/2002
Revision: 1.1
- Made resource availability explicit.
- Deprecated implementation-dependent constant queries.
- Added various error conditions described in prose of spec.
- Changed PRIMARY_COLOR_EXT to PRIMARY_COLOR_ARB.
- Cleaned up and fixed typos throughout.
Date: 1/2/2002
Revision: 1.02
- Added note that PRIMARY_COLOR_EXT and SECONDARY_INTERPOLATOR_ATI can not
be used on the first pass of a two pass shader. Also added error
for this case to Errors section.
- Added note that in order to save the contents of a register from the
first pass to the second, there has to be a PassTexCoordATI() on that
register to itself on the next pass.
- Changed PRIMARY_COLOR to PRIMARY_COLOR_EXT.
Date: 10/15/2001
Revision: 1.01
- Fixed typos in example program.
- Added language about the shader result being placed in REG_0_ATI.
- Specify range supported [-8..8].
- Added notes on how to specify whether DOT4/DOT3/DOT2_ADD result
goes to alpha channel.
Date: 8/21/2001
Revision: 1.0
- Added equation for source modifiers.
Date: 8/6/2001
Revision: 0.6
- Added restraint that only SWIZZLE_STR_ATI and SWIZZLE_STR_DR_ATI
can be used on the second pass when the source is a register.
Date: 6/29/2001
Revision: 0.5
- Removed glTexProjectATI and change glSampleMapATI/glPassTexCoordATI to
take a parameter instead of .
- Changed MAD_ATI from (a + b * c) to (a * b + c).
Date: 6/11/2001
Revision: 0.4
- Removed FRAC_ATI.
- Added parameter to SampleMapATI and PassTexCoordATI to
match current implementation.
Date: 5/01/2001
Revision: 0.3
- Added COLOR_ALPHA_PAIRING_ATI.
- Attempted to clarify definition of SampleMapATI in the documentation
section. Changed to .
- Added TexProjectATI and documented texture projection modes to allow
implementations that only support 3-tuples to select between (s, t, r)
and (s, t, q) coordinates.
Date: 4/19/2001
Revision: 0.2
- Removed from ColorFragmentOp[1..3]ATI.
- Changed SHADER_ATI to FRAGMENT_SHADER_ATI.
- Fixed the 's in the New Tokens section to go to the proper
Color/AlphaOp functions.
- Added ZERO and ONE constants.
- Made number of passes queryable: removed NUM_PASSn_INSTRUCTIONS_ATI,
replaced with NUM_PASSES_ATI, NUM_INSTRUCTIONS_PER_PASS_ATI, and
NUM_INSTRUCTIONS_TOTAL_ATI.
- Documented when new pass starts (SampleMapATI/PassCoordATI).
- Added NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI/NUM_LOOPBACK_COMPONENTS_ATI.
- Fixed sample usage to not do a dependent read on the base map.
Date: 4/16/2001
Revision: 0.1
- First draft