Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript WebGL 基础疑惑点 #110

Open
XXHolic opened this issue Nov 7, 2021 · 0 comments
Open

JavaScript WebGL 基础疑惑点 #110

XXHolic opened this issue Nov 7, 2021 · 0 comments

Comments

@XXHolic
Copy link
Owner

XXHolic commented Nov 7, 2021

目录

引子

尝试 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 颜色

参考资料

🗑️

最近看了芥川龙之介的小说《河童》,里面构建的河童世界真是让我涨了见识。下面是一些摘录。

河童分娩也跟我们人类一样,要请医生和产婆帮忙。但临产的时候,做父亲的就像打电话似的对着做母亲的下身大声问到:“你好好考虑一下愿不愿意生到这个世界上来,再回答我。”

募集遗传义勇队——,健全的雌雄河童们,为了消灭恶性遗传,去和不健全的雌雄河童结婚吧!

在河童的世界里有一个《职工屠宰法》,被解雇的河童职工会被宰掉,把肉做成各种食物。这样可以保持市场肉价平稳以及解除饿死的境况。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant