Basic concepts of shader and program Programming

Source: Internet
Author: User
Tags types of functions

I. Concerns in this article:

• Introduction to Shader and program objects
• Create and compile a shader object
• Create and link a program object
• Obtain and set the uniforms
• Get and set attributes

In OpenGL ES, each program object has only one vertex shader object and one fragment shader object to connect to it.

Shader: similar to the C Compiler

Program: similar to C linker

The gllinkprogram operation generates the final executable program, which contains the hardware commands that can finally be executed on the hardware.

Ii. Overview of shader and program Programming

1. Create a shader
1) write the vertex shader and fragment shader source code.

2) create two shader instances: gluint glcreateshader (glenum type );

3) Specify the source code for the shader instance. Glshadersource

4) Compile the Shaer source code void glcompileshader (gluint shader) online)

2. Create a program

1) create a program gluint glcreateprogram (void)

2) bind the shader to the program. Void glattachshader (gluint program, gluint shader ). Each program must be bound with a vertex shader and a fragment shader.

3) link to program. Void gllinkprogram (gluint Program)

4) use porgram. Void gluseprogram (gluint Program)

For binary shader Code Compiled using an independent shader compiler, you can use glshaderbinary to load it into a shader instance.

 

Iii. Data Types and variables in shading Language
1. Uniforms and attributes

Uniforms is uniformly allocated in a program. The unim m with the same name in vertext and fragment must be of the same type. It corresponds to the variable that does not change frequently (used to store variables with read-only constant values ).

Variables with high attributes change rate. It is mainly used to define each vertex attribute of an input.

The uniforms and attributes are mapped by location and name in the shader.

2. Data Type

1)Three basic data types: Float, Int, Boolean

2)Composite Type: Floating Point, integer, Boolean vector vec2, vec3, vec4. There are two ways to access a vector:

(1 ). operation: Mathematics {X, Y, Z, w}, color {R, G, B, A} or texture coordinate {S, T, R, Q}, but cannot be mixed, example:

Vec3 myvec3 = vec3 (0.0, 1.0, 2.0); // myvec3 = {0.0, 1.0, 2.0}
Vec3 temp;
Temp = myvec3.xyz; // temp = {0.0, 1.0, 2.0}
Temp = myvec3.xxx; // temp = {0.0, 0.0, 0.0}
Temp = myvec3.zyx; // temp = {2.0, 1.0, 0.0}

(2) [] operation: [0] corresponds to X, [1] corresponds to Y, [2] corresponds to Z, [3] corresponds to W. [] Can only be a constant or uniform variable, not an integer variable (such as I, J, K ).

 

3)Matrix: Mat2, mat3, and mat4 (stored in column order)

Mat3 mymat3 = mat3 (1.0, 0.0, 0.0, // The first column
0.0, 1.0, 0.0, // second column
0.5, 1.0, 1.0); // The third column

You can use the [] or. Operator to access:

Mat4 mymat4 = mat4 (1.0); // initialize diagonal to 1.0 (identity)
Vec4 col0 = mymat4 [0]; // get col0 vector out of the matrix
Float m1_1 = mymat4 [1] [1]; // get element at [1] [1] In Matrix
Float m2_2 = mymat4 [2]. Z; // get element at [2] [2] In Matrix

4)Constant

Const Float Zero = 0.0;
Const float Pi = 3.14159;
Const vec4 Red = vec4 (1.0, 0.0, 0.0, 1.0 );
Const mat4 identity = mat4 (1.0 );

5)Struct: Constructs struct with basic and composite types.

Struct fogstruct
{
Vec4 color;
Float start;
Float end;
} Fogvar;
Fogvar = fogstruct (vec4 (0.0, 1.0, 0.0, 0.0), // color
0.5, // start
(2.0); // end
Vec4 color = fogvar. color;
Float start = fogvar. Start;
Float end = fogvar. end;

6)Array: Similar to the C language, the index starts from 0. Cannot be initialized at creation, and the index can only be a constant or uniform variable.

Float floatarray [4];
Vec4 vecarray [2];

7)Operation

Supported operations include: *,/, +,-, ++, --, =, + =,-=, * =,/=, = ,! =, <,>, <=, >=, &, ^, |

float myFloat;vec4 myVec4;mat4 myMat4;myVec4 = myVec4 * myFloat; // Multiplies each component of myVec4                           // by a scalar myFloatmyVec4 = myVec4 * myVec4;  // Multiplies each component of myVec4                           // together (e.g., myVec4 ^ 2 )myVec4 = myMat4 * myVec4;  // Does a matrix * vector multiply of                           // myMat4 * myVec4myMat4 = myMat4 * myMat4;  // Does a matrix * matrix multiply of                           // myMat4 * myMat4myMat4 = myMat4 * myFloat; // Multiplies each matrix component by                           // the scalar myFloat

The number of rows in the preceding matrix is the number of rows in the result matrix, and the number of columns in the following matrix is the number of columns in the result matrix.

8)Custom functions:

vec4 myFunc(inout float myFloat,  // inout parameter            out vec4 myVec4,      // out parameter            mat4 myMat4);         // in parameter (default)

Functions cannot be called recursively, Because GPUs do not necessarily have stack and throttling.

9)Shading language embedded Functions

There are mainly the following types of functions:

(1) angle and trigonometric function

(2) exponential functions

(3) general functions (absolute value, integer, remainder, decimal part, etc)

(4) geometric Functions

(5) Matrix Functions

(6) vector comparison functions

(7) Texture search function

(8) derivative Functions

10)Control Flow

If (color. A <0.25) {color * = color. A;} else {color = vec4 (0.0) ;}// for loop. Only constant loops are supported. // No matter the subscript or loop variable, only constants that can be determined during compilation can be used. For (INT I = 0; I <3; I ++) {sum + = I ;}

The following statements are not allowed (because the subscript is a variable or the number of loops is a variable ):

    float myArr[4];    for(int i = 0; i < 3; i++)    {        sum += myArr[i]; // NOT ALLOWED IN OPENGL ES, CANNOT DO                         // INDEXING WITH NONCONSTANT EXPRESSION    }    ...    uniform int loopIter;    // NOT ALLOWED IN OPENGL ES, loopIter ITERATION COUNT IS NONCONSTANT    for(int i = 0; i < loopIter; i++)    {        sum += i;    }

11) uniforms (modified in the previous Region)
The initial value of the variable modified before uniform is assigned by the external program. The program has a uniform access space and limited storage space. The shader is read-only and can only be passed in by external host programs.

It is used to store various data required by shader, such as transform matrix, illumination parameters and colors. Basically, a shader is a constant, but its value is unknown during compilation, it should be used as an uniform variable.

The uniform variable is shared between vertex shader and fragment shader. After gluniform *** is used to set the value of an uniform variable, vertex shader and fragment shader have the same value.

The uniform variable is stored in the "constant storage area" of the GPU, and its space is fixed. You can use the API <glgetintegerv> to query (gl_max_vertex_uniform_vectors or gl_max_fragment_uniform_vectors ).

 

12) attributes (modified in the previous Region)

Attribute type variables are available only in vertex shader. The variable modified by vertex prior to attribute defines the attribute variables of each vertex, including location, color, normal, and texture coordinates.

Attribute variables are read-only in vertex shader and can only be passed in by external host programs.

Attribute type variable: data specified for each vertex being drawn. Before drawing, attributes of each vertex are input by the application.

Like the uniform variable, the storage quantity is also limited. You can use glgetintegerv (gl_max_vertex_attribs) to query. The GPU supports at least eight attributes. Therefore, the source code of vertex shader must contain no more than eight attribuckets.

 

13) varyings

The varying variable is used to store vertex shader output and fragment shader input. The same varying variable must be declared in vertex shader and fragment shader.

Like uniform and attribute, the storage capacity is limited. You can use glgetintegerv (gl_max_varying_vectors) to query the storage capacity. GPU supports at least 8 varying vectors, so the source code of vertex shader must contain no more than 8 varying
Vector.

Glint maxvertexattribs; // n will be> = 8
Glgetintegerv (gl_max_vertex_attribs, & maxvertexattribs );

 

14) preprocessing 

 

#define#undef#if#ifdef#ifndef#else#elif#endif__LINE__ // Replaced with the current line number in a shader__FILE__ // Always 0 in OpenGL ES 2.0__VERSION__ // The OpenGL ES shading language version (e.g., 100)GL_ES // This will be defined for ES shaders to a value of 1

15) minimum uniform attribute varying storage space

Variable type

Minimum number of GPUs required

Vertex uniform Vectors

128

Fragment uniform Vectors

16

Vertex attributes

8

Varying Vectors

8

 16) precision qualifiers)

Keywords: lowp highp mediump

(1) Specify the variable precision (before the data type ):
 

         highp vec4 position;         varying lowp vec4 color;         mediump float specularExp;

(2) Specify the default precision (at the beginning of vertex and fragment shader source code ):

         precision highp float;         precision mediump int;

In vertex shader, if there is no default precision, the float and INT precision are both high hp. In fragment shader, float has no default precision, therefore, you must specify a default precision for float in the fragment shader or for each float variable.

17) result consistency

Invariant can be applied to any vertex shader
Varying outputs variables. Currently, the same operations and inputs are ensured, and the results are the same. Because shader has different precision, the results may be different.

uniform mat4 u_viewProjMatrix;attribute vec4 a_vertex;invariant gl_Position;void main{    // …    gl_Position = u_viewProjMatrix * a_vertex; // Will be the same                                              // value in all                                              // shaders with the                                              // same viewProjMatrix                                              // and vertex}

You can also specify that all output variables are: invariant.

#pragma STDGL invariant(all)

 

Iv. Obtain and set the uniforms

Use glint glgetuniformlocation (gluint program, const char * Name). Obtain the location according to the name of an uniform.

You can use the gluniform *** series functions to set an uniform value for a location.

void glUniform1f(GLint location, GLfloat x)void glUniform1fv(GLint location, GLsizei count,const GLfloat* v)void glUniform1i(GLint location, GLint x)void glUniform1iv(GLint location, GLsizei count,const GLint* v)void glUniform2f(GLint location, GLfloat x, GLfloat y)void glUniform2fv(GLint location, GLsizei count,const GLfloat* v)void glUniform2i(GLint location, GLint x, GLint y)void glUniform2iv(GLint location, GLsizei count,const GLint* v)void glUniform3f(GLint location, GLfloat x, GLfloat y,GLfloat z)void glUniform3fv(GLint location, GLsizei count,const GLfloat* v)void glUniform3i(GLint location, GLint x, GLint y,GLint z)void glUniform3iv(GLint location, GLsizei count,const GLint* v)void glUniform4f(GLint location, GLfloat x, GLfloat y,GLfloat z, GLfloat w);void glUniform4fv(GLint location, GLsizei count,const GLfloat* v)void glUniform4i(GLint location, GLint x, GLint y,GLint z, GLint w)void glUniform4iv(GLint location, GLsizei count,const GLint* v)void glUniformMatrix2fv(GLint location, GLsizei count,                        GLboolean transpose,const GLfloat* value)void glUniformMatrix3fv(GLint location, GLsizei count,                        GLboolean transpose,const GLfloat* value)void glUniformMatrix4fv(GLint location, GLsizei count,                       GLboolean transpose,const GLfloat* value)

The transpose in the function that sets the value for the matrix uniform variable must be gl_false for compatibility purposes, but it does not work in OpenGL ES 2.0.

Once you set the value of the unirom variable in a program, even if you activate another program, the value of this uniform remains unchanged. That is, the uniform variable is the local variable of the program.

V. vertex attributes

The vertex attribute specifies the data of each vertex. In OpenGL es1.1, the vertex attributes have four predefined names: Position, normal, color, and texture coordinates ). In OpenGL es2.0, you must define the "vertex attribute name ".

1. Constant vertex attribute)

Constant vertex attributes are the same for all vertices. Therefore, you only need to specify a value to apply it to all vertices. It is rarely used. The setting functions include:

void glVertexAttrib1f(GLuint index, GLfloat x);void glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y);void glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);void glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z,GLfloat w);void glVertexAttrib1fv(GLuint index, const GLfloat *values);void glVertexAttrib2fv(GLuint index, const GLfloat *values);void glVertexAttrib3fv(GLuint index, const GLfloat *values);void glVertexAttrib4fv(GLuint index, const GLfloat *values);

 

2. How to load vertex data? (Vertex arrays)

Vertex array (vertex array) is a memory buffer stored in the Application Space (client). It stores attribute data of each vertex.

How can we pass the data of the vertex Data Group to the GPU?

Void glvertexattribpointer (gluint index,

Glint size, // The number of each attribute element. Valid values: 1-4 (x, y, z, W)
Glenum type, // the Data Type of each element in the array
Glboolean normalized,
Glsizei stride, // if the data is continuously stored, it is 0 or

// Size * sizeof (type)
Const void * PTR) // vertex array pointer

Example:

 

   GLfloat vVertices[] = {  0.0f,  0.5f, 0.0f,                            -0.5f, -0.5f, 0.0f,                            0.5f, -0.5f, 0.0f };         // Set the viewport   glViewport ( 0, 0, esContext->width, esContext->height );      // Clear the color buffer   glClear ( GL_COLOR_BUFFER_BIT );   // Use the program object   glUseProgram (programObject );   // Load the vertex data   glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );

2.1 All attributes of a vertex are stored together (array of structures)

As shown in, the vertex position (x, y, z), normal (x, y, z) and two texture coordinates (S, T) are stored together, as shown in:

 

2.2 Each attribute of a vertex is stored separately (structure of arrays)

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.