WebGL 1.0基于OpenGL ES 2.0(Shading 1.0)是现在浏览器的主流版本
Specifications
Specification | Status | Comment |
---|---|---|
WebGL 1.0 | Recommendation | Initial definition. Based on OpenGL ES 2.0 |
WebGL 2.0 | Editor's Draft | Builds on top of WebGL 1. Based on OpenGL ES 3.0. |
OpenGL ES 2.0 | Standard | |
OpenGL ES 3.0 | Standard |
矩阵(列矩阵,每列是一个vector)
5.6 Matrix Components
The components of a matrix can be accessed using array subscripting syntax. Applying a single subscript
to a matrix treats the matrix as an array of column vectors, and selects a single column, whose type is a
vector of the same size as the matrix. The leftmost column is column 0. A second subscript would then
operate on the column vector, as defined earlier for vectors. Hence, two subscripts select a column and
then a row.
mat4 m;
m[1] = vec4(2.0); // sets the second column to all 2.0
m[0][0] = 1.0; // sets the upper left element to 1.0
m[2][3] = 2.0; // sets the 4th element of the third column to 2.0
The behavior when accessing a component outside the bounds of a matrix are the same as those for
vectors and arrays. The compiler must generate an error if the index expression is a constant expression
but the behavior is undefined for non-constant expression. (e.g., component [3][3] of a mat3 must
generate a compile-time error).
下面是矩阵, 向量操作的介绍
5.11 Vector and Matrix Operations
With a few exceptions, operations are component-wise. When an operator operates on a vector or matrix,
it is operating independently on each component of the vector or matrix, in a component-wise fashion.
For example,
vec3 v, u;
float f;
v = u + f;
will be equivalent to:
v.x = u.x + f;
v.y = u.y + f;
v.z = u.z + f;
And
vec3 v, u, w;
w = v + u;
will be equivalent to:
w.x = v.x + u.x;
w.y = v.y + u.y;
w.z = v.z + u.z;
and likewise for most operators and all integer and floating point vector and matrix types. The exceptions
are matrix multiplied by vector, vector multiplied by matrix, and matrix multiplied by matrix. These do
not operate component-wise, but rather perform the correct linear algebraic multiply. They require the
size of the operands match.
vec3 v, u;
mat3 m;
u = v * m;
is equivalent to
u.x = dot(v, m[0]); // m[0] is the left column of m
u.y = dot(v, m[1]); // dot(a,b) is the inner (dot) product of a and b
u.z = dot(v, m[2]);
And
u = m * v;
is equivalent to
u.x = m[0].x * v.x + m[1].x * v.y + m[2].x * v.z;
u.y = m[0].y * v.x + m[1].y * v.y + m[2].y * v.z;
u.z = m[0].z * v.x + m[1].z * v.y + m[2].z * v.z;
And
mat m, n, r;
r = m * n;
is equivalent to
r[0].x = m[0].x * n[0].x + m[1].x * n[0].y + m[2].x * n[0].z;
r[1].x = m[0].x * n[1].x + m[1].x * n[1].y + m[2].x * n[1].z;
r[2].x = m[0].x * n[2].x + m[1].x * n[2].y + m[2].x * n[2].z;
r[0].y = m[0].y * n[0].x + m[1].y * n[0].y + m[2].y * n[0].z;
r[1].y = m[0].y * n[1].x + m[1].y * n[1].y + m[2].y * n[1].z;
r[2].y = m[0].y * n[2].x + m[1].y * n[2].y + m[2].y * n[2].z;
r[0].z = m[0].z * n[0].x + m[1].z * n[0].y + m[2].z * n[0].z;
r[1].z = m[0].z * n[1].x + m[1].z * n[1].y + m[2].z * n[1].z;
r[2].z = m[0].z * n[2].x + m[1].z * n[2].y + m[2].z * n[2].z;
and similarly for vectors and matrices of size 2 and 4.
All unary operations work component-wise on their operands. For binary arithmetic operations, if the two
operands are the same type, then the operation is done component-wise and produces a result that is the
same type as the operands. If one operand is a scalar float and the other operand is a vector or matrix,
then the operation proceeds as if the scalar value was replicated to form a matching vector or matrix
寄存器变量的布局方式,大小限制
7 Counting of Varyings and Uniforms
GLSL ES 1.00 specifies the storage available for varying variables in terms of an array of 4-vectors.
Similarly for uniform variables. The assumption is that variables will be packed into these arrays without
wasting space. This places significant burden on implementations since optimal packing is
computationally intensive. Implementations may have more internal resources than exposed to the
application and so avoid the need to perform packing but this is also considered an expensive solution.
ES 2.0 therefore relaxes the requirements for packing by specifying a simpler algorithm that may be used.
This algorithm specifies a minimum requirement for when a set of variables must be supported by an
implementation. The implementation is allowed to support more than the minimum and so may use a more
efficient algorithm and/or may support more registers than the virtual target machine.
In all cases, failing resource allocation for variables must result in an error.
The resource allocation of variables must succeed for all cases where the following packing algorithm
succeeds:
• The target architecture consists of a grid of registers, 8 rows by 4 columns for varying variables
and 128 rows by 4 columns for uniform variables. Each register can contain a float value.
• Variables are packed into the registers one at a time so that they each occupy a contiguous sub-
rectangle. No splitting of variables is permitted.
• The orientation of variables is fixed. Vectors always occupy registers in a single row. Elements
of an array must be in different rows. E.g. vec4 will always occupy one row; float[8] will occupy
one column. Since it is not permitted to split a variable, large arrays e.g.. for varyings, float[16]
will always fail with this algorithm.
• Variables consume only the minimum space required with the exception that mat2 occupies 2
complete rows. This is to allow implementations more flexibility in how variables are stored.
• Arrays of size N are assumed to take N times the size of the base type.
• Variables are packed in the following order:
1. Arrays of mat4 and mat4
2. Arrays of mat2 and mat2 (since they occupy full rows)
3. Arrays of vec4 and vec4
4. Arrays of mat3 and mat3
5. Arrays of vec3 and vec3
6. Arrays of vec2 and vec2
7. Arrays of float and float
• For each of the above types, the arrays are processed in order of size, largest first. Arrays of size
1 and the base type are considered equivalent. In the case of varyings, the first type to be packed
(successfully) is mat4[2] followed by mat4, mat2[2], mat2, vec4[8], ve4[7],...vec4[1], vec4,
mat3[2], mat3 and so on. The last variables to be packed will be float (and float[1]).
Version 1.00 Revision 17 (12 May, 2009)
Appendix A: Limitations for ES 2.0 112
• For 2,3 and 4 component variables packing is started using the 1st column of the 1st row.
Variables are then allocated to successive rows, aligning them to the 1st column.
• For 2 component variables, when there are no spare rows, the strategy is switched to using the
highest numbered row and the lowest numbered column where the variable will fit. (In practice,
this means they will be aligned to the x or z component.) Packing of any further 3 or 4
component variables will fail at this point.
• 1 component variables (i.e. floats and arrays of floats) have their own packing rule. They are
packed in order of size, largest first. Each variable is placed in the column that leaves the least
amount of space in the column and aligned to the lowest available rows within that column.
During this phase of packing, space will be available in up to 4 columns. The space within each
column is always contiguous.
• If at any time the packing of a variable fails, the compiler or linker must report an error.
Example: pack the following types:
varying vec4 a; // top left
varying mat3 b; // align to left, lowest numbered rows
varying vec2 c[3]; // align to left, lowest numbered rows
varying vec2 d[2]; // Cannot align to left so align to z column, highest
// numbered rows
varying vec2 e; // Align to left, lowest numbered rows.
varying float f[3] // Column with minimum space
varying float g[2]; // Column with minimum space (choice of 2, either one
// can be used)
varying float h; // Column with minimum space
In this example, the varyings happen to be listed in the order in which they are packed. Packing is
independent of the order of declaration.
x y z w
0 a a a a
1 b b b f
2 b b b f
3 b b b f
4 c c g h
5 c c g
6 c c d d
7 e e d d
Some varyings e.g. mat4[8] will be too large to fit. These always fail with this algorithm.
Version 1.00 Revision 17 (12 May, 2009)
Appendix A: Limitations for ES 2.0 113
If referenced in the fragment shader (after preprocessing), the built-in special variables (gl_FragCoord,
gl_FrontFacing and gl_PointCoord) are included when calculating the storage requirements of varyings.
Only varyings statically used in both shaders are counted.
When calculating the number of uniform variables used, any literal constants present in the shader source
after preprocessing are included when calculating the storage requirements. Multiple instances of
identical constants should count multiple times.
Part of the storage may be reserved by an implementation for its own use e.g. for computation of
transcendental functions. This reduces the number of uniforms available to the shader. The size of this
reduction is undefined but should be minimized.
8 Shader Parameters
The following are the minimum values that must be supported by an ES 2.0 implementation:
const mediump int gl_MaxVertexAttribs = 8;
const mediump int gl_MaxVertexUniformVectors = 128;
const mediump int gl_MaxVaryingVectors = 8;
const mediump int gl_MaxVertexTextureImageUnits = 0;
const mediump int gl_MaxCombinedTextureImageUnits = 8;
const mediump int gl_MaxTextureImageUnits = 8;
const mediump int gl_MaxFragmentUniformVectors = 16;
const mediump int gl_MaxDrawBuffers = 1;
可以查询存储器的大小,我用浏览器测出来是253, 16, 也就是最大63个mat4。(或者是最大63跟骨骼,还要排除其它参数)
var maxVerUni = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS); //测试是253,规范最少128
var maxVerAtt = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);//16
变量精度限制
7 内部变量
7.1 Vertex Shader Special Variables
highp vec4 gl_Position; // should be written to
mediump float gl_PointSize; // may be written t
7.2 Fragment Shader Special Variables
The built-in variables that are accessible from a fragment shader are intrinsically given types as follows:
mediump vec4 gl_FragCoord;
bool gl_FrontFacing;
mediump vec4 gl_FragColor;
mediump vec4 gl_FragData[gl_MaxDrawBuffers];
mediump vec2 gl_PointCoord;
7.3 Vertex Shader Built-In Attributes
There are no built-in attribute names in OpenGL ES.
7.4 Built-In Constants
The following built-in constants are provided to the vertex and fragment shaders.
//
// Implementation dependent constants. The example values below
// are the minimum values allowed for these maximums.
//
const mediump int gl_MaxVertexAttribs = 8;
const mediump int gl_MaxVertexUniformVectors = 128;
const mediump int gl_MaxVaryingVectors = 8;
const mediump int gl_MaxVertexTextureImageUnits = 0;
const mediump int gl_MaxCombinedTextureImageUnits = 8;
const mediump int gl_MaxTextureImageUnits = 8;
const mediump int gl_MaxFragmentUniformVectors = 16;
const mediump int gl_MaxDrawBuffers = 1;
Version 1.00 Revision 17 (12 May, 2009)
7 Built-in Variables 62
7.5 Built-In Uniform State
As an aid to accessing OpenGL ES processing state, the following uniform variables are built into the
OpenGL ES Shading Language. All notations are references to the 2.0 specification. If an
implementation does not support highp precision in the fragment language, and state is listed as highp,
then that state will only be available as mediump in the fragment language.
//
// Depth range in window coordinates
//
struct gl_DepthRangeParameters {
highp float near; // n
highp float far; // f
highp float diff; // f - n
};
uniform gl_DepthRangeParameters gl_DepthRange;
参考
https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getParameter
https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.2
https://blog.csdn.net/myarrow/article/details/7737313