2023. 10. 10. 18:22ㆍRun/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)
'Run > Computer Graphics' 카테고리의 다른 글
[Computer Graphics] Texture Mapping (0) | 2023.10.10 |
---|---|
[Computer Graphics] Lighting (1) | 2023.10.10 |
[Computer Graphics] Viewing (1) | 2023.10.10 |
[Computer Graphics] WebGL 다각형 그리기 (0) | 2023.10.10 |
[Computer Graphics] WebGL 삼각형 그리기 (1) | 2023.10.10 |