- 一、内置变量
- 二、内置函数
- 三、内置变量解释
- 1、gl_ClipDistance[]
- 2、gl_DepthRange
- 3、gl_FragCoord
- 4、gl_FragDepth
- 5、gl_FrontFacing
- 6、gl_GloballnvocationlD
- 7、gl_InstancelD
- 8、gl_InvocationID
- 9、gl_Layer
- 10、gl_LocallnvocationlD
- 11、gl_Locallnvocationlndex
- 12、gl_NumSamples
- 13、gl_NumWorkGroups
- 14、gl_PatchVerticesIn
- 15、glPointCoord
- 16、gl_PointSize
- 17、gl_Position
- 18、gl_PrimitiveID
- 19、gl_PrimitivelDIn
- 20、gl_SamplelD
- 21、gl_SampleMask
- 22、gl_SampIeMaskln
- 23、gl_SamplePosition
- 24、gl_TessCoord
- 25、gl_TessLevelOuter、gl_TessLevelOuter
- 26、gl_ViewportID
- 27、gl_ViewportIndex
- 28、gl_WorkGroupSize
- 29、gl_WorkGroupID
一、内置变量
1、顶点着色器
in int gl_VertexID;
in int gl_InstanceID;
out gl_PerVertex{
vec4 gl_Position;
float gl__PointSize;
float gl_ClipDistance[];
}
2、细分控制着色器
in gl_PerVertex{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
} gl_in[gl_MaxPatchVertices];
in int gl_PatchVerticesIn;
in int gl_PrimitiveID;
in int gl_InvocationID;
out gl_PerVertex{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
} gl_out[];
patch out float gl_TessLevelOuter[4];
patch out float gl_TessLevelInner[2];
3、细分计算着色器
in gl_PerVertex{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
} gl_in[gl_MaxPatchVertices];
in int gl_PatchVerticesIn;
in int gl_PrimitiveID;
in vec3 gl_TessCoord;
patch in float gl_TessLevelOuter[4];
patch in float gl_TessLevelInner[2];
out gl_PerVertex{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
};
4、几何着色器
in gl_PerVertex{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
} gl_in[];
in int gl_PrimitiveIDIn;
in int gl_InvocationID;
out gl_PerVertex{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
};
out int gl_PrimitiveID;
out int gl_Layer;
out int gl_ViewportIndex;
5、片段着色器
in vec4 gl_FragCoord;
in bool gl_FrontFacing;
in float gl_ClipDistance[];
in vec2 gl_PointCoord;
in int gl_PrimitiveID;
in int gl_SampleID;
in vec2 gl_SamplePosition;
in int gl_SampleMaskin[];
in int gl_Layer;
in int gl_ViewportIndex;
out float gl_FragDepth;
out int g1_SampleMask[];
6、计算着色器
in uvec3 gl_NumWorkGroups; // 工作组大小
const uvec3 gl_WorkGroupSize;
in uvec3 gl_WorkGroupID; // 工作组和调用的ID
in uvec3 gl_LocalInvocationID;
in uvec3 gl_GlobalInvocationID; // 衍生变量
in uint gl__Local Invocationindex;
7、通用着色器
内置状态变量。
struct gl_DepthRangeParameters{
float near;
float far;
float diff;
};
uniform gl_DepthRangeParameters gl_DepthRange;
uniform int gl_NumSamples;
二、内置函数
如果列出每个函数的原型,内容将非常多,我们使用一些符号来代表特定类型。
1、约定符号
返回类型或参数标记 | |
---|---|
通用标记 | 特定类型 |
genType | float vec2 vec3 vec4 |
genDType | double dvec2 dvec3 dvec4 |
genIType | int ivec2 ivec3 ivec4 |
genoType | uint uvec2 uvec3 uvec4 |
genBType | bool bvec2 bvec3 bvec4 |
vec | vec2 vec3 vec4 |
ivec | ivec2 ivec3 ivec4 |
uvec | uvec2 uvec3 uvec4 |
bvec | bvec2 bvec3 bvec4 |
gvec4 | vec4 ivec4 uvec4 |
gsampler[…] | sampler[…] isampler[…] usampler[…] |
gimage[…] | image]…] iimage[…] uimage[…] |
mat | 所有单精度矩阵类型;mat4, mat2x3,… |
dmat | 所有双精度矩阵类型;dmat4, dmat2x3,… |
2、三角函数
genType radians(genType degrees); // 度转弧度
genType degrees(genType radians); // 弧度转度
genType sin(genType angle); // 三角正弦函数。
genType cos(genType angle); // 三角余弦函数。
genType tan(genType angle); // 三角正切函数。
genType asin(genType x); // 反正弦函数。返回正弦值是x的一个角度值。
// 返回值范围[-pi/2, pi/2],
// 如果x>l或者x<-l,则返回值没定义。
genType acos(genType x); // 反余弦函数。返回余弦值是x的一个角度值。函数返回值的范围是[0, pi]。
//如果x>l或者x<-l,则返回值没定义。
genType atan(genType y, genType x); // 反正切函数。返回的正切值是的一个角度值。
// x 和y的符号用来确定角度在哪个象限内。函数的返回值范围是[-pi, pi]
// 如果x和y的值都是0,则返回值没定义。
genType atan(genType y_over_x); // 反正切函数。返回正切值是y_over_x的一个角度值。
// 函数的返回值范围是[-pi/2, pi/2]
genType sinh(genType x); // 返回双曲线正弦函数(e^x - e^-x)/2
genType cosh(genType x); // 返回双曲线余弦函数(e^x + e^-x)/2
genType tanh(genType x); // 返回双曲线正切函数sinh(x)/cosh(x)
genType asinh(genType x); // 双曲线反正弦函数;返回sinh的逆函数。
genType acosh(genType x); // 双曲线反余弦函数;返回cosh的逆函数。 如果x<1,则返回值没定义。
genType atanh(genType x); // 双曲线反正切函数;返回tanh的逆函数。 如果x>=1或者x<=-1 , 则返回值没定义。
3、指数函数
genType pow(genType x, genType y); // 返回x^y
// 如果x<0返回值没定义。
// 如果x=0和y<=0 , 则返回值没定义。
genType exp(genType x); // 返回x的自然指数幂,即e^x。
genType log(genType x); // 返回x的自然对数,即返回满足等式x=e^y值 。
// 如果x<=0 ,则返回值没定义。
genType exp2(genType x); // 返回2^x
genType log2(genType x); // 返回以2为底x的自然对数,艮U,返回满足等式x=2,值。
// 如果x<=0, 则返回值没定义。
genType sqrt(genType x); // 返回x的开方,如果x<0,没有定义
genDType sqrt(genDType x);
genType inversesqrt(genType x); // 返回开方的倒数,如果x<=0,没有定义
genDType inversesqrt(genDType x);
4、公共函数
genType abs(genType x); // 如果x>=0 , 返回x;否则返回-x。
genIType abs(genIType x);
genDType abs(genDType x);
genType sign(genType x); // 如果x>0,返回1.0
genIType sign(genIType x); // 如果x=0,返回0
genDType sign(genDType x); // 如果x<0,返回-1.0
genType floor(genType x); // 返回小于或等于x的最大整数值。
genDType floor(genDType x);
genType trunc(genType x); // 返回一个最大整数值,它的绝对值是不大于x的绝对值。
genDType trunc(genDType x);
genType round(genType x); // 返回一个最接近x的整数值。分数0.5决定具体设备实现选择四舍五入的方向,
genDType round(genDType x); // 也就是最快速的方向。因此对于任何的x值,round(x)返回的值与roundEven(x)返回的值存在相等的可能。
genType roundEven(genType x); // 返回一个最接近x 的整数值。分数部分是0.5时将四舍五入一个最接近的偶整数值
genDType roundEven(genDType x); // 如x的值是3.5~4.5时,都返回4.0
genType ceil(genType x); // 返回一个大于或等于x的最小整数值。
genDType ceil(genDType x);
genType fract(genType x); // 返回 x = floor(x)
genDType fract(genDType x);
genType mod(genType x, float y); // 取模。返回 x = y x floor(x/y)
genType mod(genType x, genType y);
genDType mod(genDType x, double y);
genDType mod(genDType x, genDType y);
genType modf(genType x, out genType i); // 返回X的小数部分,把整数部分赋予i(数字整体作为浮点数)。返回值部分及输出参数的符号和X的符号一致。
genDType modf(genDType x, out genDType i);
genType min(genType x, genType y); // 如果y<x,则返回y;否则返回x。
genType min(genType x, float y);
genDType min(genDType x, genDType y);
genDType min(genDType x, double y);
genIType min(genIType x, genIType y);
genIType min(genIType x, int y);
genUType min(genUType x, genUType y);
genUType min(genUType x, uint y);
genType max(genType x, genType y); // x<y,则返回y,否则返回x
genType max(genType x, float y);
genDType max(genDType x, genDType y);
genDType max(genDType x, double y);
genIType max(genIType x, genIType y);
genIType max(genIType x, int y);
genUType max(genUType x, genUType y);
genUType max(genUType x, uint y);
genType clamp(genType x, genType minVal, genType max Vai); // 返回min(max(x, minVal), maxVal)。
genType clamp(genType x, float minVal, float maxVal); // 如果minVal>maxVal,那么返回值未定义。
genDType clamp(genDType x, genDType min Vai,genDType max Vai);
genDType clamp(genDType x, double minVal, double max Vai);
genIType clamp(genIType x, genIType minVal, genIType maxVal);
genIType clamp(genIType x, int minVal, int max Vai);
genUType clamp(genUType x, genUType min Vai,genUType max Vai);
genUType clamp(genUType x, uint minVal, uint max Vai);
genType mix(genType x, genType y, genType a); // 返回x和y的线性插值结果,即x(1-a)+ya
genType mix(genType x, geniype y, float a);
genDType mix(genDType x, genDType y, genDType a);
genDType mix(genDType x, genDType y, double a);
genType mix(genType x, genType y, genBType a); //设置返回的分量来自哪个向量。
genDType mix(genDType x, genDType y, genBType a); //如果a的某个分量是false,那么返回对应的x分量。
//如果a的某个分量是true,那么将返回对应的y分量。
// 对于x和y当中没有被选中的分量,也可以是非法的浮点数值,并且不会对结果产生影响。
// 因此我们可以用它来实现一些其他的功能,例如,
genType mix(genType x, genType y, genType(a)) //a是一个布尔向量。
genType step(genType edge, genType x); // 如果x<edge,则返回0.0,否则返回1.0。
genType step(float edge, genType x);
genDType step(genDType edge, genDType x);
genDType step(double edge, genDType x);
genType smoothstep(genType edge0, genType edge1, genType x);
genType smoothstep(float edge0, float edge1, genType x);
genDType smoothstep(genDType edge0, genDType edge1,genDType x);
genDType smoothstep(double edge0, double edge1, genDType x);
// 如果x<=edge0, 则返回0.0,
// 如果x>=edge1, 则返回1.0,
// 并且当edge0 < r < edge1时,执行平滑埃尔米特插值。这在需要有平滑变换的阈函数时有用。等同于下面计算式:
// genType t;
// t = clamp ((x - edge0) / (edge1 - edge0), 0, 1);
// return t * t * (3 - 2 * t);
// (同样对双精度数值适用)如果edge0 >= edge1返回值未定义。
genBType isnan(genType x); // 如果X保存NaN ,则返回true ,否则返回false。如果NaN没实现则一致返回false。
genBType isnan(genDType x);
genBType isinf(genType x); // 如果X是正无穷大或者是负无穷大,则返回true 。否则返回false。
genBType isinf(genDType x);
genIType floatBitsToInt(genType value); // 返回一个表示浮点数编码的有符号或无符号的整型值。用保留浮点数值的位元表示。
genUType floatBitsToUint(genType value);
genType intBitsToFloat(genIType value);
genType uintBitsToFloat(genUType value);
// 返回一个用有符号或无符号整数值编码的浮点数的浮点值。
// 如果传入NaN ,函数不会触发,并且返回值是不明确的。如果传入inf,返回结果也是相应的inf。
genType fma(genType a, genType b, genType c);
genDType fma(genDType a, genDType b, genDType c);
// 计算并且返回a x b + c,在返回值被声明有精度的变量引用的场合下使用。
// fma是单一操作,然而在表达式a x b + c被一个声明为有精度的变量引用时被当做有两个操作。
// fma的精度可能和表达式axb+c的精度不同。
// fma计算出的精度和任何另外一个被精度变量引用fma计算精度一样,对同样的输入a、b 和c的值输出恒定不变的结果。
// 另外,在没有精度引用的情况下,fma和表达式a x b + c在操作次数和精度上没什么特殊限制。
genType frexp(genType x, out genIType exp);
genDType frexp(genDType x, out genIType exp);
// 把x分成浮点值significand,其范围是[0.5, 1.0)和2的整数次幂:significand * 2^exponent
// significand的值由函数返回,exponent的值由函数的参数exp返回。
// 如果结果太大,超出浮点数的范围,那么其结果是未定义的。
// 对一个值为0 的浮点数,对应的significand和exponent的值都是0。
// 对一个值为无限或不是数值的浮点数,其结果是未定义的。
genType ldexp(genType x, in genIType exp);
genDType ldexp(genDType x, in genIType exp);
// 把浮点数x重构成一个significand与2的整数次幂的乘积:significand * 2^exponent
// 如果结果太大超过浮点数范围,那么其结果是未定义的。
5、浮点打包与解包函数
uint packUnorm2x16(vec2 v);
uint packSnorm2x16(vec2 v);
uint packllnorm4x8(vec4 v);
uint packSnorm4x8(vec4 v);
// 首先,把参数v的每个标准化的浮点元素转化成8位或16位的整数值。
// 然后将结果打包成(packed into) 32位无符号整数。
// 参数v的每个元素c转换过程如下:
// packUnorm2xl6: round(clamp(c, 0, +1) * 65535.0)
// packSnorm2xl6: round(clamp(c, -1, +1) * 32767.0)
// packUnorm4x8: round(c1amp(c, 0, +1) * 255.0)
// packSnorm4x8: round(clamp(cz -1, +1) * 127.0)
// 向量v的第一个元素写入结果的最低有效位。以此类推,最后一个元素写入最高有效位。
vec2 unpackUnorm2x16(uint p);
vec2 unpackSnorm2x16(uint p);
vec4 unpackUnorm4x8(umt p);
vec4 unpackSnorm4x8(uint p);
// 首先,把一个32位无符号整数p分解成(unpack)一对16位无符号整数,4个8位无符号整数,或4个8位有符号整数。
// 然后,把每个整数转换成标准化的浮点值来生成,返回向量的2个或4个元素值。
// 把定点数转换成浮点数的过程如下:
// unpackUnorm2xl6: f / 65535.0
// unpackSnorm2xl6: clamp(f / 32767.0, -1, +1)
// unpackUnorm4x8: f / 255.0
// unpackSnorm4x8: clamp(f / 127.0/ -1, +1)
// 返回向量的第一个元素从输入整数值的最低有效位抽取;最后一个元素从最高有效位抽取。
double packDouble2x32(uvec2 v);
// 把向量v的元素打包成64位数值,作为双精度数值返回。
// 如果结果是一个IEEE 754 无限值或NaN,则返回值是没明确的。否则,保存向量v的位标识。
// 向量的第一个元素写入最低的32个有效位;第二个元素写入最高的32个有效位。
uvec2 unpackDouble2x32(double v);
// 返回一个代表双精度数值v的两个元素且元素都是无符号整数的向量。保存v的位标识。
// 向量的第一个元素由双精度数的最低32个有效位构成;第二个元素由最高的32个有效位构成。
uint packHalf2x16(vec2 v);
// 返回一个无符号整数值,该整数值是先把有两个浮点型向量的元素分别转换成由16位浮点表示,
// 然后把这两个16位整数打包(packing)成 32位无符号整数。
// 向量的第一个元素构成返回结果的16个最低有效位;第二个元素构成16个最高有效位。
vec2 unpackHalf2x16(uint v);
// 返回一个有两个元素且元素都是浮点数的向量,该向量的元素把一个32位无符号整数值分解成两个16位整数,
// 由这两个整数生成16位浮点数,并把这两个16位浮点数分别转换成32位浮点数。
// 向量的第一个元素由无符号整数值v的16个最低有效位构成;第二个元素由v的16个最高有效位构成。
6、几何函数
float length(genType x); // 返回向量的长度,
double length(genDType x);
float distance(genType p0, genType p1); // 返回p0和p1之间的距离:length(pO - p1)
double distance(genDType p0, genDType p1);
float dot(genType x, genType y); // 向量点积
double dot(genDType x, genDType y);
vec3 cross(vec3 x, vec3 y); // 向量叉乘
dvec3 cross(dvec3 x, dvec3 y);
genType normalize(genType x); // 归一化:返回与向量方向一致但长度是1的向量。
genDType normalize(genDType x);
genType faceforward(genType N, genType I, genType Nref);
genDType faceforward(genDType N, genDType I,genDType Nref);
// if (dot(Nref, I) < 0.0)
// return N;
// else return -N;
genType reflect(genType I, genType N); // 对于一个向量I及表面法线N , 返回反射方向:I - 2 * dot(N, I) * N
genDType reflect(genDType I, genDType N); // 为了得到想要的结果,N必须先归一化。
genType refract(genType I, genType N, float eta);
genDType refract(genDType I, genDType N, float eta);
// 对于一个向量I及表面法线N,及折射率为eta,返回折射向量,N、I必须是单位向量。用以下程序计算:
k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));
if (k < 0.0)
return genType(0.0); // 或者用 genDType (0.0)
else
return eta * I - (eta * dot(N, I) + sqrt(k)) * N;
7、矩阵函数
单精度浮点版本:参数及返回值都是单精度,
双精度浮点版本:参数及返回值都是双精度。
下面只展示单精度版本。
mat matrixCompMult(mat x, mat y);
// 对于矩阵x及y 进行按分量逐个乘法运算,即
// result[i][j] = x[i][j] * y[i][j];
// x * y则是线性代数中的矩阵乘法。
mat2 outerProduct(vec2 c, vec2 r);
mat3 outerProduct(vec3 c, vec3 r);
mat4 outerProduct(vec4 c, vec4 r);
mat2x3 outerProduct(vec3 c, vec2 r);
mat3x2 outerProduct(vec2 c, vec3 r);
mat2x4 outerProduct(vec4 c, vec2 r);
mat4x2 outerProduct(vec2 c, vec4 r);
mat3x4 outerProduct(vec4 c, vec3 r);
mat4x3 outerProduct(vec3 c, vec4 r);
// 把第一个参数视作列向量(只有一列的矩阵),把第二个参数视作行向量(只有一行的矩阵),
// 对矩阵c及r,进行线性代数相乘c x r , 产生一个行数与c的元素数相同,以及列数与r的元素相同的矩阵。
mat2 transpose(mat2 m);
mat3 transpose(mat3 m);
mat4 transpose(mat4 m);
mat2x3 transpose(mat3x2 m);
mat3x2 transpose(mat2x3 m);
mat2x4 transpose(mat4x2 m);
mat4x2 transpose(mat2x4 m);
mat3x4 transpose(mat4x3 m);
mat4x3 transpose(mat3x4 m);
// 返回m的转置矩阵。输入参数m本身不会改变。
float determinant(mat2 m);
float determinant(mat3 m);
float determinant(mat4 m);
// 返回矩阵秩的行列式的模。
mat2 inverse(mat2 m);
mat3 inverse(mat3 m);
mat4 inverse(mat4 m);
// 返回矩阵m的逆矩阵。输入参数矩阵m本身不会改变。
// 如果m是奇异的或者接近奇异的(poorly-conditioned) , 则返回值未定义。
8、向量关系函数
以下是向量比较函数(用相应的运算操作符对标量进行比较)。
在所有情况下,调用任何函数的输入参数及返回向量的元素大小必须一致。
bvec lessThan(vec x, vec y); // 返回按向量分量逐个进行比较操作x < y的向量。
bvec lessThan(ivec x, ivec y);
bvec lessThan(uvec x, uvec y);
bvec lessThanEqual(vec x, vec y); // 返回按向量分量逐个进行比较操作x <= y 的向量。
bvec lessThanEqual(ivec x, ivec y);
bvec lessThanEqual(uvec x, uvec y);
bvec greaterThan(vec x, vec y); // 返回按向量分量逐个进行比较操作x > y的向量。
bvec greaterThan(ivec x, ivec y);
bvec greaterThan(uvec x, uvec y);
bvec greaterThanEqual(vec x, vec y); // 返回按向量分量逐个进行比较操作x >= y的向量。
bvec greaterThanEqual(ivec x, ivec y);
bvec greaterThanEqual(uvec x, uvec y);
bvec equal(vec x, vec y); // 返回按向量分量逐个进行比较操作x == y的向量。
bvec equal(ivec x, ivec y);
bvec equal(uvec x, uvec y);
bvec equal(bvec x, bvec y);
bvec notEqual(vec x, vec y); // 返回按向量分量逐个进行比较操作x != y的向量。
bvec notEqual(ivec x, ivec y);
bvec notEqual(uvec x, uvec y);
bvec notEqual(bvec x, bvec y);
bool any(bvec x); // 如果向量的任何一个元素的值为true,则返回true
bool all(bvec x); // 如果向量的所有元素的值为true,则返回true
bvec not(bvec x); // 返回对向量X元素逐个进行逻辑补操作后结果的向量。
9、整数函数(位操作)
在这些函数中,记 号 [a, b] 表示从位a 到 b 的位数(包含 a 和 b 位)。最低位是0 位开始。位数(Bit number)是指从最低位数0 开始的位的个数。
genUType uaddCarry(genUType x, genUType y, out genUType carry);
// 把两个32位无符号整数x与y相加,把相加的结果2^32取模作为返回值。如果两数的carry值小于2^32值则置成0 , 否则置成1。
genUType usubBorrow(genUType x, genUType y,out genUType borrow);
// 从x中减去32位无符号整数y,
// 如果差是非负值则返回该差值,否则返回差值与2^32的和。
// 如果x>=y , 则borrow的值设置成0 , 否则设置成1。
void umulExtended(genUType x, genUType y, out genUType msb, out genUType lsb);
void imulExtended(genIType x, genIType y, out genIType msb, out genIType lsb);
// 把整数值x与y相乘,产生一个64位的结果。该结果的32个最低有效位保存在lsb中。32个最高有效位保存在msb中。
genIType bitfieldExtract(genIType value, int offset, int bits);
genUType bitfieldExtract(genUType value, int offset, int bits);
// 从值value中抽取位[offset, offset + bits - 1], 在结果值的最低有效位时返回。
// 对于无符号数据类型,最高有效位设置成0。
// 对于有符号数据类型,最高有效位设置成位offset + bits - 1的值。
// 如果bits的值是0, 那么返回结果是0。
// 如果offset或bits是负值或者offset与bits的和比用来操作的值的位数大,那么返回结果将是未定义的。
genIType bitfieldlnsert(genIType base, genIType insert, int offset,int bits);
genUType bitfieldInsert(genUType base, genUType insert,int offset, int bits);
// 返回插入base中bits个最低有效位后的结果。该结果有从[0, bits- 1]中抽取bits个数位插入
// [offset, offset + bits — 1]中bits个数位,其他所有数位直接从相应的base数位中提取。
// 如果bits的值为0 , 返回结果则是base
// 如果bits的值为负数或者offset及bits两者的和比操作数base的位数量大,返回结果将是未定义的。
genIType bitfieldReverse(genIType value);
genUType bitfieldReverse(genUType value);
// 返回value的位反转后的值。结果位n的值从位(bits - 1) - n 中获取,其中bits是value值的总位数。
genIType bitCount(genIType value);
genIType bitCount(genUType value);
// 返回用二进制表示的value中位的数值为1的个数。
genIType findLSB(genIType value);
genIType findLSB(genUType value);
// 返回用二进制表示的value中最低有效位的数值为1的个数。如果value为 0 , 则返回-1
genIType findMSB(genIType value);
genIType findMSB(genUType value);
// 返回用二进制表示的value中最高有效位的个数。
// 对于正整数,返回最高有效位的数值为1的个数。
// 对于负数,返回最高有效位的数值为0的个数。
// Value为 0 或者是-1, 将返回—1
10、纹理函数
在所有着色阶段纹理查找函数都可用。然而,只在片元着色阶段隐含地计算细节层次,所以OpenGL可以自动进行mipmap过滤。其他着色阶段使用细节层次为0 或者直接使用 没有mipmap化的纹理。如果纹理函数需要隐含导数,那么它们必须在非一致的流程控制外 调用。也就是说,如果它们在流程控制中片元间有变化,则将没有足够的信息正确计算细节层次,这样将产生一个未定义的隐含导数,因此纹理查看函数的返回结果将是未定义的。
在GL中纹理数据可以用单精度浮点数、无符号标准化整数、无符号整数,或有符号整数来存储。这由纹理的内部格式来决定的。在纹理查看过程中无符号标准化整数及浮点数都返回取值范围在[0.0, 1.0] 的浮点数。
根据输入纹理查看函数的sampler的类型,如提供浮点数、无符号整数,或者有符号整 数,纹理查看函数将分别返回相应的类型。使用纹理时一定要仔细选正确的sampler数据类 型。
- 如果sampler是整数类型,那么纹理查看函数的返回值是ivec4。
- 如果sampler是无符号整数类型,那么纹理查看函数的返回值是uvec4
- 如果sampler是浮点数类型,那么纹理查看函数的返回值是vec4每个元素的取值范围是[0,1]
对于阴影形式(sampler参数是阴影类型),需要对绑定到sampler的深度纹理进行深度比较查找。要注意是向量中的哪一个元素表示。
对于阴影形式,以下情况,结果是未定义的:
- 绑定到sampler的纹理不是深度纹理
- 一个非阴影纹理调用了一个sampler,其中sampler表示一个深度纹理且深度比较是打开的
- 一个阴影纹理调用了一个sampler,其中sampler表示一个深度纹理且深度比较是没打开的
- 一个阴影纹理调用了一个sampler,其中sampler不表示一个深度纹理
在这些函数中,片元着色器阶段参数bias是非强制性的。在其他着色阶段不接受参数 biaS。如果在片元着色器中设置参数bias,则在进行纹理存取操作前将它加入隐含细节层次。在矩形纹理、多重采样纹理,或纹理缓冲中不能带参数bias和lod,这是因为在这些纹理类型中不容许有mipmap。对于cubemap形式,P用于2维纹理查找中选定cubemap的那个面。 对于数组形式,对应的数组层是:
对于深度模板纹理,sampler类型必须与通过OpenGL API获取的元素一致。当深度模板纹理设置成DEPTH_ COMPONENT模式时,用浮点型sampler。当深度模板纹理设置成STENCIL_INDEX模式时,用无符号整型sampler。当在纹理查找中使用不支持的组合时, 将返回未定义的值。
纹理查询函数
函数textureSize查询sampler一个特定纹理层次的维度。 函数textureQueryLod只在片元着色器中可用。用输入参数P 的元素来计算层次细节 信息,这些信息在常规的纹理查我中用来获取纹理。在任何LOD偏斜之后获取层次细节,但限制在
[ TEXTURE_MIN_LOD、TEXTURE_MAX_LOD ]之前。同样也把 mipmap 数组计算出来。如果只获取单个层次细节,则返回与初始层相关的层次细节的层数。如果获取多个层次细节,则返回两个层数之间的一个浮点数,该数的小数部分等于经过计算及限制取数范围的层次细节的小数部分。
int textureSize( gsampler1D sampler, int lod );
ivec2 textureSize( gsampler2D sampler, int lod );
ivec3 textureSize( gsampler3D sampler, int lod );
ivec2 textureSize( gsamplerCube sampler, int lod );
int textureSize( samplerlDShadow sampler, int lod );
ivec2 textureSize( sampler2DShadow sampler, int lod );
ivec2 textureSize( samplerCubeShadow sampler, int lod );
ivec3 textureSize( gsamplerCubeArray sampler, int lod );
ivec3 textureSize( samplerCubeArrayShadow sampler, int lod );
ivec2 textureSize( gsampler2DRect sampler );
ivec2 textureSize( sampler2DRectShadow sampler );
ivec2 textureSize( gsamplerlDArray sampler, int lod );
ivec3 textureSize( gsampler2DArray sampler, int lod );
ivec2 textureSize( samplerlDArrayShadow sampler, int lod );
ivec3 textureSize( sampler2DArrayShadow sampler, int lod );
int textureSize( gsamplerBuffer sampler );
ivec2 textureSize( gsampler2DMS sampler );
ivec3 textureSize( gsampler2DMSArray sampler );
// Return the dimensions of level lod (if present) for the texture bound to sampler.
// The components in the return value are filled in, in order, with the width, height,
// and depth of the texture. For the array forms, the last component of the return
// value is the number of layers in the texture array, or the number of cubes
// in the texture cube-map array.
vec2 textureQueryLod( gsamplerlD sampler, float P );
vec2 textureQueryLod( gsampler2D sampler, vec2 P );
vec2 textureQueryLod( gsampler3D sampler, vec3 P );
vec2 textureQueryLod( gsamplerCube sampler, vec3 P );
vec2 textureQueryLod( gsamplerlDArray sampler, float P );
vec2 textureQueryLod( gsampler2DArray sampler, vec2 P );
vec2 textureQueryLod( gsamplerCubeArray sampler, vec3 P );
vec2 textureQueryLod( samplerlDShadow sampler, float P );
vec2 textureQueryLod( sampler2DShadow sampler, vec2 P );
vec2 textureQueryLod( samplerCubeShadow sampler, vec3 P );
vec2 textureQueryLod( samplerlDArrayShadow sampler, float P );
vec2 textureQueryLod( sampler2DArrayShadow sampler, vec2 P );
vec2 textureQueryLod( samplerCubeArrayShadow sampler, vec3 P );
// Return the mipmap array(s) that would be accessed in the x component of the return value.
// Return the computed level of detail relative to the base level in the y component of the return value.
// If called on an incomplete texture, the results are undefined.
int textureQueryLevels( gsamplerlD sampler );
int textureQueryLevels( gsampler2D sampler );
int textureQueryLevels( gsampler3D sampler );
int textureQueryLevels( gsamplerCube sampler );
int textureQueryLevels( gsampler ID Array sampler );
int textureQueryLevels( gsampler2DArray sampler );
int textureQueryLevels( gsamplerCubeArray sampler );
int textureQueryLevels( gsamplerlDShadow sampler );
int textureQueryLevels( gsampler2DShadow sampler );
int textureQueryLevels( gsamplerCubeShadow sampler );
int textureQueryLevels( gsamplerlDArrayShadow sampler );
int textureQueryLevels( gsampler2DArrayShadow sampler );
int textureQueryLevels( gsamplerCubeArrayShadow sampler );
// return the number of mipmap levels accessible in the texture associated with sampler.
// The value zero will be returned if no texture or an incomplete texture is associated with sampler.
// Available in all shader stages.
纹理元素查询函数
gvec4 texture( gsampler1D sampler, float P[, float bias] );
gvec4 texture( gsampler2D sampler, vec2 P[, float bias] );
gvec4 texture( gsampler3D sampler, vec3 P[, float bias] );
gvec4 texture( gsamplerCube sampler, vec3 P[, float bias] );
float texture( sampler1DShadow sampler, vec3 P[, float bias] );
float texture( sampler2DShadow sampler, vec3 P[, float bias] );
float texture( samplerCubeShadow sampler, vec4 P[, float bias] );
gvec4 texture( gsampler1DArray sampler, vec2 P[, float bias] );
gvec4 texture( gsampler2DArray sampler, vec3 P[, float bias] );
gvec4 texture( gsamplerCubeArray sampler, vec4 P[, float bias] );
float texture( sampler1DArrayShadow sampler, vec3 P[, float bias] );
float texture( sampler2DArrayShadow sampler, vec4 P );
gvec4 texture( gsampler2DRect sampler, vec2 P );
float texture( sampler2DRectShadow sampler, vec3 P );
float texture( gsamplerCubeArrayShadow sampler, vec4 P, float compare );
// 用纹理坐标P, 从绑定到sampler当前纹理中作纹理查找。
// 用作阴影形式时:
// 当存在比较操作时,它被用作Dref且层数组来自P.w;
// 当不存在比较操作时,P的最后一个元素用作Dref且层数组来自P的从第二个到最后一个元素(在1D阴影查找中P的第二个元素无用)。
// 对非阴影形式:层数组来自P的最后一个元素。
gvec4 textureProj( gsampler1D sampler, vec2 P[, float bias] );
gvec4 textureProj( gsampler1D sampler, vec4 P[, float bias] );
gvec4 textureProj( gsampler2D sampler, vec3 P[, float bias] );
gvec4 textureProj( gsampler2D sampler, vec4 P[, float bias] );
gvec4 textureProj( gsampler3D sampler, vec4 P[, float bias] );
float textureProj( samplerlDShadow sampler, vec4 P[, float bias] );
float textureProj( sampler2DShadow sampler, vec4 P[, float bias] );
gvec4 textureProj( gsampler2DRect sampler, vec3 P );
gvec4 textureProj( gsampler2DRect sampler, vec4 P );
float textureProj( sampler2DRectShadow sampler, vec4 P );
// 用投射方式进行纹理查找。纹理坐标来自P的元素与最后一个元素相除的结果,纹理坐标不包含P的最后一个元素。
// 在阴影形式中,P元素相除结果的第三个元素用作Dref。计算完这些值后,在纹理中进行纹理查找操作。
gvec4 textureLod( gsamplerlD sampler, float P, float lod );
gvec4 textureLod( gsampler2D sampler, vec2 P, float lod );
gvec4 textureLod( gsampler3D sampler, vec3 P, float lod );
gvec4 textureLod( gsamplerCube sampler, vec3 P, float lod );
float textureLod( sampler1DShadow sampler, vec3 P, float lod );
float textureLod( sampler2DShadow sampler, vec3 P, float lod );
gvec4 textureLod( gsampler1DArray sampler, vec2 P, float lod );
gvec4 textureLod( gsampler2DArray sampler, vec3 P, float lod );
float textureLod( sampler1DArrayShadow sampler, vec3 P, float lod );
gvec4 textureLod( gsamplerCubeArray sampler, vec4 P, float lod );
在纹理中texture以显式层次细节进行纹理查找;lod设定 , 偏导公式如下:
gvec4 textureOffset( gsamplerlD sampler, float P,int offset[, float bias] );
gvec4 textureOffset( gsampler2D sampler, vec2 P, ivec2 offset[, float bias] );
gvec4 textureOffset( gsampler3D sampler, vec3 P, ivec3 offset[, float bias] );
gvec4 textureOffset( gsampler2DRect sampler, vec2 P, ivec2 offset );
float textureOffset( sampler2DRectShadow sampler, vec3 P, ivec2 offset );
float textureOffset( sampler1DShadow sampler, vec3 P, int offset[, float bias] );
float textureOffset( sampler2DShadow sampler, vec3 P, ivec2 offset[, float bias] );
gvec4 textureOffset( gsampler1DArray sampler, vec2 P, int offset[, float bias] );
gvec4 textureOffset( gsampler2DArray sampler, vec3 P, ivec2 offset[, float bias] );
float textureOffset( sampler1DArrayShadow sampler, vec3 P, int offset[, float bias] );
float textureOffset( sampler2DArrayShadow sampler, vec4 P, vec2 offset[, float bias] );
// 在纹理中进行纹理查找前把offset的值加到纹理坐标( u, v, w )中,再进行纹理元素查找。
// Offset的值必须是常数表达式。
// 支持offset的值的范围有限[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
// 注意,offset不适用于纹理数组的层次坐标。
// 注意,offset也不适用于cubemap纹理。
gvec4 texelFetch( gsamplerlD sampler, int P, int lod );
gvec4 texelFetch( gsampler2D sampler, ivec2 P, int lod );
gvec4 texelFetch( gsampler3D sampler, ivec3 P, int lod );
gvec4 texelFetch( gsampler2DRect sampler, ivec2 P );
gvec4 texelFetch( gsampler1DArray sampler, ivec2 P, int lod );
gvec4 texelFetch( gsampIer2DArray sampler, ivec3 P, int lod );
gvec4 texelFetch( gsamplerBuffer sampler, int P );
gvec4 texelFetch( gsampler2DMS sampler, ivec2 P, int sample );
gvec4 texelFetch( gsampler2DMSArray sampler, ivec3 P, int sample );
// 在sampler中用整数纹理坐标查找单个纹理元素。对数组形式,层数组来自p的最后一个元素。
gvec4 texelFetchOffset( gsamplerlD sampler, int P, int lod, int offset );
gvec4 texelFetchOffset( gsampler2D sampler, ivec2 P, int lod, ivec2 offset );
gvec4 texelFetchOffset( gsampler3D sampler, ivec3 P, int lod, ivec3 offset );
gvec4 texelFetchOffset( gsampler2DRect sampler, ivec2 P, ivec2 offset );
gvec4 texelFetchOffset( gsampler1DArray sampler, ivec2 P, int lod, int offset );
gvec4 texelFetch0ffset( gsampler2DArray sampler, ivec3 P, int lod, ivec2 offset );
// 正如在textureOffset中描述那样,用补偿量offset通过texelFetch来获得一个纹理元素。
gvec4 textureProjOffset( gsampler1D sampler, vec2 P, int offset[, float bias] );
gvec4 textureProjOffset( gsampler1D sampler, vec4 P, int offset[, float bias] );
gvec4 textureProjOffset( gsampler2D sampler, vec3 P, ivec2 offset[, float bias] );
gvec4 textureProjOffset( gsampIer2D sampler, vec4 P, ivec2 offset[, float bias] );
gvec4 textureProjOffset( gsampler3D sampler, vec4 P, ivec3 offset[, float bias] );
gvec4 textureProj0ffset( gsampler2DRect sampler, vec3 P, ivec2 offset );
gvec4 textureProjOffset( gsampler2DRect sampler, vec4 P, ivec2 offset );
float textureProjOffset( sampler2DRectShadow sampler, vec4 P, ivec2 offset );
float textureProjOffset( sampler1DShadow sampler, vec4 P, int offset[, float bias] );
float textureProj0ffset( sampler2DShadow sampler, vec4 P, ivec2 offset[, float bias] );
// 正如在textureOffset中描述那样,用补偿量offset通过textureProj以投射纹理查找的模式来获得一个纹理元素。
gvec4 textureLodOffset( gsamplerlD sampler, float P, float lod, int offset );
gvec4 textureLodOffset( gsampler2D sampler, vec2 P, float lod, ivec2 offset );
gvec4 textureLodOffset( gsampler3D sampler, vec3 P, float lod, ivec3 offset );
float textureLodOffset( sampler1DShadow sampler, vec3 P, float lod, int offset );
float textureLodOffset( sampler2DShadow sampler, vec3 P, float lod, ivec2 offset );
gvec4 textureLodOffset( gsampler1DArray sampler, vec2 P, float lod, int offset );
gvec4 textureLodOffset( gsampler2DArray sampler, vec3 P, float lod, ivec2 offset );
float textureLodOffset( sampler1DArrayShadow sampler, vec3 P, float lod, int offset );
// 以显式层次细节方式进行补偿纹理查找。参见 textureLod 和 textureOffset
gvec4 textureProjLod( gsampler1D sampler, vec2 P, float lod );
gvec4 textureProjLod( gsampler1D sampler, vec4 P, float lod );
gvec4 textureProjLod( gsampler2D sampler, vec3 P, float lod );
gvec4 textureProjLod( gsampler2D sampler, vec4 P, float lod );
gvec4 textureProjLod( gsampler3D sampler, vec4 P, float lod );
float textureProjLod( sampler1DShadow sampler, vec4 P, float iod );
float textureProjLod( sampler2DShadow sampler, vec4 P, float lod );
// 以显式层次细节方式进行投射纹理查找。参见 textureProj 和 textureLod
gvec4 textureProjLodOffset( gsampler1D sampler, vec2 P, float lod, int offset );
gvec4 textureProjLodOffset( gsampler1D sampler, vec4 P, float lod, int offset );
gvec4 textureProjLodOffset( gsampler2D sampler, vec3 P, float lod, ivec2 offset );
gvec4 textureProjLodOffset( gsampler2D sampler, vec4 P, float lod, ivec2 offset );
gvec4 textureProjLodOffset( gsampler3D sampler, vec4 P, float lod, ivec3 offset );
float textureProjLodOffset( sampler1DShadow sampler, vec4 P, float lod, int offset );
float textureProjLodOffset( sampler2DShadow sampler, vec4 P, float lod, ivec2 offset );
// 以显式层次细节方式进行补偿投射纹理查找。 参见 textureProj、textureLod 及 textureOffset
gvec4 textureGrad( gsamplerlD sampler, float P, float dPdx, float dPdy );
gvec4 textureGrad( gsampler2D sampler, vec2 P, vec2 dPdx, vec2 dPdy );
gvec4 textureGrad( gsampler3D sampler, vec3 P, vec3 dPdx, vec3 dPdy );
gvec4 textureGrad( gsamplerCube sampler, vec3 P, vec3 dPdx, vec3 dPdy );
gvec4 textureGrad( gsampler2DRect sampler, vec2 P, vec2 dPdx, vec2 dPdy );
float textureGrad( sampler2DRectShadow sampler, vec3 P, vec2 dPdx, vec2 dPdy );
float textureGrad( samplerlDShadow sampler, vec3 P, float dPdx, float dPdy );
float textureGrad( sampler2DShadow sampler, vec3 P, vec2 dPdx, vec2 dPdy );
float textureGrad( samplerCubeShadow sampler, vec4 P, vec3 dPdx, vec3 dPdy );
gvec4 textureGrad( gsamplerlDArray sampler, vec2 P, float dPdx, float dPdy );
gvec4 textureGrad( gsampler2DArray sampler, vec3 P, vec2 dPdx, vec2 dPdy );
float textureGrad( samplerlDArrayShadow sampler, vec3 P, float dPdx, float dPdy );
float textureGrad( sampler2DArrayShadow sampler, vec4 P, vec2 dPdx, vec2 dPdy );
gvec4 textureGrad( gsamplerCubeArray sampler, vec4 P, vec3 dPdx, vec3 dPdy );
以显式渐变方式进行纹理查找。偏导数p与窗口x值及y值有关。 对于1D纹理,公式为:
对于多维纹理,公式为:
对于cubemap纹理版本,偏导数p坐标在相应的立体面投射之前的坐标系中。
gvec4 textureGradOffset( gsampler1D sampler, float P, float dPdx, float dPdy, int offset );
gvec4 textureGradOffset( gsampler2D sampler, vec2 P, vec2 dPdx, vec2 dPdy, ivec2 offset );
gvec4 textureGradOffset( gsampler3D sampler, vec3 P, vec3 dPdx, vec3 dPdy, ivec3 offset );
gvec4 textureGradOffset( gsampler2DRect sampler, vec2 P, vec2 dPdx, vec2 dPdy, ivec2 offset );
float textureGradOffset( sampler2DRectShadow sampler, vec3 P, vec2 dPdx, vec2 dPdy, ivec2 offset );
float textureGradOffset( samplerlDShadow sampler, vec3 P, float dPdx, float dPdy, int offset );
float textureGradOffset( sampler2DShadow sampler, vec3 P, vec2 dPdx, vec2 dPdy, ivec2 offset );
gvec4 textureGradOffset( gsamplerlDArray sampler, vec2 P, float dPdx, float dPdy, int offset );
gvec4 textureGradOffset( gsampler2DArray sampler, vec3 P, vec2 dPdx, vec2 dPdy, ivec2 offset );
float textureGradOffset( sampler1DArrayShadow sampler, vec3 P, float dPdx, float dPdy, int offset );
float textureGradOffset( sampler2DArrayShadow sampler, vec4 P, vec2 dPdx, vec2 dPdy, ivec2 offset );
// 正如在textureGrad和textureOffset描述的一样,以显式渐变量和补偿量方式进行纹理查找。
gvec4 textureProjGrad( gsampler1D sampler, vec2 P, float dPdx, float dPdy );
gvec4 textureProjGrad( gsampler1D sampler, vec4 P, float dPdx, float dPdy );
gvec4 textureProjGrad( gsampler2D sampler, vec3 P, vec2 dPdx, vec2 dPdy );
gvec4 textureProjGrad( gsampler2D sampler, vec4 P, vec2 dPdx, vec2 dPdy );
gvec4 textureProjGrad( gsampler3D sampler, vec4 P, vec3 dPdx, vec3 dPdy );
gvec4 textureProjGrad( gsampler2DRect sampler, vec3 P, vec2 dPdx, vec2 dPdy );
gvec4 textureProjGrad( gsampler2DRect sampler, vec4 P, vec2 dPdx, vec2 dPdy );
float textureProjGrad( sampler2DRectShadow sampler, vec4 P, vec2 dPdx, vec2 dPdy );
float textureProjGrad( samplerlDShadow sampler, vec4 P, float dPdx, float dPdy );
float textureProjGrad( sampler2DShadow sampler, vec4 P, vec2 dPdx, vec2 dPdy );
// 该函数进行与textureProj描述的一样进行投射纹理查找及在textureGrad中进行显式变量纹理查找。
// 假设偏导数dPdx和dPdy都进行了投射变换。
gvec4 textureProjGradOffset( gsamplerlD sampler, vec2 P, float dPdx, float dPdy, int offset );
gvec4 textureProjGradOffset( gsamplerlD sampler, vec4 P, float dPdx, float dPdy, int offset );
gvec4 textureProjGradOffset( gsampler2D sampler, vec3 P, vec2 dPdx, vec2 dPdy, ivec2 offset );
gvec4 textureProjGradOffset( gsampler2D sampler, vec4 P, vec2 dPdx, vec2 dPdy, ivec2 offset );
gvec4 textureProjGradOffset( gsampler2DRect sampler, vec3 P, vec2 dPdx, vec2 dPdy, ivec2 offset );
gvec4 textureProjGradoffset( gsampler2DRect sampler, vec4 P, vec2 dPdx, vec2 dPdy, ivec2 offset );
float textureProjGradOffset( sampler2DRectShadow sampler, vec4 P, vec2 dPdx, vec2 dPdy, ivec2 offset );
gvec4 textureProjGradOffset( gsampler3D sampler, vec4 P, vec3 dPdx, vec3 dPdy, ivec3 offset );
float textureProjGradOffset( sampler1DShadow sampler, vec4 P, float dPdx, float dPdy, int offset );
float textureProjGradOffset( sampler2DShadow sampler, vec4 P, vec2 dPdx, vec2 dPdy, ivec2 offset );
// 该函数进行与textureProjGrad描述的一样以显式渐变量进行投射纹理查找及在textureOffset描述中进行补偿纹理查找。
纹理采集函数
纹理采集函数把一个浮点向量的分量作为纹理坐标,从特定纹理图像的初始层次细节采集四个纹理元素作为样本,并返回有四个分量的向量,其中每个分量存储纹理元素的值。当执行纹理采集函数时,忽略过滤符minification及 magnification, 且 LINEAR的过滤规则作用于从其纹理图像中采集四个纹理元素的初始层。纹理元素先转变成纹理基础颜色,然后进行纹理综合。选取每一个以排序且进行过纹理综合的纹理颜色的分量来组合成一个有四个分量的向量。
对于使用阴影类型的sampler纹理采集函数来说,四个纹理元素每一次查找都执行与 refZ中传入作为深度参照值的深度进行比较,且在返回向量相应的分量中体现比较结果。 对其他纹理查找函数而言,如果在阴影sanpier中引用的纹理不是一个深度纹理或者深度比较没有被enable;或者如果在非阴影sampler中引用的纹理是深度纹理且深度比较被enable,这两种情况下纹理采集函数的结果未定义。
gvec4 textureGather( gsampler2D sampler, vec2 P[, int comp] );
gvec4 textureGather( gsampler2DAiray sampler, vec3 P[, int comp] );
gvec4 textureGather( gsamplerCube sampler, vec3 P[, int comp] );
gvec4 textureGather( gsamplerCubeArray sampler, vec4 P[, int comp] );
gvec4 textureGather( gsampler2DRect sampler, vec2 P[, int comp] );
vec4 textureGather( sampler2DShadow sampler, vec2 P, float refZ );
vec4 textureGather( sampler2DAirayShadow sampler, vec3 P, float refZ );
vec4 textureGather( samplerCubeShadow sampler, vec3 P, float refZ );
vec4 textureGather( samplerCubeArrayShadow sampler, vec4 P, float refZ );
vec4 textureGather( sampler2DRectShadow sampler, vec2 P, float refZ );
// 返回一个vec4, 它的值由下面的四个分量构成:
// Sample i0j1( P, base ).comp
// Sample i1j1( P, base ).comp
// Sample i1j0( P, base ).comp
// Sample i0j0( P, base ).comp
// 如果指定comp的值必须是一个常整数表达式,那么它的值只能是0、1、2, 或者3, 分别代表纹理综合过的纹理查找结果,
// 即有四分量向量的纹理元素的x、y、z 或 w 分量。
// 如果没指定comp, 它被视作0, 并选择每个纹理元素的x分量来产生结果。
gvec4 textureGatherOffset( gsampler2D sampler, vec2 P, ivec2 offset[, int comp] );
gvec4 textureGatherOffset( gsampler2DArray sampler, vec3 P, ivec2 offset[, int comp] );
gvec4 textureGatherOffset( gsampler2DRect sampler, vec2 P, ivec2 offset[, int comp] );
vec4 textureGatherOffset( sampler2DShadow sampler, vec2 P, float refZ, ivec2 offset );
vec4 textureGatherOffset( sampler2DArrayShadow sampler, vec3 P, float refZ, ivec2 offset );
vec4 textureGatherOffset( sampler2DRectShadow sampler, vec2 P, float refZ, ivec2 offset );
// 执行与在textureGather中描述的一样的纹理采集操作,与在textureOffset中描述的一样的补偿纹理操作,
// 只不过offset可以是变量( 非常量 )且offset的最小值与最大值与具体的 OpenGL 实现有关,
// 其中MIN_PROGRAM_TEXTURE_GATHER_OFFSET给出最小值
// 其中MAX_PROGRAM_TEXTURE_GATHER_OFFSET给出最大值。
gvec4 textureGatherOffsets( gsampler2D sampler, vec2 P, ivec2 offsets[4][, int comp] );
gvec4 textureGatherOffsets( gsampler2DArray sampler, vec3 P, ivec2 offsets[4][, int comp] );
gvec4 textureGatherOffsets( gsampler2DRect sampler, vec3 P, ivec2 offsets[4][, int comp] );
vec4 textureGatherOffsets( sampler2DShadow sampler, vec2 P, float refZ, ivec2 offsets[4] );
vec4 textureGatherOffsets( sampler2DArrayShadow sampler, vec3 P, float refZ, ivec2 offsets[4] );
vec4 textureGatherOffsets( sampler2DRectShadow sampler, vec2 P, float refZ, ivec2 offsets[4] );
// 与textureGatherOffset执行同样的操作,只不过offset用来确定样本中四个纹理元素的位置。
// 通过获取补偿集合( offsets )中相应的offset作为( u, v )坐标对p的补偿,确认四纹理元素的线性印迹,
// 从印迹中选择纹理元素iai。。在补偿集合中设定的补偿值必须是常整数表达式。
11、原子计数器函数
原子计数操作相互之间具有原子性。任何一个计数器都具有原子性,意味着在一个着色器实例化过程中对一个特定计数器的操作相对于发生在另一个着色器实例化过程中对同样的计数器的一些操作是不可分割的。这并不能保证对计数器进行其他形式的操作或对孤立的计数器进行序列化时也具有原子性。这种情况下如果想得到具有原子性或序列化的操作,则需增加栅栏(fence)、屏 障 (barrier),或者其他形式的同步方式。原子计 数函数的返回值是原子计数器的值,它可以在原子操作中增加并返回,或者在原子操作中减小并返回,或者仅仅返回原值。计数器的数据类型是32位无符号整数。增加及减小限制在 [0, 232-1]范围内。
uint atomicCounterlncrement(atomic_uint c);
// 自动地
// 1、增加计数器c。
// 2、返回执行增加操作前的值。
// 相对于本表中的atomic-counter函数,这两步操作具有原子性。
uint atomicCounterDecrement(atomic_uint c);
//自动地
//1、减小计数器。
//2、返回执行减小操作前的值。
//相对于本表中的atomic-counter函数,这两步操作具有原子性。
uint atomicCounter(atomic_uint c);
//返回计数器的值c。
12、原子内存函数
原子内存函数对存储在缓冲对象或共享变量中单个有符号或无符号整数进行原子操作。所有原子内存函数操作都是从内存中读取一个值,用以下描述的方法计算出一个新值,把新计算出的值写入内存,并返回原来的值。可以保证在读取原值及写入新值期间,被更新的内存内容不会被任何其他着色器请求赋值及其他原子内存函数更改。原子内存函数仅仅支持有限的变量。如果传入原子内存函数的参数m e m 的值不与缓冲或共享变量中对应,那 么着色器将编译失败。只要数组或向量是缓冲或共享变量类型的,原子内存函数就可以接受数组的一个元素或向量的一个分量作为参数mem 的值。
uint atomicAdd(inout uint mem, uint data); //把data加到mem中得到一个新men值。
int atomicAdd(inout int mem, int data);
uint atomicMin(inout uint mem,uint data); // 从mem中减去data的最小值得到一个新mem值。
int atomicMin(inout int mem,int data);
uint atomicMax(inout uint mem,uint data); // 从mem中减去data的最大值得到一个新mem值。
int atomicMax(inout int mem,int data);
uint atomicAnd(inout uint mem,uint data); // 把data的值和mem进行位与操作,得到一个新mem值。
int atomicAnd(inout int mem,int data);
uint atomicOr(inout uint mem,uint data); // 把data的值和mem进行位或操作,得到一个新mem值。
int atomicOr(inout int mem,int data);
uint atomicXor(inout uint mem,uint data); // 把data的值和mem进行位异或操作,得到一个新mem值。
int atomicXor(inout int mem,int data);
uint atomicExchange(inout uint mem,uint data); // 将data的值拷贝到mem
int atomicExchange(inout int mem,int data);
uint atomicCompSwap(inout uint mem,uint compare,uint data);
int atomicCompSwap(inout int mem, int compare,int data);
// 对比mem与data的值。如果相等,data的值赋予mem;否则,它新值来自于mem原来的内容。
13、图形函数
内置着色图形内存函数用图形基本类型之一的变量来读和写纹理的单个元素。每个图形变量表示一个纹理单元,其附加纹理图像。
当纹理函数访问内存时,标示出在图形中与p 的值对应的坐标(i)、(i,j ) 或 (i,j,k) 位置上的纹理元素。image2DMS和 image2DMSArray变量(对应有符号和无符号整数类型) 与多样本纹理对应,每个纹理元素可以有多个样本且用整数sample参数来表示一个单独样本。装载和储存支持浮点、整数及无符号整数类型。在下面原型中IMAGE_PARAMS是个占位符代表33种的独立函数,每种都代表不同的图形变量类型。占位符IMAGE_PARAMS被以下参数表中之一替代。
- gimagelD image, int P
- gimage2D image, ivec2 P
- gimage3D image, ivec3 P
- gimage2DRect image, ivec2 P
- gimageCube image, ivec3 P
- gimageBuffer image, int P
- gimagelDArray image, ivec2 P
- gimage2DArray image, ivec3 P
- gimageCubeArray image, ivec3 P
- gimage2DMS image, ivec2 P, int sample
- gimage2DMSArray image, ivec3 P, int sample
这里每一行代表三种不同的图形变量、图形p 、以及设定要进行操作的单个纹理元素 的sampleo原子函数对单个纹理元素或图形变量的samples进行原子操作。原子内存操作 读取选择的纹理元素的值,用下面描述的操作进行运算,把计算得到的值写入选择的纹理元素中,并返回读取的初始值。可以保证在读取原值及写入新值期间,被更新的内存内容不会被其他图形存储或其他原子函数更改。
原子函数操作仅仅支持图形变量的子集;图形必须是以下其中之一
- 一个有符号整型图形变量(类型以“ image” 开头)和一个格式修饰符r32i , 用 int 类型数据参数。
- 一个无符号整型图形变量(类型以“ uimage” 开头)和一个格式修饰符r32ui , 用 uint类型数据参数。 ```cpp
int imageSize( gimage1D image ); ivec2 imageSize( gimage2D image ); ivec3 imageSize( gimage3D image ); ivec2 imageSize( gimageCube image ); ivec3 imageSize( gimageCubeArray image ); ivec2 imageSize( gimageRect image ); ivec2 imageSize( gimage1DArray image ); ivec3 imageSize( gimage2DArray image ); int imageSize( gimageBuffer image ); ivec2 imageSize( gimage2DMS image ); ivec3 imageSize( gimage2DMSArray image ); // 返回图形或者绑定到image图形集的大小。 // 对于图形数组,返回值的最后一个分量保存数组的大小。 // 对cubemap图形只返回一个面的大小, // 如果是cubemap图形数组,则返回cubemap的数量。
gvec4 imageLoad( readonly IMAGE PARAMS ); // 从图形单元image( 在IMAGE_PARAMS内 )加载位于坐标p 的纹理元素。 // 对多样本加载,其样本数由sample提供。 // 当图形p 和样本表示一个有效的纹理元素时,选择的纹理元素的位转换成vec4、ivec4, 或 uvec4。
void imageStore( writeonly IMAGE PARAMS, gvec4 data ); // 把数据存储到用image指定的图形中位于坐标p的纹理元素。 // 对多样本存储,其样本数由sample提供。 // 当图形p和样本标示一个有效的纹理元素时,数据的位转换成纹 理单位的格式。
uint imageAtomicAdd( IMAGE PARAMS, uint data ); // 把 data的值加到选定的纹理元素中。 int imageAtomicAdd( IMAGE_PARAMS, int data );
uint imageAtomicMin( IMAGE_PARAMS, uint data ); // 从选择的纹理元素中减去data的最小值得到一个新值。 int imageAtomicMin( IMAGE_PARAMS, int data );
uint imageAtomicMax( IMAGE_PARAMS, uint data ); // 从选择的纹理元素中减去data的最大值得到一个新值。 int imageAtomicMax( IMAGE_PARAMS, int data );
uint imageAtomicAnd( IMAGE_PARAMS, uint data ); // 把data的值和选择的纹理元素进行位与操作,得到一个新值。 int imageAtomicAnd( IMAGE_PARAMS, int data );
uint imageAtomicOr( IMAGE_PARAMS, uint data ); // 把data的值和选择的纹理元素进行位或操作,得到一个新值。 int imageAtomicOr( IMAGE_PARAMS, int data );
uint imageAtomicXor( IMAGE_PARAMS, uint data ); // 把data的值和选择的纹理元素进行位异或操作,得到一个新值。 int imageAtomicXor( IMAGE_PARAMS, int data );
uint imageAtomicExchange(IMAGE_PARAMS,uint data); // 拷贝data的值生成一个新值。 int imageAtomicExchange(IMAGEPARAMS,int data);
uint imageAtomicCompSwap(IMAGE_PARAMS,uint compare,uint data); int imageAtomicCompSwap(IMAGE_PARAMS,int compare,int data); // 对比compart与选定的纹理元素的内容。 // 如果相等,data的值赋予新值;否则,它新值来自于从纹理元素加载的初始值。
<a name="PAsBm"></a>
## 14、片元处理函数
仅在片元着色器中可以使用片元处理函数。
<a name="Ml50z"></a>
### 导数函数
OpenGL通过比较相邻的片元计算表达式的值来实行经典的近似导数。因此,当在非统 一的控制流程中(在着色器中的命令行有条件的前提下执行,其中像素间执行条件有变化),导数将是未定义的。
```cpp
genType dFdx(genType p); // 返回基于相邻片元的值p、x 方向的导数。
genType dFdy(genType p); // 返回基于相邻片元的值p、y 方向的导数。
genType fwidth(genType p); // 返回输入参数p的x方向及y方向的绝对导数的和。 abs(dFdx(p)) + abs(dFdy(p));
插值函数
内置插值函数可用来计算输入着色器指定位置(x, y ) 的数据的插值。一个独立的位置 (x, y) 可以用在内置函数的每次调用中,但这些位置数据可能和用来产生输入的缺省值不同。对所有插值函数,插值必须是一个输入变量或者输入变量为数组的一个元素。设定插值时,不得使用分量来选择操作符(如,.xy)。如果插值声明为flat或 centroid ,那么这个修饰符对插值没有效果。如果声明为noperspective ,那么计算出的插值结果没有进行透视校正。
float interpolateAtCentroid( float interpolant );
vec2 interpolateAtCentroid( vec2 interpolant );
vec3 interpolateAtCentroid( vec3 interpolant );
vec4 interpolateAtCentroid( vec4 interpolant );
// 返回输入插值在处理的像素和图元中位置的采样值。
// 如果声明为centroid, 则获取到的值与输入值一样。
float interpolateAtSample( float interpolant, int sample );
vec2 interpolateAtSample( vec2 interpolant, int sample );
vec3 interpolateAtSample( vec3 interpolant, int sample );
vec4 interpolateAtSample( vec4 interpolant, int sample );
// 返回位于sample编码的样本的输入插值变量的值。
// 如果不存在多样本缓冲,那么输入值是元素中心的估值。
// 如果不存在sample编码的样本,那么用来插值的位置的输入变量将是未定义的。
float interpolateAtOffset( float interpolant, vec2 offset );
vec2 interpolateAtOffset( vec2 interpolant, vec2 offset );
vec3 interpolateAtOffset( vec3 interpolant, vec2 offset );
vec4 interpolateAtOffset( vec4 interpolant, vec2 offset );
// 返回输入插值变量从像素中心开始补偿且补偿量用offset指定的位置的样本值。
// 补偿向量的两个浮点分量给出了x和y方向的补偿量。( 0, 0 )表示像素的中心。
// 本函数支持补偿量的范围和粒度与OpenGL具体实现有关。
15、噪声函数
可移植性声明:内置噪声函数在平台间是不可移植的。在你关心的平台上确认其支持程度及表现。
噪声函数用来增加视觉复杂度。下面的噪声函数返回值能给出一个随机的表现但其结果并不随机。相反,对同样的输入值他们给出同样的结果,容许对同样的变量在片元间再现同样的结果。
下面定义的噪声函数有以下特性:
- 返回值始终在[-1.0, 1.0] 范围内,对于类高斯分布其范围至少是[-0.6, 0.6]
- 返回值的总平均数是0.0。
- 他们是可重现的,一个特定的输入值总是产生相同的结果。
- 不论怎么变换它们都有统计恒定性(无论域怎么变换,它都有相同的统计特征)。
- 变换后它们给出不同的结果。
- 空间频率相对集中,集中在0.5 ~ 1.0
- 无论在那都是C1连续的(即,第一导数是连续的)。 ```cpp
float noise1(genType x); // 返回基于值x 的 1维噪声。 vec2 noise2(genType x); // 返回基于值x 的2维噪声。 vec3 noise3(genType x); // 返回基于值x 的3维噪声。 vec4 noise4(genType x); // 返回基于值x 的四维噪声。
<a name="3zKhM"></a>
## 16、几何着色器函数
几何着色器函数只在几何着色器中可用,用来管理在该着色阶段创建的数据流。<br />函数**EmitStreamVertex**指定已完成的一个顶点。通过和流有关的输出值的当前值把一个顶点加入顶点流stream的当前输出图元。这包含gl_PointSize、gl_ClipDistance] 、gl_ Layer、gl_Position、gl_PrimitivelD和gl_ViewportIndex() 在调用 **EmitStreamVertex**之后,所有输出流的所有输出变量的值都是未定义的。如果一个集合着色器请求中提交了比在输出布局中规定的最大值max_vertices更多的顶点,那么函数EmitStreamVertex的调用结果将是未定义的。<br />函数**EndStreamPrimitive**指定顶点流stream的当前输出图元已完成,随后的任何一个 EmitStreamVertex函数开始一个新的输出图元(对相同的类型)。这个函数并不提交一个顶点。如果输出布局中声明为“ points” , 那 么 EndStreamPrimitive调用是任意的(可有可无的)。<br />对每个流,几何着色器开始时的输出图元不包含顶点。当一个几何着色器结束时,每个流的当前输出图元将自动结束。如果几何着色器仅写一个图元,那么调用**EndStreamPrimitive**函数是非必要的。<br />如果输出图元类型声明为points,则支持多输出流。<br />如果输出图元类型不是points,且程序中包含函数**EmitStreamVertex**调用或者函数**EndStreamPrimitive**调用,那么程序链<br />接将失败。
```cpp
void EmitStreamVertex(int stream);
// 将输出变量的当前值提交到流stream中当前输出图元。流的参数必须是常整数表达式。
// 当从函数调用返回时,所有输出变量的值是未定义的。
// 仅当支持多输出流可用。
void EndStreamPrimitive(int stream);
// 在流stream中结束当前输出图元。流的参数必须是常整数表达式。
// 不提交顶点。
// 仅当支持多输出流可用。
void EmitVertexO;
// 将输出变量的当前值提交到当前输出图元。当从函数调用返回时,所有输出变量的
// 值是未定义的。当支持多输出流时,这与调用函数EmitStreamVertex(0)一样。
void EndPrimitive();
// 结束当前输出图元,开始一个新的图元。不提交顶点。
// 当支持多输出流时,与调用函数EndStreamPrimitive(0)一样。
17、着色器请求控制函数
着色器请求控制函数仅在细分控制着色器和计算着色器中可用。它用来控制着色器请求执行顺序,这些着色器请求用来处理patch (在细分控制着色器中)或者局部工作组(在 计算着色器中),否则将以一种未知的顺序执行。
void barrier();
// 对于barrier任何一个静态实例,在其之外的容许的程序执行之前,
// 对于一个输入 patch,所有的细分控制器调用必须进入其中,或者对于一个工作组必须进入其中。
函数barrier提供定义在着色器请求之间执行顺序的一部分。这可以确保着色调用在一 个给定的静态实例barrier之前的写入值可以在同样的静态实例执行后安全的读取出来。因 为着色调用可以在这些barrier间执行,这是因为没有明确的顺序执行,在一些情况下输出的 per-vertex、per-patch的值或者计算着色器的共享变量将是不明确的。 函数barrier只能放在细分控制着色器的main函数内部,且不能在任何控制流中调用。函数Barrier同样不 容许在主函数main返回之后调用。任何错误放置将导致程序编译错误。
18、着色器内存控制函数
所有类型的着色器可以通过图形变量来读写纹理和缓冲对象的内容。在单个着色器请求中读写的顺序是明确的,但多个独立的着色器请求对于一个共享内存的读写的相对顺序来说,大部分都是不明确的。一个着色器请求执行内存存取的顺序,是其他着色器请求应该遵守的顺序,然而对于其他大部分着色调用来说也是不明确的,但可以用内存控制函数来控制。
void memoryBarrier(); // 控制单个着色调用发起的内控事务的顺序。
void memoryBarrierAtomicCounter(); // 控制单个着色调用发起的读写原子计数器的顺序。
void memoryBarrierBuffer(); // 控制单个着色调用发起的缓冲变量内控事务的顺序。
void memoryBarrierShared(); // 控制单个着色调用发起的共享变量内控事务的顺序。仅在计算着色器中可用。
void memoryBarrierlmage(); // 控制单个着色调用发起的图形内控事务的顺序。
void groupMemoryBarrier();
// 控制单个着色调用发起的图形内控事务的顺序,在同工作组中的其他着色调用可查。仅在计算着色器中可用
三、内置变量解释
1、gl_ClipDistance[]
提供了控制用户裁剪的机制。元素gl_ClipDistance[i]指定每个平面的裁剪距离。距离为0意味着顶点在这个平面上,距离为正说明这个点位于裁剪平面内,而距离为负说明这个点位于裁剪平面外。这个输出的裁剪距离将和图元进行线性插值,插值距离小于0 ,则图元部分将剪切掉。
gl_ClipDistance[]事先声明为没指定长度的数组并且必须在着色器中重新声明长度或者用整常数表达式索引。数组的长度必须包含所有通过OPENGL API enable 的裁剪平面总数。如果数组的长度不能包含所有的enabled的裁剪平面,那么程序结果是不明确的。数组长度最大可以是gl_MaxClipDistances。不管多少裁剪平面被enabled,在 gl_ClipDistance[]用到的变化元素(gl MaxVaryingComponents)的大小必须和数组大小一致。OPENGL API enable的裁剪平面在着色器中必须设置为gl_ClipDistance[]中的所有元素值,否则运行结果不明确。设置没有enabled的裁剪平面对应gl_ClipDistance[]的元素值没有作用。
作为输出型变量,gl_ClipDistance[]为着色器提供设置这些距离值的场所。在除了片元 着色器以外的着色器中作为输入型变量时,它读入上一个着色器写入的值。在片元着色器中,gl_ClipDistance[]数组包含一些这样数值,这些数值由一个着色器把顶点线性插值写入 gl_ClipDistance[]中并作为输出型值。只有 enable的裁剪平面才在这个数组元素有明确的值。
2、gl_DepthRange
结构gl_DepthRange包含视口 0 的近裁剪面和远裁剪面的位置。这些数值是在窗口坐标系下的。结构的成员diff是 far与 near的差far - near。
3、gl_FragCoord
在片元中通过固定功能计算的深度数值(depth)可以用gl_FragCoord.z来获取。
输入片元着色器中的gl_FragCoord变量保存当前片元的窗口坐标(x,y,z, 1/w)的数值。 如果是多重采样模式,那么这个值可以位于像素内的任何位置。导致这个结果的原因是:在顶点处理后用固定功能给产生片元插值图元。如果没有着色器写入gl_FragDepth, 那么gl_FragCoord.z可以用作片元的深度值。这对有恒定性深度值需求情形下有作用:如 果一个着色器在一定条件下计算gl_FragDepth的值,而后来又需要固定功能的片元深度值。
4、gl_FragDepth
在片元着色器中写入gl_FragDepth来建立被处理片元的深度值。如果enable深度缓冲, 并且没有着色器写入gl_FragDepth,那么固定功能计算的深度值就作为片元的深度值。如果一个着色器在片元阶段的任何地方对gl_FragDepth赋值,同时在这个着色器中存在一个执行路径没有设置gl_FragDepth的值,那么在执行没有赋值的路径时片元的深度值有可能不明确。所以如果在任何地方写入了它的值,那么务必在执行路径中都写入它的值。
5、gl_FrontFacing
片元着色器可以读输入型的内置变量gl_FrontFacing,如果片元属于面朝前的图元,那 么它的值是true。选择通过顶点或几何着色器计算出的两种颜色中的其中之一来模拟双面光照是其用法之一。
6、gl_GloballnvocationlD
计算着色器中输入型变量gl_GlobalInvocationID包含当前工作项的全局索引。它的值指定了由当前glDispatchCompute调用发起运算过程中局部与全局工作组的中唯一一个调用(Invocation )。用以下公式计算:
gl_GlobalInvocationID = gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID;
7、gl_InstancelD
顶点着色器中输入变量glInstancelD保存在实例化绘图命令中的当前图元的实例索引。 如果当前图元不来自实例化绘图命令,那么glInstancelD的值为0。
8、gl_InvocationID
在细分控制着色器和几何着色器中可以读取glJnvocationlD的值。在细分控制着色器 中,它代表为细分控制着色器请求(Invocation)分配的输出patch顶点数。在几何着色器 中,它代表为几何着色器请求(Invocation)分配的调用( Invocation)值。在这两种情况下glJnvocationlD的取值范围是[0, N - 1],N是输出patch顶点数量或每个图元几何着色器的调用(Invocation)数量。
9、gl_Layer
变量gl_Layer从几何着色器中输出,并输入片元着色器中。在几何着色器中它用来选 定多层级帧缓冲中附属一个特定的层级(或者是cubemap中的面和层级)。实际的层级来自着色图元顶点中的一个顶点。当从来自顶点的层级不明确时,最好把图元所有顶点的层级值设置成一样。如果在任何几何着色器中设置了gl_Layer值,那么会enable层级渲染模式。 一旦enable了该模式,如果着色器存在一个执行路径没有设置gl.Layer的值,那么程序结果不明确。所以你要确保着色器中所有路径中都设置了它的值。
在用作cubemap纹理数组时输出变量gl_Layer有特殊的值。它不仅代表层级的值,还用来选择cubemap纹理中的面和层级。把 glLayer的值设置成, 渲染在层级中定义的cubemap的面face。面的取值如下表所示:
面的值 | 面的目标 |
---|---|
0 | TEXTURE_CUBE_MAP_POS1TIVE_X |
1 | TEXTURE_CUBE_MAP_NEGATIVE_X |
2 | TEXTURE_CUBE_MAP_POS1TIVE_Y |
3 | TEXTURE_CUBE_MAP_NEGATIVE_Y |
4 | TEXTURE_CUBE_MAP_POSITIVE_Z |
5 | TEXTURE_CUBE_MAP_NEGATIVE_Z |
举例,要渲染cubemap第5层级y正方向的面,把 glLayer的值设置成5 x 6 + 2 即可。
输入片元着色器gl_Layer的值和从几何着色器写入并输出的gl Layer的值相等。如果在几何着色器阶段没有着色器对gl_Layer动态赋值,那么在片元着色器中gl_Layer的值不明确。如果在几何着色器阶段没有对所有gl_Layer赋值,那么在片元着色器中输入变量gl Layer的值为0。否则,片元着色阶段将读取与几何着色阶段写入相同的值,即使该值已经溢出。如果片元着色器用到gl_Layer,它应该计算在片元着色阶段OpenGl具体实现定义的最大输入值之内。
10、gl_LocallnvocationlD
在计算着色器中输入变量glLocallnvocationlD, 它包括当前调用正在执行全局工作组 中里局部工作组的t维索引。它的取值范围是:
11、gl_Locallnvocationlndex
在计算着色器中输入的变量gl_Locallnvocationlndex是 gl_LocallnvocationlD的1维表示。它用来区分本次调用使用的在局部工作中唯一的共享内存区域。用如下公式计算:
gl_LocalInvocationindex =
gl_LocalInvocationID.z * gl_WorkGroupSize.x * gl_WorkGroupSize.y +
gl_LocalInvocationID.y * gl_WorkGroupSize.x + gl_LocalInvocationID.x;
12、gl_NumSamples
在使用多样本帧缓冲时,所有阶段中输入型uniform gl_NumSamples变量包含帧缓冲中所有样本的总数。当用作非多样本帧缓冲时,gl_NumSamples的值是1。
13、gl_NumWorkGroups
在计算着色器中输入的变量gl_NumWorkGroups包含运行计算着色器的每个工作组的全局工作项的总数。它的内容等于在glDispatchCompute API调用入口中设置的参数num_groups_x、num_groups_y、num_groups_z。
14、gl_PatchVerticesIn
细分着色器可以读取gl_PatchVerticesIn的值。它是个整型值,设置着色器要处理输入 patch的顶点个数。一个细分控制着色器或者细分估值着色器可以读取不同大小的patch,所以gl_PatchVertices!n的值可以在不同的patch间有变化。
15、glPointCoord
当点图形(point Sprites)被enable时,gl_PointCoord的 2 维坐标值表示当前片元在点图元中的位置。它们的取值范围是从0.0 ~ 1.0。如果当前图元不是点,或者点图形没有 enable时,从 gl PointCoord读取的值将是不明确的。
16、gl_PointSize
作为输出变量,gl_PointSize是着色器用来控制被栅格化点的大小。它是用像素来衡量 的。如果gl_PointSize没有赋值,那么在随后的着色阶段它的值将是没明确的。作为输入 值,读取在前着色器阶段写入的值作为gl_PointSize的值。
17、gl_Position
作为输出变量,gl_Position用来保存顶点位置的齐次坐标。该值用作图元装配、裁剪、筛选,以及其他固定功能操作,如果可能,在顶点处理后对图元进行处理。如果在顶点着色器执行过程中没有对gl_Position赋值,那么在顶点处理阶段以后它的值是不明确的,同样,如果从上一次调用EmitVertex后几何着色器调用了 EmitVertex而没有对gl Position赋值(或者根本没有对它赋值)也是如此。作为输入变量,读取前着色器阶段写入的值作为gl Position 的值。
18、gl_PrimitiveID
将几何着色器输出整数型gl_PrimitiveID变量作为图元的标识符。然后作为片元输入 gl_PrimitivelD在片元着色器中可用,选择将触发顶点所在着色图元的ID写入图元ID。如 果片元着色器用到的gl_PrimitiveID是有效的,并且几何着色器也是有效的,那么几何着色器必须对gl_PrimitiveID赋值,否则输入片元着色器中的gl_PrimitiveID值是不明确的。
对于细分着色器和细分估值着色器来说,输入变量gl_PrimitiveID的值是着色器从一组 当前渲染图元开始以来一共处理图元的个数。如果有几何着色器,在片元着色器中,它读取几何着色器赋予gl_PrimitiveID的值,并作为输出值。否则,它采取和在细分控制着色器 和细分估值着色器中一样的方式来赋值。
19、gl_PrimitivelDIn
几何着色器输入变量gl_PrimitiveIDIn等同于细分控制着色器和细分估值着色器输入变量 gl_PrimitivelD,在上面已做过描述。
20、gl_SamplelD
在片元着色器中输入变量gl_SampleID的值是当前处理的样本数量。它的取值范围是0 到 gl_NumSamples-1, 其中gl_NumSamples是在帧缓冲中样本的总数,或者在非多样本渲染帧缓冲中其值为1。使用这个变量的片元着色器,而这个着色器则评估为每样本(persample) 。
21、gl_SampleMask
片元输出数组gl_SampleMask[]为被处理片元设置样本掩码。掩码的数值和输出变量 gl_SampleMask逻辑与的结果作为当前片元的数值。这个数组的大小可以通过隐式或显式 设置,且必须和上面描述的大小一致。
如果任何片元着色器对gl_SampleMask变量赋值,但任何片元着色请求对任一数组元素赋值失败,那么这个样本掩码将是不明确的。如果没有着色器对gl_SampleMask赋值, 那么在片元处理过程中样本掩码没有作用。
掩码gl_SampleMask[M]位 B 与样本32 x M +B 对应。有 (s/32 )(取顶值)个数组元素,s 是在系统所支持的最大彩色样本数量。
22、gl_SampIeMaskln
片元着色器输入变量gl_SampleMaskIn代表在多样本栅格化过程中,由图元生成片元 掩码的一组样本。如果样本覆盖了片元着色器请求,那么它就生成一个样本位。
掩码gl_SampleMask[M]位 B 与样本32 x M +B 对应。有 (s/32)(取顶值)个数组元素,s 是在系统所支持的最大彩色样本数量。
23、gl_SamplePosition
片元着色器输入变量glSamplePosition表示在多样本绘图缓冲中当前样本的位置。gl SamplePosition的 x 及 y 部分包含当前样本的子像素坐标,取值范围是0.0 ~ 1.0。如果在 任何片元着色器中使用这个变量,则整个片元阶段评估为每样本(per sample)。
24、gl_TessCoord
变量gl_TessCoord只在细分估值着色器中可用。它是有三个分量( u,v,w)的向量代表 与图元细分相关的被处理顶点的位置。它的值用以下特性来协助拷贝细分算法。
gl_TessCoord.x == 1.0 - (1.0 - gl_TessCoord.x)
gl_TessCoord.y == 1.0 - (1.0 - gl_TessCoord.y)
gl_TessCoord.z == 1.0 - (1.0 - gl_TessCoord.z)
25、gl_TessLevelOuter、gl_TessLevelOuter
输入变量gl_TessLevelOuter和 gl_TessLevelOuter只在细分估值着色器中可用。如果细分控制着色器有效,那么这些值在细分控制着色器中作为输出变量被赋值。否则它们被赋予缺省的细分层次。
输出变量gl_TessLevelOuter和 gl_TessLevelOuter只在细分控制着色器中可用。写入变量的这些值,用来控制输出patch相应的外部和内部细分层次。它们被细分图元生成器用来 控制图元细分,也可以在细分估值着色器中获取。
26、gl_ViewportID
在顶点着色器输入变量gl_VertexID保存顶点的整数索引。虽然变量gl_VertexID一直存在,但是它的值不是一直都有定义。
27、gl_ViewportIndex
在几何着色器中作为输出的变量在片元着色器中作为输入变量。在几何着色器中,它提供几何着色器绘制下一个图元的视口索引。几何着色器生成的图元要经过视口变换,用视口变换和gl_ViewPortIndex的值选择的裁剪矩形来进行裁剪测试。视口索引来 自着色的图元中的一个顶点。然而视口索引来自哪个顶点是由OpenGL具体实现来决定的,所以最好在一个图元里的所有顶点用同样的视口索引。如果在几何着色器中没有对 gl_ViewportIndex赋值,那么将使用视口变换及裁剪矩形0。如果几何着色器对gl_Viewportindex赋值,以及几何着色阶段存在一个路径没有对gl Viewportlndex进行赋值,那么如果有着色器执行了这个路径,那么gl_ViewportIndex的值是不明确的。
在片元着色器中作为输入变量,gl_ViewportIndex的值与在几何着色阶段写入的输 出值相同。在几何着色阶段没有动态对gl_ViewportIndex赋值,那么在片元着色器中gl_Viewportindex的值将是不明确的。如果几何着色阶段没有对gl_ViewportIndex赋值,那么在片元着色阶段读取的值为0。否则,不管gl_ViewportIndex是否超出了范围,将在片元着 色阶段读取与在几何着色阶段写入的同样的值。如果在片元着色器中存取gl Viewportindex 的值,那么它将计算在由。penGL具体实现定义的、片元着色阶段最多能输入的变量的数 值内。
28、gl_WorkGroupSize
内置常数gl_WorkGroupSize在计算着色器中用来指定着色器的局部工作组的大小。工作组的x、y、z 维度的大小分别保存在x、y 及 z 部分。保存在gl WorkGroupSize的值与在当前着色器布局( layout)修饰设定的local_size_x、local_size_y及 local_size_z的值—致。该值是常量,可以用在局部工作组中指示内存数组的大小,且可以在局部工作组中共享。
29、gl_WorkGroupID
计算着色器中输入变量gl_WorkGro叩ID是当前执行调用( invocation)所在的全局工作 组 3 维索引。作为调用glDispatchCompute函数的输入参数,取值范围是:
(0, 0, 0)到(gl_NumWorkGroups.x - 1, gl_NumWorkGroups.y - 1, gl_NumWorkGroups.z - 1)