JavaScript WebGL 基础疑惑点

目录

引子

尝试 JavaScript WebGL 绘制一条直线 之后总算是熟悉了一点,但还是有些疑惑,在此集中记录一下。

顶点坐标范围为什么要在 -1.0 到 1.0 之间 ?

在绘制直线的示例中,如果按照 Canvas 的大小修改顶点坐标,发现大都看不到对应的点。查资料说每个顶点的 x,y,z 坐标都应该在 -1.0 到 1.0 之间,超出这个坐标范围的顶点都将不可见。原因是整个过程中涉及到多个坐标系统的转换。

多个坐标系转换的优点是,一些操作或运算在特定的坐标系中才有意义且更方便容易。一个顶点到最后展示到屏幕,主要经历了下面一些坐标系转换:

93-coordinate

  1. 局部空间中的局部坐标(Local Coordinate),是物体的起始坐标。
  2. 接着通过模型矩阵变换,变为世界空间的世界坐标(World Coordinate)。这些坐标相对于世界的全局原点,它们会和其它物体一起相对于世界的原点进行摆放。
  3. 接着通过观察矩阵变换,变为观察空间的观察坐标(View Coordinate),使得每个坐标都是从摄像机或者说观察者的角度进行观察的。
  4. 接着需要将其投影到裁剪空间的裁剪坐标(Clip Coordinate)。裁剪坐标会被处理至 -1.0 到 1.0 的范围内,并判断哪些顶点将会出现在屏幕上。
  5. 最后,将裁剪坐标变换为屏幕空间的屏幕坐标(Screen Coordinate),使用一个叫做视口变换(Viewport Transform)的过程。视口变换将位于 -1.0 到 1.0 范围的坐标变换到由 glViewport 函数所定义的坐标范围内。变换出来的坐标将会送到光栅器,将其转化为片元。

多次缓冲数据是覆盖还是增量 ?

缓冲是分类型的,尝试了下 gl.ARRAY_BUFFER 类型每次相同的变量会覆盖之前的数据。

这是基于绘制直线示例,最后只绘制了垂直直线:

  let vertices = [-0.5, 0, 0.0, 0.5, 0, 0.0]; // 水平直线
  let vertices2 = [0, 0.5, 0.0, 0, -0.5, 0.0]; // 垂直直线
  setBuffers(glContext, vertices);
  setBuffers(glContext, vertices2);

vertexAttribPointer 解析顶点一次就足够了 ?

在频繁绘制的场景中,vertexAttribPointer 每次都需要重新解析顶点,还是解析一次就足够了?

在绘制直线示例的基础上尝试发现:

  1. 要先保证已缓冲了数据,该函数才能有效解析。
  2. 每次更新了缓冲,需要重新解析才能生效。

enableVertexAttribArray 方法也是类似。

useProgram 函数激活一次就足够了 ?

在频繁绘制的场景中,useProgram 是否需要重新激活?

在绘制直线示例的基础上尝试发现只需要激活一次,这是示例

基于的坐标系是什么 ?

基于的坐标系是右手坐标系。

93-right

按如下的步骤做:

  • 沿着正 y 轴方向伸出你的右臂,手指着上方。
  • 大拇指指向右方。
  • 食指指向上方。
  • 中指向下弯曲90度。

如果你的动作正确,那么你的大拇指指向正 x 轴方向,食指指向正 y 轴方向,中指指向正 z 轴方向。

常见的变量类型有那些?

摘自官方提供的 WebGL 1.0 卡片索引。

存储限定符

  • const : 编译时常量,或只读函数参数。
  • attribute : 用这个修饰的变量,表示是用于顶点着色器和 OpenGL ES 之间的链接。
  • varying : 用这个修饰的变量,表示是用于顶点着色器和片元着色器之间的链接。
  • uniform : 用这个修饰的变量,表示全局且唯一的变量,可以在任意阶段访问到,变量的值会一直保存。

基本类型

类型 含义
void 没有返回值的函数或空参数列表
bool 布尔值
int 有符号整数
float 浮点标量
vec2, vec3, vec4 2/3/4 分量的浮点向量
bvec2, bvec3, bvec4 2/3/4 分量的布尔向量
ivec2, ivec3, ivec4 2/3/4 分量的有符号整数向量
mat2, mat3, mat4 2x2, 3x3, 4x4 浮点数矩阵
sampler2D 2D 纹理
samplerCube 立体贴图纹理

内置的输入/输出变量有那些 ?

摘自官方提供的 WebGL 1.0 卡片索引。

顶点着色器特殊变量

输入:

变量 描述 单位或坐标系统
highp vec4 gl_Position; 转换顶点位置 剪切坐标
mediump float gl_PointSize; 变换点大小(仅点光栅化) 像素

片元着色器特殊变量

输入:

变量 描述 单位或坐标系统
mediump vec4 gl_FragCoord; 帧缓冲区内的片元位置 窗口坐标
bool gl_FrontFacing; 片元属于前向基本体 布尔值
mediump vec2 gl_PointCoord; 点内的片元位置(仅点光栅化) 每个组件从 0.0 到 1.0

输出:

变量 描述 单位或坐标系统
mediump vec4 gl_FragColor; 片元颜色 RGBA 颜色
mediump vec4 gl_FragData[n] 颜色附件n的片元颜色 RGBA 颜色

参考资料

posted @ 2021-12-13 08:59  XXHolic  阅读(60)  评论(0编辑  收藏  举报