AI 协作日志

学生 Web 实验作品平台

学号:202412211401028 · 来源:ai-log.md

# 实验一 AI协作记录

> 本文档记录本次实验过程中与AI协作的3个关键过程,包含我的判断、测试和核验。

---

## AI协作1:理解数据流

### 我的目标
弄清从 JavaScript 的 `Float32Array` 到屏幕上出现三角形,中间发生了哪些关键步骤,并能在 task1.html / js/task1.js 中逐项找到对应代码。

### 提示词
> 从 JavaScript 的 Float32Array 到屏幕上出现一个三角形,中间发生了哪些关键步骤?请结合 WebGL2 解释 Buffer、vertexAttribPointer、Vertex Shader、光栅化和 Fragment Shader 各自负责什么,不要直接修改我的代码。

### AI关键回答摘要
1. **Buffer**:GPU 端显存中的字节数组,用来存储顶点数据。`createBuffer` 只是分配对象,`bindBuffer` 把它绑定到 `gl.ARRAY_BUFFER` 这个挂载点,`bufferData` 才把 `Float32Array` 的字节真正上传到 GPU。
2. **vertexAttribPointer**:告诉 GPU “当前绑定的 Buffer”应如何被某个顶点属性读取——从第几个 float 开始、每次读几个 float、什么类型、是否归一化、步幅、偏移。
3. **Vertex Shader**:对每个顶点执行一次,把 `in` 变量(如 `vPosition`)转换成 `gl_Position`,并可向 Fragment Shader 输出 `out` 变量。
4. **图元组装 / 光栅化**:根据 `drawArrays` 的 mode 把顶点组合成图元(三角形),再生成覆盖像素的片元,并对顶点输出变量做插值。
5. **Fragment Shader**:对每个片元执行一次,决定该像素的颜色,输出到 `fColor`。

### 我的判断
我原以为 `vertexAttribPointer` 只是“绑定属性名”,AI 提到它还描述了数据布局(每次2个float vs 4个float),这点我之前理解不清。

### 验证方法
在 task1.js 中逐项对应:
- `gl.createBuffer()` / `gl.bindBuffer()` / `gl.bufferData()` → Buffer 建立与上传;
- `gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0)` → 位置属性每顶点读2 float;
- `in vec4 vPosition;` → Vertex Shader 输入;
- `gl.drawArrays(gl.TRIANGLES, 0, 3)` → 图元组装/光栅化入口;
- `fColor = uColor;` → Fragment Shader 输出。

### 验证结果
代码中每一项均能找到对应位置。我还把 `vertexAttribPointer` 第2个参数从 `2` 临时改成 `4`,三角形立即消失——验证了“size 描述每顶点读取的 float 数量”。

### 修正后的结论
最初我以为 `in vec4 vPosition` 决定了“每个顶点4个 float”,事实上 Shader 中的 `vec4` 只是 Shader 内部表示,GPU 实际读取多少数据完全由 `vertexAttribPointer` 决定,shader 会把 `vec2` 自动补齐为 `vec4`(z=0, w=1)。Shader 类型与 Buffer 数据布局是两个独立的事。

---

## AI协作2:程序调试

### 现象
在 task3 中,第一个三角形能正常显示,但第二个四边形不显示。

### 我的初步判断
我怀疑是 Shader 编译失败,或者顶点数据写错了。

### 给AI的提示词
> 下面是一段 WebGL2 代码。第一个图形正常,第二个图形没有显示。请不要重写完整程序,只列出最可能的3个原因,并告诉我应该通过什么现象、Console 信息或代码检查逐一验证。

### AI给出的关键建议
最可能的3个原因:
1. **未对新 Buffer 重新调用 `vertexAttribPointer`**:绑定新的 `ARRAY_BUFFER` 不会自动更新属性读取来源,GPU 仍指向旧 Buffer,但因为旧 Buffer 数据量较少,可能导致读取越界或不绘制。
2. **顶点数量 / draw mode 写错**:四边形用 `TRIANGLE_STRIP` 需要4个顶点,若误写 `TRIANGLES` 会变成1个三角形;若把顶点数误填为2则只画1条线段。
3. **uniform 颜色被设置成了背景色或 alpha=0**:四边形被绘制了,但与背景同色不可见。

### 我的实际进行测试
1. 在 `bindBuffer(quadBuffer)` 之后立即 `console.log(gl.getParameter(gl.ARRAY_BUFFER_BINDING))`,确认绑定到了 quadBuffer;
2. 检查代码发现:我**确实忘了**在绑定新 Buffer 后重新 `vertexAttribPointer`;
3. 补上 `gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);` 和 `enableVertexAttribArray` 后再运行。

### 测试结果
补上 `vertexAttribPointer` 后四边形正常显示。说明第二个对象之所以消失,是因为属性指针仍指向第一个 Buffer 的内存布局,新 Buffer 的数据未被正确解读。

### 最终原因
**绑定新 Buffer 后未重新设置 `vertexAttribPointer`**。WebGL 是状态机,`ARRAY_BUFFER` 绑定和属性指针是两个独立状态,必须都更新。

### 是否采纳AI建议及理由
采纳。AI 的3个假设中第1个命中,且其推理(“属性指针指向旧 Buffer”)与我的测试现象一致。同时第2、3个假设也提醒我检查 mode 和 uniform 颜色,均正常。

---

## AI协作3:顶点属性与颜色

### 我的目标
理解为什么位置属性 `vPosition` 每顶点2个 float,颜色属性 `vColor` 每顶点4个 float,以及两个 Buffer 是如何分别对应到这两个属性的。

### 提示词
> 在 WebGL2 中,位置属性 vPosition 每个顶点提供2个 float,而颜色属性 vColor 每个顶点提供4个 float。请从“GPU怎样按 vertexAttribPointer 的参数读取 Buffer 中连续数据”的角度解释两个属性的区别,不要只列参数定义。

### AI关键回答摘要
- `vertexAttribPointer(location, size, type, normalized, stride, offset)` 中的 `size` 表示**一个顶点**读取多少个 `type` 分量;
- GPU 把 Buffer 看作连续字节流,按 `(顶点索引 × stride + offset)` 计算读取起点;
- 位置 Buffer 每顶点2 float(8字节),颜色 Buffer 每顶点4 float(16字节);
- 不同属性只要 `bindBuffer` 后 `vertexAttribPointer` 即可绑定到不同 Buffer,因为属性指针记录了“当前 ARRAY_BUFFER”的引用。

### 对照实验
把颜色属性的 `vertexAttribPointer` 中的 `4` 临时改为 `3`:
```javascript
gl.vertexAttribPointer(vColor, 3, gl.FLOAT, false, 0, 0);
```
(仍保持数据 Buffer 中每顶点4个 float)

### 实际现象
三角形仍然显示,但颜色出现异常:
- 每个顶点只读取了 R、G、B 三个分量;
- 第二个顶点的第4个 float(A=1.0)被当作下一个顶点的 R 分量;
- 第三个顶点的读取起点偏移,颜色错位;
- 三角形整体颜色不再纯净的红绿蓝,且边缘出现半透明感。

### 我的解释
`size=3` 告诉 GPU 每顶点只读3 float,于是 GPU 按“每顶点12字节”解读颜色 Buffer;但实际数据是按“每顶点16字节”排列的,导致后续顶点读取的起点错位,颜色串行错乱。

### 最终结论
`vertexAttribPointer` 的 `size` 必须与 Buffer 中每个顶点实际存储的 float 数量一致,否则 GPU 会按错误的步长解读字节流,颜色属性对不齐。这印证了 AI 的说法:Buffer 只是字节流,数据含义完全由 `vertexAttribPointer` 描述。