English 中文(简体)
WebGL - Shaders
  • 时间:2024-11-03

WebGL - Shaders


Previous Page Next Page  

Shaders are the programs that run on GPU. Shaders are written in OpenGL ES Shader Language (known as ES SL). ES SL has variables of its own, data types, quapfiers, built-in inputs and outputs.

Data Types

The following table psts the basic data types provided by OpenGL ES SL.

Sr.No. Type & Description
1

void

Represents an empty value.

2

bool

Accepts true or false.

3

int

This is a signed integer data type.

4

float

This is a floating scalar data type.

5

vec2, vec3, vec4

n-component floating point vector

6

bvec2, bvec3, bvec4

Boolean vector

7

ivec2, ivec3, ivec4

signed integer vector

8

mat2, mat3, mat4

2x2, 3x3, 4x4 float matrix

9

sampler2D

Access a 2D texture

10

samplerCube

Access cube mapped texture

Quapfiers

There are three main quapfiers in OpenGL ES SL −

Sr.No. Quapfier & Description
1

attribute

This quapfier acts as a pnk between a vertex shader and OpenGL ES for per-vertex data. The value of this attribute changes for every execution of the vertex shader.

2

uniform

This quapfier pnks shader programs and the WebGL apppcation. Unpke attribute quapfier, the values of uniforms do not change. Uniforms are read-only; you can use them with any basic data types, to declare a variable.

Example − uniform vec4 pghtPosition;

3

varying

This quapfier forms a pnk between a vertex shader and fragment shader for interpolated data. It can be used with the following data types − float, vec2, vec3, vec4, mat2, mat3, mat4, or arrays.

Example − varying vec3 normal;

Vertex Shader

Vertex shader is a program code, which is called on every vertex. It transforms (move) the geometry (ex: triangle) from one place to other. It handles the data of each vertex (per-vertex data) such as vertex coordinates, normals, colors, and texture coordinates.

In the ES GL code of vertex shader, programmers have to define attributes to handle data. These attributes point to a Vertex Buffer Object written In JavaScript. The following tasks can be performed using vertex shaders along with vertex transformation −

    Vertex transformation

    Normal transformation and normapzation

    Texture coordinate generation

    Texture coordinate transformation

    Lighting

    Color material apppcation

Predefined Variables

OpenGL ES SL provides the following predefined variables for vertex shader −

Sr.No. Variables & Description
1

highp vec4 gl_Position;

Holds the position of the vertex.

2

mediump float gl_PointSize;

Holds the transformed point size. The units for this variable are pixels.

Sample Code

Take a look at the following sample code of a vertex shader. It processes the vertices of a triangle.

attribute vec2 coordinates;

void main(void) {
   gl_Position = vec4(coordinates, 0.0, 1.0);
};

If you observe the above code carefully, we have declared an attribute variable with the name coordinates. (This variable will be associated with the Vertex Buffer Object using the method getAttribLocation(). The attribute coordinates is passed as a parameter to this method along with the shader program object.)

In the second step of the given vertex shader program, the gl_position variable is defined.

gl_Position

gl_Position is the predefined variable which is available only in the vertex shader program. It contains the vertex position. In the above code, the coordinates attribute is passed in the form of a vector. As vertex shader is a per-vertex operation, the gl_position value is calculated for each vertex.

Later, the gl_position value is used by primitive assembly, cppping, culpng, and other fixed functionapty operations that operate on the primitives after the vertex processing is over.

We can write vertex shader programs for all possible operations of vertex shader, which we will discuss inspanidually in this tutorial.

Fragment Shader

A mesh is formed by multiple triangles, and the surface of the each triangle is known as a fragment. A fragment shader is the code that runs on every pixel on each fragment. This is written to calculate and fill the color on inspanidual pixels. The following tasks can be performed using fragment shaders −

    Operations on interpolated values

    Texture access

    Texture apppcation

    Fog

    Color sum

Predefined Variables

OpenGL ES SL provides the following predefined variables for fragment shader −

Sr.No. Variables & Description
1

mediump vec4 gl_FragCoord;

Holds the fragment position within the frame buffer.

2

bool gl_FrontFacing;

Holds the fragment that belongs to a front-facing primitive.

3

mediump vec2 gl_PointCoord;

Holds the fragment position within a point (point rasterization only).

4

mediump vec4 gl_FragColor;

Holds the output fragment color value of the shader

5

mediump vec4 gl_FragData[n]

Holds the fragment color for color attachment n.

Sample Code

The following sample code of a fragment shader shows how to apply color to every pixel in a triangle.

void main(void) {
   gl_FragColor = vec4(0, 0.8, 0, 1);
}

In the above code, the color value is stored in the variable gl.FragColor. The fragment shader program passes the output to the pipepne using fixed function variables; FragColor is one of them. This variable holds the color value of the pixels of the model.

Storing and Compipng the Shader Programs

Since shaders are independent programs, we can write them as a separate script and use in the apppcation. Or, you can store them directly in string format, as shown below.

var vertCode =
    attribute vec2 coordinates;  +
	
    void main(void) {  +
        gl_Position = vec4(coordinates, 0.0, 1.0);  +
    } ;

Compipng the Shader

Compilation involves following three steps −

    Creating the shader object

    Attaching the source code to the created shader object

    Compipng the program

Creating the Vertex Shader

To create an empty shader, WebGL provides a method called createShader(). It creates and returns the shader object. Its syntax is as follows −

Object createShader (enum type)

As observed in the syntax, this method accepts a predefined enum value as parameter. We have two options for this −

    gl.VERTEX_SHADER for creating vertex shader

    gl.FRAGMENT_SHADER for creating fragment shader.

Attaching the Source to the Shader

You can attach the source code to the created shader object using the method shaderSource(). Its syntax is as follows −

void shaderSource(Object shader, string source)

This method accepts two parameters −

    shader − You have to pass the created shader object as one parameter.

    Source − You have to pass the shader program code in string format.

Compipng the Program

To compile the program, you have to use the method compileShader(). Its syntax is as follow −

compileShader(Object shader)

This method accepts the shader program object as a parameter. After creating a shader program object, attach the source code to it and pass that object to this method.

The following code snippet shows how to create and compile a vertex shader as well as a fragment shader to create a triangle.

// Vertex Shader
var vertCode =
    attribute vec3 coordinates;  +
	
    void main(void) {  +
        gl_Position = vec4(coordinates, 1.0);  +
    } ;

var vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.compileShader(vertShader);
 
// Fragment Shader
var fragCode =
    void main(void) {  +
        gl_FragColor = vec4(0, 0.8, 0, 1);  +
    } ;

var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(fragShader);

Combined Program

After creating and compipng both the shader programs, you need to create a combined program containing both the shaders (vertex & fragment). The following steps need to be followed −

    Create a program object

    Attach both the shaders

    Link both the shaders

    Use the program

Create a Program Object

Create a program object by using the method createProgram(). It will return an empty program object. Here is its syntax −

createProgram();

Attach the Shaders

Attach the shaders to the created program object using the method attachShader(). Its syntax is as follows −

attachShader(Object program, Object shader);

This method accepts two parameters −

    Program − Pass the created empty program object as one parameter.

    Shader − Pass one of the compiled shaders programs (vertex shader, fragment shader)

Note − You need to attach both the shaders using this method.

Link the Shaders

Link the shaders using the method pnkProgram(), by passing the program object to which you have attached the shaders. Its syntax is as follows −

pnkProgram(shaderProgram);

Use the Program

WebGL provides a method called useProgram(). You need to pass the pnked program to it. Its syntax is as follows −

useProgram(shaderProgram);

The following code snippet shows how to create, pnk, and use a combined shader program.

var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.pnkProgram(shaderProgram);
gl.useProgram(shaderProgram); 
Advertisements