AI 协作日志
学生 Web 实验作品平台
学号:202412211401014 · 来源:ai-log.md
# 实验一 AI协作记录 > 请记录本人真实的AI协作过程。不要只粘贴AI生成结果,应体现自己的判断、测试和核验。 ## AI协作1:理解数据流 ### 我的目标 弄清楚:`js/task1.js` 里的 `Float32Array` 是怎样变成 Canvas 上那个青绿色三角形的。任务1要求先解释再对照代码核验,不要只听概念。 ### 提示词 从 JavaScript 的 Float32Array 到屏幕上出现一个三角形,中间发生了哪些关键步骤?请结合 WebGL2 解释 Buffer、vertexAttribPointer、Vertex Shader、光栅化和 Fragment Shader 各自负责什么,不要直接修改我的代码。 ### AI关键回答摘要 AI 把流水线拆成几段: 1. `Float32Array` 只在 CPU 侧,必须 `createBuffer` + `bindBuffer` + `bufferData` 才进入 GPU。 2. `vertexAttribPointer(vPosition, 2, FLOAT, false, 0, 0)` 告诉 GPU:当前 `ARRAY_BUFFER` 里每 2 个 float 组成一个顶点的 xy。 3. Vertex Shader 用 `in vec4 vPosition` 接收,并写到 `gl_Position`。 4. `drawArrays(TRIANGLES, 0, 3)` 把 3 个顶点组装成一个三角形,光栅化生成片元。 5. Fragment Shader 用 `uniform vec4 uColor` 给每个片元上色,输出到 `out vec4 fColor`。 ### 我的判断 这段描述和指导书第 1 节的数据流一致。我原先有两点含糊:一是以为改了 JS 数组屏幕就会立刻变;二是不明白 Shader 里是 `vec4`、JS 里却只传 2 个 float。需要对着 `task1.html` / `js/task1.js` 逐项找对应代码。 ### 验证方法 1. 在 `task1.html` 找到 `#version 300 es` 的 Vertex / Fragment Shader,确认 `in vec4 vPosition`、`uniform vec4 uColor`、`out vec4 fColor`。 2. 在 `js/task1.js` 按注释核对:顶点数据 → 创建并绑定 Buffer → 上传数据到 GPU → `vertexAttribPointer` → `uniform4f` → `drawArrays`。 3. 实际改第三个顶点为 `(0.15, -0.75)`,颜色改为 `(0.05, 0.62, 0.68, 1.0)`,用本地 HTTP 打开 `task1.html` 看形状和颜色是否一起变。 4. 对照:只改数组、不重新执行 `bufferData` 的话,GPU 里仍是旧数据(本程序每次刷新都会重新 `bufferData`,所以要靠“刷新才变”来理解这一点)。 ### 验证结果 - 刷新后三角形明显向左下倾斜,颜色是青绿而不是红,说明顶点 Buffer 和 `uColor` 都生效。 - 代码位置都能对上,没有出现 Console 报错。 - `vertexAttribPointer` 的 size 确实是 `2`,与 Shader 的 `vec4` 并存,三角形仍能画出来。 ### 修正后的结论 我修正了两个概念: 1. JS 数组不会自动同步到 GPU,必须经过 `bufferData`。 2. size=2 时,GPU 只填 `vPosition.xy`,`z` 默认 0、`w` 默认 1,所以 `in vec4` 仍然合法。`drawArrays` 最后的 `3` 是顶点个数,不是 float 个数(数组里有 6 个 float)。 --- ## AI协作2:程序调试 ### 现象 任务3第一次写完后,左侧橙色三角形、右侧蓝色四边形都能显示,两个对象也不重叠。指导书要求:若一次成功,应人为制造小错误再走一遍排错闭环。于是把右侧 ```javascript gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); ``` 临时改成 ```javascript gl.drawArrays(gl.TRIANGLE_STRIP, 0, 3); ``` 刷新后:左边三角形还在,右边不再是矩形,只剩一块蓝色直角三角形。 ### 我的初步判断 颜色、Shader、左侧对象都正常,更像是“第二个对象的绘制数量或图元解释”出了问题,而不是 WebGL2 上下文失败。我当时还怀疑过:是不是绑定了新 Buffer 却没再设 `vertexAttribPointer`。 ### 给AI的提示词 下面是一段 WebGL2 代码。第一个图形正常,第二个图形没有显示(或显示不完整)。请不要重写完整程序,只列出最可能的3个原因,并告诉我应该通过什么现象、Console 信息或代码检查逐一验证。 ### AI给出的关键建议 AI 给了 3 个优先假设(要求不要整段重写): 1. 第二次 `drawArrays` 的顶点数量或 draw mode 不对。验证:看缺的是整块还是缺一个角;对照 Buffer 里实际有几个顶点。 2. 换 Buffer 之后没有再次 `vertexAttribPointer` / `enableVertexAttribArray`。验证:第二个对象可能仍在用第一个 Buffer 的数据,形状会“跟着三角形走”。 3. `uColor` 的 location 拿错或第二次没更新。验证:两个对象颜色相同,或第二个完全透明/黑色。 并建议先看 Console 有没有 JS 异常,再逐项改回一个参数做对照。 ### 我实际进行的测试 1. 打开开发者工具:没有红色 JS 报错,页面状态栏仍显示“两次 drawArrays”,说明程序跑完了,不是中途 throw。 2. 颜色仍是橙 + 蓝,排除假设 3。 3. 右侧图形位置仍在画布右半边,没有跑到左边三角形的坐标上,说明第二次绑定的仍是四边形 Buffer,不太像假设 2。 4. 右侧正好缺掉右下角那一块:`TRIANGLE_STRIP` 用前 3 个顶点(左上、左下、右上)只会拼出 1 个三角形,第 4 个顶点(右下)没被用到。这与假设 1 完全对得上。 5. 把最后一个参数改回 `4` 后再刷新。 ### 测试结果 改回 `4` 后右侧重新变成完整蓝色矩形。对照实验可以复现:`3` → 缺一块;`4` → 完整。 ### 最终原因 不是 Buffer 没绑上,而是 `drawArrays` 的顶点数量写成了 3。最后一个参数是顶点个数。`TRIANGLE_STRIP` 用 3 个顶点只能出 1 个三角形,4 个顶点才是 2 个三角形组成的四边形。 ### 是否采纳AI建议及理由 采纳假设 1,并用现象排除了 2 和 3。这次最有用的不是 AI 直接改代码,而是它给出的“用颜色、位置、缺角形状来区分三种原因”的验证顺序。 --- ## AI协作3:顶点属性与颜色 ### 我的目标 搞清楚任务4里为什么位置属性每个顶点读 2 个 float、颜色属性读 4 个 float,以及把颜色的 size 改成 3 时会发生什么。 ### 提示词 在 WebGL2 中,位置属性 vPosition 每个顶点提供2个 float,而颜色属性 vColor 每个顶点提供4个 float。请从“GPU怎样按 vertexAttribPointer 的参数读取 Buffer 中连续数据”的角度解释两个属性的区别,不要只列参数定义。 ### AI关键回答摘要 AI 强调:`ARRAY_BUFFER` 只是一串连续 float。真正“怎么切成每个顶点一份”的是 `vertexAttribPointer` 的 **size** 和 **stride**。 - 位置 Buffer:`size=2, stride=0` → 每顶点连续取 xy,下一个顶点紧挨着。 - 颜色 Buffer:`size=4, stride=0` → 每顶点连续取 RGBA。若改成 `size=3`,GPU 仍按 3 个 float 一组往下切,原来按 RGBA 排好的数据会被错位:第 1 个顶点的 A 会变成第 2 个顶点的 R,后面的颜色全部错位;`vec4` 缺的那个分量会用默认值(通常 w=1)。 两个 Buffer 能分别接到 `vPosition` 和 `vColor`,是因为绑定谁、就对谁调用 `getAttribLocation` + `vertexAttribPointer`。属性槽记住的是“当时那个 Buffer + 切法”,不是全局一份数据。 ### 对照实验 按指导书把 ```javascript gl.vertexAttribPointer(vColor, 4, gl.FLOAT, false, 0, 0); ``` 临时改成 `size = 3`,刷新 `task4.html`,看完再改回 `4`。 ### 实际现象 正确 `size=4`:顶红、左下绿、右下蓝,内部是连续渐变。 错误 `size=3`:顶仍偏红,但左下变成品红/粉,右下变成绿,原来的纯蓝顶点消失。三角形内部仍有渐变,只是三个角的颜色已经不是红绿蓝。Console 没有报错。 ### 我的解释 颜色数组实际是: ```text 1,0,0,1, 0,1,0,1, 0,0,1,1 ``` `size=3` 时按 3 个一组读取: - 顶点0:`(1,0,0)` → 红,w 默认 1 - 顶点1:`(1,0,1)` → 品红(吃进了上一顶点的 A 和下一个顶点的 RG) - 顶点2:`(0,1,0)` → 绿 这正好对上截图。说明 AI 说的“按 size 切连续 Buffer”能解释现象,不是单纯参数定义问题。 渐变仍然存在,是因为光栅化阶段仍会在三个(已经错位的)顶点颜色之间插值。Fragment Shader 拿到的是插值后的 `aColor`,不是三个顶点的原始常数色块。 ### 最终结论 1. 位置读 2 个 float 是因为只要 clip 空间 xy;颜色读 4 个 float 是因为 RGBA 四个分量都要。 2. 两个属性靠“绑定不同 Buffer + 各自 vertexAttribPointer”对应到 `vPosition` / `vColor`。 3. 内部渐变发生在光栅化插值,不在 Fragment Shader 里重新计算三个区域。 4. AI 对 `size=3` 错位的解释与对照实验一致,已恢复为 `4`。 --- ## 任务2 图元对照(控制变量) 顶点数据始终是左上、左下、右上、右下四个点,只改 draw mode: | 图元 | 观察到的结果 | |---|---| | `TRIANGLE_STRIP`(提交版) | 完整绿色填充矩形,由两个三角形组成 | | `POINTS` | 四个角上各一个点,无边无面 | | `LINE_STRIP` | 折线:左上→左下→右上→右下,中间有对角线,无填充 | | `TRIANGLES` | 只画前 3 个顶点构成的一个三角形,第 4 个顶点闲置 | 必须回答: 1. 相同顶点数据得到不同图形,是因为图元组装规则不同,Buffer 本身没变。 2. `TRIANGLE_STRIP` 按 (v0,v1,v2)、(v2,v1,v3) 的方式出三角形,顺序错了会交叉或缺面。 3. 4 个顶点的 strip 实际组成 **2** 个三角形。 --- ## 任务5 探究记录(页面中同步写了一份) 我修改了什么:draw mode 从 `TRIANGLE_STRIP` 改为 `LINE_STRIP`,顶点、顺序、颜色与任务2相同。 我原先预测:不再填充,会连成带对角线的折线。 实际结果:与预测一致,绿色折线,无填充。 原因解释:`LINE_STRIP` 只连接相邻顶点,不组装三角形。