3.3. Initializers and ConstructorsA shader variable may be initialized when it is declared. As is familiar from C, the following example initializes b at declaration time and leaves a and c undefined: float a, b = 3.0, c; Constant qualified variables must be initialized. const int Size = 4; // initializer is required Attribute, uniform, and varying variables cannot be initialized when declared. attribute float Temperature; // no initializer allowed, // the vertex API sets this uniform int Size; // no initializer allowed, // the uniform setting API sets this varying float density; // no initializer allowed, the vertex // shader must programmatically set this To initialize aggregate types, at either declaration time or elsewhere, CONSTRUCTORS are used. No initializer uses the brace syntax "{. . .}" from C. Syntactically, constructors look like function calls that have a type name where the function name would gofor example, to initialize a vec4 with the values (1.0, 2.0, 3.0, 4.0), use vec4 v = vec4(1.0, 2.0, 3.0, 4.0); Or, because constructor syntax is the same whether it's in an initializer or not, use vec4 v; v = vec4(1.0, 2.0, 3.0, 4.0); There are constructors for all the built-in types (except samplers) as well as for structures. Some examples: vec4 v = vec4(1.0, 2.0, 3.0, 4.0); ivec2 c = ivec2(3, 4); vec3 color = vec3(0.2, 0.5, 0.8); vec4 color4 = vec4(color, 1.0) struct light { vec4 position; struct tLightColor { vec3 color; float intensity; } lightColor; } light1 = light(v, tLightColor(color, 0.9)); For matrices, the components are written in column major order. For example, mat2 m = mat2(1.0, 2.0, 3.0, 4.0); results in the following matrix:
So far, we've only shown constructors taking one argument for each component being constructed. Built-in constructors for vectors can also take a single argument, which is replicated into each component. vec3 v = vec3(0.6); is equivalent to vec3 v = vec3(0.6, 0.6, 0.6); This is true only for vectors. Structure constructors must receive one argument per member being constructed. Matrix constructors also have a single argument form, but in this case it initializes just the diagonal of the matrix. The remaining components are initialized to 0.0. mat2 m = mat2(1.0); // makes a 2 x 2 identity matrix mat2 m = mat2(1.0, 0.0, 0.0, 1.0); // makes a 2 x 2 identity matrix Constructors can also have vectors and matrices as arguments. However, constructing matrices from other matrices is reserved for future definition. vec4 v = vec4(1.0); vec2 u = vec2(v); // the first two components of v initialize u mat2 m = mat2(v); Matrix components are read out of arguments in column major order and written in column major order. Extra components within a single constructor argument are silently ignored. Normally, this is useful for shrinking a value, like eliminating alpha from a color or w from a position. It is an error to have completely unused arguments passed to a constructor. vec2 t = vec2(1.0, 2.0, 3.0); // illegal; third argument is unused |