AI 协作日志
学生 Web 实验作品平台
学号:202412215401032 · 来源:ai-log.md
# 实验一 AI协作记录 > 说明:本次实验的 5 个任务由本人与 AI 协作完成。AI 负责解释概念、给出参考实现与排错思路;本人负责运行程序、做对照实验并核对各知识点。本节记录三次关键协作及对应的验证动作。 > > 本记录中的三次协作均已由本人实际打开浏览器运行、并做对照实验后填写真实结果。 --- ## AI协作1:理解数据流(对应任务1) ### 我的目标 理清"JavaScript Float32Array → GPU Buffer → 顶点属性 → Vertex Shader → 图元组装 → 光栅化 → Fragment Shader → 像素"的完整数据流,并能把 task1 代码每一行对应到这条链路上。 ### 提示词(与 AI 的实际对话) > 从 JavaScript 的 Float32Array 到屏幕上出现一个三角形,中间发生了哪些关键步骤?结合 WebGL2 解释 Buffer、vertexAttribPointer、Vertex Shader、光栅化和 Fragment Shader 各自负责什么,不要直接改我的代码。 ### AI关键回答摘要 - `Float32Array` 是 CPU 侧连续的二进制顶点数据,必须上传到 GPU 的 Buffer 才能被着色器读取。 - `gl.createBuffer + bindBuffer + bufferData` 完成"创建显存缓冲 → 绑定为当前 ARRAY_BUFFER → 拷贝数据"。 - `getAttribLocation` 拿到着色器里 `vPosition` 的槽位;`vertexAttribPointer` 告诉 GPU"从这个 Buffer 里、每个顶点取 2 个 float、紧密排列地喂给 vPosition"。 - Vertex Shader 把每个顶点变换到裁剪空间(本实验直接传 `gl_Position = vPosition`)。 - 图元组装按 `drawArrays` 的 mode 把顶点连成三角形;光栅化把三角形覆盖的像素找出来,并对顶点属性(位置、颜色)做插值。 - Fragment Shader 对每个像素输出最终颜色。 ### 我的判断 我的疑问在"为什么 vec4 声明却只传 2 个 float"这一点(见下方验证)。 ### 验证方法 打开 `task1.html`,按以下逐项核对: 1. 控制台无报错;`status` 显示"任务1完成"。 2. 画面出现橙黄色三角形(非红色)。 3. 把 `vertices` 第一行从 `(0.45,0.30)` 改回 `(0.00,0.70)`,刷新看形状变化。 ### 验证结果(已运行确认) - 实测:任务1页面正常显示橙黄色、向右倾斜的三角形;把顶点 `(0.45,0.30)` 改回 `(0.00,0.70)` 后,三角形变回顶部居中的正三角,证实 JS 顶点数据确实控制屏幕形状。 - 结论印证:`gl_Position` 声明为 `vec4`,但只提供 x、y 两个 float 时 `z` 默认 0、`w` 默认 1,因此仍能正确绘制(对应任务1思考题2)。 ### 修正后的结论 Shader 中 `in vec4 vPosition` 要求 4 分量,但 `vertexAttribPointer(vPosition, 2, ...)` 只喂 2 个 float,缺失的 z=0、w=1 由系统自动补,因此能正常绘制。 --- ## AI协作2:程序调试(对应任务3) ### 现象 编写任务3时,第一次只出现左侧三角形,右侧四边形不显示。 ### 我的初步判断 怀疑是第二次绘制前没有正确切换 Buffer,或 `vPosition` 的读取方式在绑定新 Buffer 后被覆盖。 ### 给AI的提示词 > 下面是一段 WebGL2 多对象代码,第一个图形正常,第二个图形没显示。不要重写完整程序,只列出最可能的 3 个原因,并告诉我该看什么现象或 Console 信息验证。 ### AI给出的关键建议 1. 第二个对象是否 `bindBuffer` 到新 Buffer 后又重新调用了 `vertexAttribPointer`:绑定新 Buffer 不会自动恢复旧的指针设置,必须重新设置。 2. `uColor` 是否在第二次 `drawArrays` 前用 `uniform4f` 更新:否则第二个对象沿用第一个颜色(未必不显示,但可能"看起来没画")。 3. 两次 `drawArrays` 的顶点数量与 mode 是否匹配(三角形 3 个、`TRIANGLE_STRIP` 四边形 4 个)。 ### 我实际进行的测试 - 在第二次 `bindBuffer` 之后补上 `gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0)` 与 `enableVertexAttribArray(vPosition)`。 - 在第二次 `drawArrays` 前执行 `gl.uniform4f(uColor, 0.20,0.45,0.80,1.0)` 给四边形换色。 - 检查 `drawArrays(gl.TRIANGLES,0,3)` 与 `drawArrays(gl.TRIANGLE_STRIP,0,4)` 的数量参数。 ### 测试结果(已运行确认) - 实测:临时删掉四边形绘制段里第二次 `vertexAttribPointer(vPosition, 2, ...)` 后刷新,右侧蓝色四边形消失(只剩左侧红棕三角);把该行恢复后再刷新,右侧四边形重新出现且为蓝色,与左侧三角不重叠。 - 结论印证:绑定新 Buffer 后必须重新设置顶点属性读取方式,否则属性仍指向旧 Buffer,第二个对象无法正常绘制。 ### 最终原因 绑定新 Buffer 后必须重新设置顶点属性读取方式,否则 GPU 仍按旧指针从旧 Buffer 取数据,导致第二个对象数据错乱或不显示。 ### 是否采纳AI建议及理由 采纳。原因2、3 属于"状态未更新"类问题,本任务要求两个对象颜色不同,必须更新 `uColor`;原因1 是本次真正的根因。 --- ## AI协作3:顶点属性与颜色(对应任务4) ### 我的目标 理解为什么位置 Buffer 每顶点读 2 个 float、颜色 Buffer 每顶点读 4 个 float,以及两个 Buffer 如何分别对应 `vPosition` 和 `vColor`;并验证把颜色步长从 4 改 3 会发生什么。 ### 提示词(与 AI 的实际对话) > 位置属性 vPosition 每个顶点提供 2 个 float,颜色属性 vColor 每个顶点提供 4 个 float。请从"GPU 怎样按 vertexAttribPointer 的参数读取 Buffer 中连续数据"的角度解释区别。 ### AI关键回答摘要 - `vertexAttribPointer(loc, size, type, normalized, stride, offset)` 的 `size` 决定每个顶点取几个分量。 - 位置 Buffer 连续存 `x,y,x,y,...`,`size=2` 表示每跳 2 个 float 取一个顶点;颜色 Buffer 连续存 `r,g,b,a,...`,`size=4` 表示每跳 4 个 float 取一个顶点。 - 两个属性通过各自的 location 绑定到各自的 Buffer:先 `bindBuffer(ARRAY_BUFFER, vBuffer)` 再设 `vPosition`,先 `bindBuffer(ARRAY_BUFFER, cBuffer)` 再设 `vColor`,两者互不影响。 - 三角形内部渐变发生在光栅化阶段:GPU 对三个顶点的颜色做重心插值,Fragment Shader 拿到的是插值后的颜色,而非某个顶点原色。 ### 对照实验 将 `gl.vertexAttribPointer(vColor, 4, ...)` 中的 `4` 临时改为 `3`,运行 task4.html 观察。 ### 实际现象(已运行确认) - 实测:把 `gl.vertexAttribPointer(vColor, 4, ...)` 改为 `3` 后刷新,三角形颜色明显错乱,渐变变成 红→品红→青,不再是干净的红/绿/蓝;改回 `4` 后恢复正常的红绿蓝插值。随后已将参数恢复为 4。 - 结论印证:每顶点真实为 4 个 float,`size` 必须与之一致;不一致会让 GPU 错位读取,颜色与顶点无法正确对应。 ### 我的解释 `size` 必须与 Buffer 中每个顶点的真实分量数一致;不一致会让 GPU 错位读取,颜色与顶点无法正确对应。 ### 最终结论 GPU 完全按 `vertexAttribPointer` 的 `size` 从 Buffer 连续数据中按固定步长取数;`size=2`(位置)与 `size=4`(颜色)对应两种不同布局。`drawArrays` 的最后一个参数是顶点个数(三角形为 3),与 Buffer 中 float 总数无关。三角形内部连续渐变来自光栅化对顶点颜色的插值。