AI 协作日志
学生 Web 实验作品平台
学号:202412211401001 · 来源:ai-log.md
# 实验一 AI协作记录 > 本文件记录实验一过程中与AI的3次关键协作,包含提示词、AI建议、自己的判断、测试与核验结果。 ## AI协作1:理解数据流 ### 我的目标 理解从 JavaScript 的 Float32Array 到屏幕上出现一个三角形,中间发生了哪些关键步骤,并在自己的 task1 代码中找到每个步骤对应的代码。 ### 提示词 > 从 JavaScript 的 Float32Array 到屏幕上出现一个三角形,中间发生了哪些关键步骤?请结合 WebGL2 解释 Buffer、vertexAttribPointer、Vertex Shader、光栅化和 Fragment Shader 各自负责什么,不要直接修改我的代码。 ### AI关键回答摘要 1. **Float32Array**:在 CPU 端把顶点数据按连续 float 排列,是上传 GPU 的数据源。 2. **createBuffer / bindBuffer / bufferData**:在 GPU 端申请显存、绑定到 `ARRAY_BUFFER` 目标、把 Float32Array 的内容上传到该显存。 3. **vertexAttribPointer**:告诉 GPU 如何从当前绑定的 Buffer 中"切片"读取每个顶点的属性——每几个 float 为一个顶点、数据类型、是否归一化、步长、偏移。 4. **Vertex Shader**:对每个顶点执行一次,把属性(如 `vPosition`)变换为裁剪空间坐标 `gl_Position`。 5. **图元组装 + 光栅化**:按 draw mode 把顶点组成图元,再对图元内部像素插值,生成 Fragment。 6. **Fragment Shader**:对每个 Fragment 执行一次,输出最终像素颜色(本任务中读取 uniform `uColor`)。 ### 我的判断 AI 给出的6步与实验指导书第1节的数据流图一致,应在 task1.js 中逐项找到对应代码。 ### 验证方法 在 task1.js 中逐项核验: - `new Float32Array([...])` → 顶点数据; - `gl.createBuffer()` / `gl.bindBuffer()` / `gl.bufferData()` → Buffer 创建与上传; - `gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0)` → 顶点属性读取方式; - `#version 300 es` 的 Vertex Shader 中 `gl_Position = vPosition` → 顶点变换; - `gl.drawArrays(gl.TRIANGLES, 0, 3)` → 图元组装与光栅化; - Fragment Shader 中 `fColor = uColor` → Fragment 输出颜色。 ### 验证结果 6个环节在 task1.html 与 task1.js 中均能找到对应代码,AI 描述与实际代码一一吻合。 ### 修正后的结论 我最初以为 `vertexAttribPointer` 只是"开启属性",核验后明白它真正的职责是**规定 GPU 从 Buffer 中按多大步长、几个分量读取一个顶点属性**——这是 Buffer 中连续 float 能够被正确切片为顶点的关键。此外我也修正了一个误解:Vertex Shader 是**逐顶点**执行,Fragment Shader 是**逐像素**执行,二者执行频率不同。 --- ## AI协作2:程序调试 ### 现象 完成任务3时,左侧三角形正常显示为蓝色,但右侧四边形完全没有出现(区域为空白)。 ### 我的初步判断 我最初怀疑是四边形顶点坐标写错导致超出可视范围,或者 `uColor` 没有切换。 ### 给AI的提示词 > 下面是一段 WebGL2 代码。第一个图形正常,第二个图形没有显示。请不要重写完整程序,只列出最可能的3个原因,并告诉我应该通过什么现象、Console 信息或代码检查逐一验证。 ### AI给出的关键建议 最可能的3个原因: 1. 第二次绘制前没有重新 `bindBuffer` 绑定四边形的 Buffer,GPU 仍读取三角形的 Buffer。 2. 绑定新 Buffer 后没有再次调用 `vertexAttribPointer`,顶点属性仍指向旧 Buffer 的读取方式。 3. `drawArrays` 的 mode 或顶点数量写错(例如四边形用 `TRIANGLES` 却只传4个顶点)。 ### 我实际进行的测试 1. 在四边形绘制前加 `console.log(quad.length / 2)` 确认顶点数为 4,排除数量错误。 2. 检查代码发现:我绑定了新的 `qBuffer`,但**漏掉了再次调用 `gl.vertexAttribPointer(vPosition, ...)` 和 `gl.enableVertexAttribArray(vPosition)`**。 3. 在四边形绘制代码块中补上这两行后重新运行。 ### 测试结果 补上 `vertexAttribPointer` 与 `enableVertexAttribArray` 后,右侧绿色四边形正常显示。 ### 最终原因 绑定新 Buffer 后,WebGL **不会自动**把已启用的顶点属性重新指向新 Buffer 的读取方式,必须再次调用 `vertexAttribPointer` 让属性指向当前绑定的 Buffer。 ### 是否采纳AI建议及理由 采纳。AI 给出的第2条正是问题根源。理由是:`vertexAttribPointer` 隐式记录"当前绑定的 ARRAY_BUFFER",换 Buffer 后必须重新设置一次,否则属性仍按旧 Buffer 的布局读取。这也印证了指导书中"当前 WebGL 状态会影响后续绘制"的提示。 --- ## AI协作3:顶点属性 ### 我的目标 理解任务4中为什么位置属性 `vPosition` 每个顶点提供2个 float,而颜色属性 `vColor` 每个顶点提供4个 float,从 GPU 按 `vertexAttribPointer` 读取 Buffer 的角度解释二者区别。 ### 提示词 > 在 WebGL2 中,位置属性 vPosition 每个顶点提供2个 float,而颜色属性 vColor 每个顶点提供4个 float。请从"GPU怎样按 vertexAttribPointer 的参数读取 Buffer 中连续数据"的角度解释两个属性的区别,不要只列参数定义。 ### AI关键回答摘要 `vertexAttribPointer` 的第二个参数 `size` 决定 GPU 每次为一个顶点从 Buffer 中连续读取几个 float 分量: - 位置 Buffer:`size=2`,GPU 每读2个 float 就得到一个顶点的,步长为 2×4=8 字节,下一个顶点紧随其后。 - 颜色 Buffer:`size=4`,GPU 每读4个 float 得到一个顶点的,步长为 4×4=16 字节。 GPU 按顶点索引依次推进读取指针,`size` 不同意味着"每个顶点占用的连续 float 数量"不同,但只要 Buffer 中的数据排列与之匹配,就能正确切片。两个属性各自绑定独立的 Buffer,互不干扰。 ### 对照实验 将颜色属性的 `vertexAttribPointer` 中的 `4` 临时改为 `3`: ```javascript gl.vertexAttribPointer(vColor, 3, gl.FLOAT, false, 0, 0); ``` 其余代码不变,运行观察。 ### 实际现象 三角形仍能绘制出来,但颜色出现明显偏差:原应为蓝色的第三个顶点变成了接近黑色的暗色,整体颜色插值结果与原 RGB 渐变不一致。原因是每个顶点只读取了 R、G、B 三个分量,第4个分量(A,以及下一个顶点的起始分量)读取错位,导致颜色数据被错误切片。 ### 我的解释 `size=3` 让 GPU 每个顶点只读3个 float,但 `colors` 数组中每个顶点实际存了4个 float(RGBA)。读取指针推进按 size=3 计算,于是从第2个顶点开始读到的不是该顶点的 R、G、B,而是上一顶点的 A 与本顶点的 R、G,颜色数据整体错位。这证明了 `size` 参数直接控制 GPU 对 Buffer 连续数据的切片方式。 ### 最终结论 `vertexAttribPointer` 的 `size` 参数必须与 Buffer 中每个顶点实际存储的分量数严格一致。位置属性每个顶点2个 float(xy),颜色属性每个顶点4个 float(RGBA),因此分别使用 `size=2` 与 `size=4`。AI 从"GPU 按指针推进读取连续数据"角度给出的解释能够完整说明观察到的错位现象,验证通过。