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` 描述。