WebGL 的 viewport 方法有什么用?

viewport 和 gl_FragCoord

gl_FragCoord 是webgl里面的泪之便利, 表示当前片元着色器处理的候选片元窗口相对坐标信息。可以简单理解成现在绘制的那个像素的坐标(假设每个片元刚好就是1px)。

假如,我们设定的viewport的渲染区域为(0, 0, 1280, 574) 这么大,那么,gl_Fragment的x分量 范围就在01280之间, y分量就在0574之间。

image-20201218114722192

image-20201218113812022

可以利用 gl_FragCoord 每次绘制片元都不一样的这个特性,来实现颜色变化的动效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88


<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Canvas - WebGL</title>
</head>

<body>
<canvas id="gl"></canvas>
<script id="vertex" type="x-shader/x-vertex">
attribute vec4 coords;

void main() {
gl_Position = coords;
gl_PointSize = 10.0;
}
</script>
<script id="fragment" type="x-shader/x-fragment">
precision mediump float;
uniform float time;
uniform vec2 resolution;

void main() {
vec2 uv = gl_FragCoord.xy / resolution.xy;
gl_FragColor = vec4(uv,0.5+0.5*sin(time),1.0);
}

</script>

<script>
const canvas = document.getElementById('gl'),
gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'),
verts = [
1, -1, 0,
-1, -1, 0,
1, 1, 0,
-1, 1, 0
];

canvas.width = 100;
canvas.height = 100;

gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);

gl.viewport(0, 0, canvas.width, canvas.height);
var vrt_shader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vrt_shader, document.getElementById('vertex').innerText);
gl.compileShader(vrt_shader);

var fra_shader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fra_shader, document.getElementById('fragment').innerText);
gl.compileShader(fra_shader);

var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vrt_shader);
gl.attachShader(shaderProgram, fra_shader);

gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);

var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);

var coords = gl.getAttribLocation(shaderProgram, 'coords');
gl.vertexAttribPointer(coords, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(coords);

var time = gl.getUniformLocation(shaderProgram, 'time');
var resolution = gl.getUniformLocation(shaderProgram, 'resolution');

gl.uniform2f(resolution, canvas.width, canvas.height);

function animate(timestamp) {
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
gl.uniform1f(time, timestamp * 0.001);
gl.flush();
window.requestAnimationFrame(animate);
}
animate(0);
</script>

</body>
</html>


WebGL 的 viewport 方法有什么用?
http://example.com/2024/05/23/webgl/WebGL 的 viewport 方法有什么用?/
Author
John Doe
Posted on
May 23, 2024
Licensed under