AI 协作日志
学生 Web 实验作品平台
学号:202412211401029 · 来源:ai-log.md
# 实验一 AI协作记录
> 请记录本人真实的AI协作过程。不要只粘贴AI生成结果,应体现自己的判断、测试和核验。
## AI协作1:理解数据流
### 我的目标
搞清楚一组 Float32Array 顶点数据要经过哪些环节才能变成屏幕上的三角形,
以及每个环节在 task1.html / js/task1.js 中对应哪一行代码。
### 提示词
从 JavaScript 的 Float32Array 到屏幕上出现一个三角形,中间发生了哪些关键步骤?
请结合 WebGL2 解释 Buffer、vertexAttribPointer、Vertex Shader、光栅化和 Fragment Shader
各自负责什么,不要直接修改我的代码。
### AI关键回答摘要
1. Float32Array 只是 CPU 内存里连续的字节,本身没有"顶点"概念;必须用
gl.bufferData() 把它拷贝进 GPU 的 Buffer,而 Buffer 也只是显存里的字节容器。
2. gl.vertexAttribPointer() 才是"把字节切成顶点"的说明书:size=2 表示每 2 个
float 作为一个二维顶点;stride 与 offset 的单位都是字节,填 0 表示紧密打包。
3. 顶点属性在底层固定是 vec4。size=2 时剩下的分量由默认值补齐为 z=0、w=1,
所以 shader 里的 in vec4 vPosition 实际收到 (x, y, 0, 1);w=1 保证后面的
透视除法不会除零,三角形才落在可视区域内。
4. gl.drawArrays(gl.TRIANGLES, 0, 3) 的最后一个参数是"顶点个数",不是 float 个数;
task2.js 中用 vertices.length / 2 换算顶点数可以佐证这一点。
5. 修改 JS 里的数组不会自动同步到 GPU,因为 bufferData 只是一次性拷贝,
必须重新 bindBuffer + bufferData 才能更新显存中的数据。
6. Vertex Shader 逐顶点计算 gl_Position(决定顶点在哪);光栅化把三角形离散成片元
并对 varying 做插值;Fragment Shader 逐片元决定颜色,不能改变位置。
### 我的判断
上面哪几条你一开始不认同或理解错了,为什么后来接受。
我原以为顶点数据是"两个数一组"自动被识别的,实际上是参数指定的
### 验证方法
1. 逐行定位:task1.js:36 是唯一的 CPU→GPU 拷贝点;task1.js:40 的 size=2 是
顶点分组的来源;task1.js:57 是唯一触发 GPU 绘制的地方。
2. 把 task1.js 第 40 行的 size 由 2 临时改成 3,刷新页面观察;
3. 把 task1.js 第 57 行的顶点数由 3 临时改成 6,刷新页面并观察 Console。
### 验证结果
- 实验2(size=3):画面变成压缩为很小之后的三角形
### 修正后的结论
size会影响画面的展示
任务3 在同一 Canvas 中连续绘制两个对象时,第一个图形(左侧三角形)正常显示,
第二个图形(右侧四边形)完全没有出现,页面没有弹窗,status 文案正常更新。
### 我的初步判断
四边形的绘制代码出错了,
### 给AI的提示词
下面是一段 WebGL2 代码。第一个图形正常,第二个图形没有显示。
请不要重写完整程序,只列出最可能的3个原因,并告诉我应该通过什么现象、
Console 信息或代码检查逐一验证。
### AI给出的关键建议
1. 换绑新 Buffer 后没有重新调用 vertexAttribPointer —— 属性仍然指向上一个 Buffer,
第二次绘制读到的是三角形的顶点数据。
验证:在第二次创建 Buffer 之后、drawArrays 之前检查有没有 vertexAttribPointer;
或者临时把第二次绘制的顶点数改成 3,如果画出一个三角形,就说明属性还指着第一个 Buffer。
2. 第二次绘制前没有重新设置 uColor,或 getUniformLocation 返回了 null
(uniform 名字拼错、或该 uniform 在 Shader 中被优化掉)。
验证:console.log(uColor) 看是否为 null;把 gl.clearColor 临时改成醒目的深色,
判断第二个图形是"没画出来"还是"画出来但和背景同色"。
3. drawArrays 的参数不对:count 传成了 quad.length(8,float 数)而不是 4(顶点数),
导致顶点读取越界、该次绘制被丢弃;或者 quad 数组为空导致 if 守卫不成立、
drawArrays 根本没执行。
验证:在 if 块内 console.log(quad.length);检查 drawArrays 的第三个参数;
看 Console 有没有 INVALID_OPERATION 报错。
### 我实际进行的测试
重新保存了一些代码
### 测试结果
正常显示了
### 最终原因
没有保存代码
### 是否采纳AI建议及理由
没有采用
## AI协作3:顶点属性与颜色
### 我的目标
搞清楚 GPU 到底是怎么按照 vertexAttribPointer 的参数,从两个不同的 Buffer 里
分别读出二维位置和四维颜色,以及为什么每个顶点可以有自己的颜色。
### 提示词
在 WebGL2 中,位置属性 vPosition 每个顶点提供2个 float,而颜色属性 vColor
每个顶点提供4个 float。请从"GPU怎样按 vertexAttribPointer 的参数读取 Buffer
中连续数据"的角度解释两个属性的区别,不要只列参数定义。
### AI关键回答摘要
1. vertexAttribPointer 的四要素决定了"怎么从连续字节里切出顶点":
size(每顶点读几个分量)、type(每个分量占几字节)、stride(相邻顶点相隔几字节,
填 0 表示紧密打包,即 size×4)、offset(该属性在顶点内的起始字节偏移)。
2. 位置 Buffer 里 6 个 float 按 size=2、stride=0 切分,得到 3 组 (x,y);
颜色 Buffer 里 12 个 float 按 size=4、stride=0 切分,得到 3 组 (r,g,b,a)。
两个 Buffer 的数据布局不同,但读取规则也只是 size 不同,其余参数一样。
3. vertexAttribPointer 记录的是"调用时当前绑定的 ARRAY_BUFFER",所以两个属性
必须在各自 bindBuffer 之后分别调用,才能各自指向不同的 Buffer。
4. 顶点属性底层固定是 vec4:size=2 时补成 (x,y,0,1),size=4 时正好是 (r,g,b,a)。
5. 因为颜色是逐顶点属性(varying),光栅化时会在三角形内部插值,
所以三个顶点的颜色会形成连续渐变;而 uniform 颜色对整块图形是同一个值。
### 对照实验
把 js/task4.js:74 的 vertexAttribPointer(vColor, 4, ...) 中的 4 临时改成 3。
预测:GPU 会变成"每顶点只读 3 个 float",而数据实际是 4 个一组,
于是三个顶点读到的分量整体错位。
### 实际现象
三角形仍然画得出、也仍有渐变,但三个顶点的颜色不再是
红/绿/蓝——顶点0读到 (r1,g1,b1),顶点1读到 (a1,r2,g2),顶点2读到 (b2,a2,r3),
### 我的解释
stride=0 时实际步长 = size×4,所以 size 变了,切分位置也全变了。
### 最终结论
位置属性读取 2 个 float、颜色属性读取 4 个 float,差别只体现在 size 参数上;
size 不仅决定每个顶点读几个分量,在 stride 为 0 时还隐式决定了相邻顶点之间的步长,
所以改错 size 会让整个 Buffer 的切分位置错位,而不是只丢掉一个通道。
### task1
### 思考与记录
回答:
1. `Float32Array` 中连续两个数为什么可以表示一个二维顶点?
### 因为设定了2个为一组的切分,所以连续两个自动分为一个顶点,两个参数就是2维
2. Shader 中声明的是:
```glsl
in vec4 vPosition;
```
而 JavaScript 中:
```javascript
gl.vertexAttribPointer(
vPosition,
2,
...
);
```
为什么仍然可以正常绘制?
### 因为设置了size=2,所以虽然声明的是四维,但是实际收到的是2维的数据,没有后面的数值影响所以二维后面的自动补充的数值落在了合法区域就可以绘制
3. `gl.drawArrays(gl.TRIANGLES, 0, 3)` 中最后的 `3` 表示什么?
### 处理多少个顶点的参数
4. 修改 JavaScript 中的顶点数据后,为什么要重新执行 `gl.bufferData()` 才能改变 GPU 中的数据?
### 需要更新在显示区域里面副本的数据
### task2
### 必须回答
1. 相同顶点数据为什么会得到不同图形?
### 设置的绘制方式不同,一些识别分组的参数也可能不同
2. `TRIANGLE_STRIP` 中顶点顺序为什么重要?
### 点顺序影响了绘制方式的识别
3. 4个顶点通过 `TRIANGLE_STRIP` 实际组成了几个三角形?
### 可以画出两个
### task3
### 必须回答
1. 为什么改变 uniform 后不需要重新编译 Shader?
### 因为uniform相当于是链接外部变量的一个声明,更改后只需要更新状态数据,机器码等内容不需要改变
2. 如果只设置一次 `uColor`,随后绘制两个对象,会发生什么?
### 会显示为同一个颜色
3. 为什么绑定新的 Buffer 后需要再次正确设置顶点属性读取方式?
### 是需要更新从哪个buffer,按照声明规则读取
4. “当前 WebGL 状态会影响后续绘制”在本任务中体现在哪里?
### 顶点属性的读取规则,uniform,ARRAY——BUFFER都是状态的一部分,影响读取规则,绘制规则等内容
###task4
### 必须回答
1. 为什么位置 Buffer 每个顶点读取2个 float,而颜色 Buffer 每个顶点读取4个 float?
### 顶点设定的只是二维向量,颜色一般都是rgbd四个维度的信息,所以float数量不同
2. 两个 Buffer 如何分别对应到 `vPosition` 和 `vColor`?
### 更换了绑定状态
3. 三角形内部为什么出现连续渐变色,而不是只有红、绿、蓝三个区域?
### 因为vcoloar只是顶点颜色,光栅化的时候会按照顶点颜色权重来进行颜色混合
4. 顶点颜色插值主要发生在哪个阶段?Fragment Shader 得到的是顶点原始颜色还是插值后的颜色?
### 发生在光栅化阶段 是插值之后得到的颜色
### task5的内容
我修改了什么:
把 js/task5.js:62 的 drawArrays 的 mode 从任务2 的 gl.TRIANGLE_STRIP 改成 gl.LINE_STRIP,
顶点数据、顶点数量、顶点顺序、颜色全部保持与任务2 一致。
我原先预测:
还是那 4 个顶点,只是不再填充成面,而是按顺序用线段把它们连起来,
应该得到一条开口的折线(左上→左下→右上→右下),看不到填充的四边形。
实际结果:
出现一条线段链接起来的图形,没有闭合回路
原因解释:
因为 drawArrays 的 mode 只决定 GPU 如何解释同一串顶点,并不改变顶点本身。
LINE_STRIP 的规则是"按顶点顺序依次连接相邻两点形成线段",它画的是线而不是填充面,
所以四边形不闭合、内部也不被填充。