用webgl画个正方形

1,446 阅读2分钟

「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战

直接画个顶点

绘制过顶点的同学肯定注意到了,gl.POINTS画出来的点就是方的。所以最简单的办法就是画个顶点.稍微修改一下,着色器代码, 把顶点的大小改大些, 这里pointSize的单位,经验证就是px.

attribute vec4 a_Position ; 
void main(){
    gl_Position = a_Position ;
    gl_PointSize = 422.0;
}

顶点点位是(0,0)。效果如下

image.png

用两个三角形

上一次也是用两个三角形,不过结果是铺满整个画布的矩形。顶点数据是这样的

const points = [ -1,1, 1,1, -1,-1, 1,-1, ]

从点位坐标看上去,应该就是一个正方形,但是结果却是一个和画布尺寸相同的矩形。

这是因为高宽的单位不同.他们的单位就像vh 和vw(浏览器高宽的百分之一)。 而webgl的坐标单位是画布的半个高宽。 所以我们需要将点位做一些调整。

const points = [ -1/ratio,1, 1/ratio,1, -1/ratio,-1, 1/ratio,-1, 0,0 ]

我们的正方形又回来了!。 image.png

webgl坐标系

关于前面的正方形是怎么来的,我再复述一遍。假设我们的画布尺寸是 100 * 50 。 那么一个高vh就是50, 一个宽vw就是100, 一个webgl x分量就是50, y分量就是25 。 我们之前的坐标点位是2个单位的矩形, 也就是2x * 2y ===> 100 * 50 .

现在我们想画一个正方形,就要宽高相等, 因为一般高度小于宽度,我们这里就以宽度为基准, 把高度变成和宽度一样。

已知高度是 2y, 宽度应为nx,画布宽高比 ratio 求n?

因 2y === 2nx 故 n = y/x 又 ratio = vw/vh = x/y,故 n = 1/ ratio ;

所以我们在之前的x点位上都除以了宽高比,来保证最终视觉上的正方形。

基本特点

webgl的坐标系和2d的canvas坐标系有些差别。

1 坐标原点是在 画布中心
2 y轴方向 竖直向上
3 x, y 方向的坐标的单位分别是 画布宽高的一半。 

x轴同样是水平向右的。

然后还多了一个z轴,轴的方向是垂直屏幕朝里的,也就是说屏幕后面的点的z值都是正。( 不过在使用了投影矩阵之后,我们往往把z轴方向换了回来,变成垂直屏幕朝外)。

image.png