一、需求背景
在CAD/CAE领域经常会遇到显示节点编号这种需求,效果如下图:
本文介绍如何在WebGL中实现文字的显示,对于如何在OpenGL中实现请绕路。
二、实现原理
Canvas是HTML5提供的元素,用于在网页上绘制图形,其支持2D与WebGL两种模式。对于canvas 2D擅长绘制基本图形、文字等。webgl擅长3D交互式图形的渲染,常用于游戏、3D模型、GIS、医学图像等领域。本文介绍的其实是对3D模型的标注,是将3D与2D进行结合,各自实现擅长的事。
其核心原理是在网页视图区同时放置两个Canvas,底层canvas使用WebGL,上层canvas使用2d分别绘制,两层canvas叠加实现最终效果。
两个canvas的放置顺序可使用z-index进行控制。核心原理就这么多,剩下的就是调用API的事了。
三、根据点坐标计算其屏幕位置
进行标注时需先根据点坐标确定其像素位置。这个过程跟GPU图形流水线计算顶点坐标是一样的。一般渲染引擎提供摄像机类,并有接口获取模型-视图-投影矩阵(MVP)。
用MVP矩阵乘以点坐标得到标准设备坐标系(NDC)下点的坐标,原点在屏幕中央,其范围是[-1, 1], 超过这个范围点不会显示在屏幕上。
注意Canvas 2d的API使用的坐标系是屏幕坐标系,其原点在屏幕左上角,X轴朝右,Y轴朝下。所以得到NDC坐标之后需变换到屏幕坐标系下,等价于图形流水线的视口变换。
变换公式如下:
X
=
n
d
c
X
+
1
2
∗
v
i
e
w
p
o
r
t
X
X = \frac{ndcX + 1}{2} * viewportX
X=2ndcX+1∗viewportX
Y
=
−
n
d
c
Y
+
1
2
∗
v
i
e
w
p
o
r
t
Y
Y = \frac{-ndcY + 1}{2} * viewportY
Y=2−ndcY+1∗viewportY
其中:
v
i
e
w
p
o
r
t
X
viewportX
viewportX是屏幕视口宽度
v
i
e
w
p
o
r
t
Y
viewportY
viewportY是屏幕视口高度
最后使用Canvas Context 2D的的API在(X,Y)位置绘制字体即可。