[Computer Grpahics] WebGL Variables

2023. 10. 10. 18:22Run/Computer Graphics

 

 

Variable Types

 

- bool: boolean

- int: signed integer

- float: floating point scalar

- vec2, vec3, vec4: n-dimensional float vector

- bvec2, bvec3, bvec4: n-dimensional boolean vector

- ivec2, ivec3, ivec4: n-dimensional integer vector

- mat2, mat3, mat4: 2x2, 3x3, 4x4 float matrix

- sampler2D: access a 2D texture

- samplerCube: access a cube mapped texture

 

 

Kind of Variables

 

Vertex Shader (VS) JavaScript (JS)
- built-in output (WRITE)
- attribute (READ)
- uniform (READ)
- varying (WRITE)
- regular (WRITE, READ)
- uniform (WRITE)
- attribute (WRITE)
Fragment Shader (FS)
- built-in input (READ)
- built-in output (WRITE)
- uniform (READ)
- varying (READ)
- regular (WRITE, READ)

 

Type Written In Read In Value
 Built-in Output for VS VS - 1 per vertex
Built-in Input for FS - FS 1 per fragment
Built-in Output for FS FS - 1 per fragment
Uniform JS VS & FS 1 for all vertices/fragments
Attribute JS VS 1 per vertex
Varying VS FS 1 per vertex, interpolated to
1 per fragment
Regular (no qualifier) for VS VS VS 1 per vertex
Regular (no qualifier) for FS FS FS 1 per fragment

 

 

Built-in Output Variables  for VS (written in VS / not readable / 1 value per vertex)

- gl_Position(vec4): x, y, z, w for vertex location in 3D

- gl_PointSize(float): Size of the point

 

Built-in Input Variables for FS (not writeable / read in FS / 1 value per fragment)

- gl_FragCoord(vec4): x(0~512), y(0~512), z, w for fragment position within framebuffer

- gl_FrontFacing(bool): 1 (if fragment belongs to front-facing primitive)

- gl_PointCoord(vec2): x, y for fragment position within a point

 

Built-in Output Variables for FS (written in FS / not readable / 1 value per fragment)

- gl_FragColor(vec4): R, G, B, Opacity(alpha) values

- gl_FragData(array with n elements of type vec4): if you have n draw buffers, you can specify R, G, B, Opacity values for each buffer

 

Uniform Variables (written in JS / read in VS & FS / 1 value for all vertices & fragments)

<script id="fragment-shader" type="x-shader/x-fragment">
    precision mediump float;
    uniform vec4 fragColor;
    void main() {
        gl_FragColor = fragColor;
    }
</script>

- 'fragColor' is a uniform variable read in fragment shader

- 1 color available to all fragments

- 'fragColor' will be set in JS file (아래 예제는 삼각형 그린 뒤 사각형 그리는 예제)

// get the memory location of 'fragColor' in the shaders
fragColorLoc = gl.getUniformLocation(myShaderProgram, "fragColor");

// first draw triangle (offset 0, number of points 3)
gl.uniform4f(fragColorLoc, 0.0, 1.0, 0.0, 1.0);
gl.drawArrays(gl.TRIANGLES, 0, 3);

// then draw square (offset 3, number of points 4)
gl.uniform4f(fragColorLoc, 0.0, 0.0, 1.0, 1.0);
gl.drawArrays(gl.TRIANGLE_FAN, 3, 4);

The fragment shader executes for 2 times.

Each time the shader executes, it works with a different value for 'fragColor'.

 

Attribute Variables (written in JS / read in VS / 1 value per vertex)

<script id="vertex-shader" type="x-shader/x-vertex">
    attribute vec4 myPosition;
    attribute vec4 scaleValue;
    void main() {
        gl_PointSize = 1.0;
        gl_Position.x = myPosition[0] * scaleValue[0];
        gl_Position.y = myPosition[1] * scaleValue[1];
        gl_Position.z = myPosition[2] * scaleValue[2];
        gl_Position.w = myPosition[3] * scaleValue[3];
    }
</script>
var p1 = vec4(0.0, 0.0, 0.0, 1.0);
var p2 = vec4(0.0, 1.0, 0.0, 1.0);
var p3 = vec4(1.0, 0.0, 0.0, 1.0);

var arrayOfPointsForTriangle = [p1, p2, p3];

var bufferId = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
gl.bufferData(gl.ARRAY_BUFFER, flatten(arrayOfPointsForTriangle), gl.STATIC_DRAW);

 

Varying Variables (written in VS / read in FS / 1 value per vertex)

- Interpolated by rasterizer to 1 value per fragment

- varying vec4 interpColor

<script id="vertex-shader" type="x-shader/x-vertex">
    attribute vec4 myPosition;
    varying vec4 interpColor;
    void main() {
        gl_PointSize = 1.0;
        gl_Position = myPosition;
        interpColor = myPosition;
        // point (0.0, 1.0) => green (0.0, 1.0, 0.0)
        // point (0.0, 0.0) => black (0.0, 0.0, 0.0)
        // point (1.0, 0.0) => red (1.0, 0.0, 0.0)
    }
</script>

<script id="fragment-shader" type="x-shader/x-fragment">
    precision mediump float;
    varying vec4 interpColor;
    void main() {
        gl_FragColor = interpColor;
    }
</script>

Both fragment shader and vertex shader must have declaration for varying variable.

Varying varaible is set (written) in vertex shader and is read in fragment shader.

gl.clearColor(0.3, 0.3, 0.3, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

var p1 = vec4(0.0, 0.0, 0.0, 1.0);
var p2 = vec4(0.0, 1.0, 0.0, 1.0);
var p3 = vec4(1.0, 0.0, 0.0, 1.0);

var arrayOfPointsForTriangle = [p1, p2, p3];

 

 

Accessing Variables Locations in Shaders

 

- method 1

   ex1) gl_FragCoord[0], gl_FragCoord[1], gl_FragCoord[2], gl_FragCoord[3]

   ex2) gl_FragColor[0], gl_FragColor[1], gl_FragColor[2], gl_FragColor[3]

 

- method 2

   ex1) gl_FragCoord.x, gl_FragCoord.y, gl_FragCoord.z, gl_FragCoord.w (Point Variables)

   ex2) gl_FragColor.r, gl_FragColor.g, gl_FragColor.b, gl_FragColor.a (Color Variables)