AI 协作日志
学生 Web 实验作品平台
学号:202412211401032 · 来源:ai-log.md
# 实验一 AI协作记录 > 学号:202412211401032 > 记录本人真实的 AI 协作过程,包含自己的判断、对照实验与核验结果。 ## AI协作1:理解数据流 ### 我的目标 在动手修改任务1之前,先弄清楚一组 JavaScript 顶点数据是怎样最终变成屏幕上的三角形的,并要求 AI 只解释、不改代码。 ### 提示词 > 从 JavaScript 的 Float32Array 到屏幕上出现一个三角形,中间发生了哪些关键步骤?请结合 WebGL2 解释 Buffer、vertexAttribPointer、Vertex Shader、光栅化和 Fragment Shader 各自负责什么,不要直接修改我的代码。 ### AI关键回答摘要 - `Float32Array` 只在 CPU 内存中;`gl.bufferData()` 才把数据真正复制到 GPU 的 Buffer 对象里。 - `vertexAttribPointer()` 不搬运数据,它告诉 GPU“从当前绑定的 ARRAY_BUFFER 中、按几个 float 一组、步距多少、偏移多少”去取数,并把这套读取规则登记到指定顶点属性上。 - Vertex Shader 逐顶点执行,输出 `gl_Position`;图元组装把顶点连成三角形;光栅化把三角形拆成片元;Fragment Shader 逐片元执行给出颜色。 ### 我的判断 AI 的说法大体可信,但“vertexAttribPointer 只是登记读取规则、数据归属在调用时绑定的 Buffer”这一点我之前理解模糊,我原以为“绑定到哪个 Buffer 决定一切”。需要对照代码逐项核验,而不是直接接受。 ### 验证方法 在 task1.html 和 js/task1.js 中逐项找对应代码并运行观察: | AI 所说环节 | 代码位置 | |---|---| | 顶点数据(CPU) | task1.js 中 `var vertices = new Float32Array([...])` | | 上传到 GPU Buffer | `gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)` | | 登记读取规则 | `gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0)` | | Vertex Shader | task1.html 中 `in vec4 vPosition; gl_Position = vPosition;` | | Fragment Shader | task1.html 中 `uniform vec4 uColor; fColor = uColor;` | | 绘制 | `gl.drawArrays(gl.TRIANGLES, 0, 3)` | ### 验证结果 页面正常显示紫色不等边三角形,Console 无错误。修改顶点后必须重新执行 `bufferData` 才看到形变,证明确实存在“CPU 数据 → GPU 副本”的复制过程。 ### 修正后的结论 - **修正点**:我最初以为 bindBuffer 之后属性就一直跟着“当前绑定”走。核验任务4双 Buffer 后明确:`vertexAttribPointer` 调用时会把当时绑定的 Buffer“记录”在该属性上,之后再 bind 别的 Buffer 不影响已登记好的属性。 - 任务1思考题回答: 1. `vertexAttribPointer` 指定每 2 个 float 为一组,GPU 按 (x, y) 切分连续内存,故连续两个数表示一个二维顶点。 2. Shader 声明 `vec4` 而只提供 2 个分量时,缺失的 z、w 自动补为 0、1,即 (x, y, 0, 1),所以绘制正常。 3. `drawArrays` 最后的 `3` 是**顶点数量**(3个顶点),不是数组中 float 的个数。 4. `bufferData` 是把数据从 CPU 复制到 GPU;只改 JS 数组,GPU 中的副本不会自动更新,必须重新上传。 --- ## AI协作2:程序调试 ### 现象 任务3完成后,左侧三角形正常,右侧四边形只显示了一半(一个三角形),且右半部分缺失。 ### 我的初步判断 怀疑是四边形 Buffer 数据没上传全,或顶点属性读取方式没重新设置。 ### 给AI的提示词 > 下面是一段 WebGL2 代码。第一个图形正常,第二个图形没有完整显示,只出现半个四边形。请不要重写完整程序,只列出最可能的3个原因,并告诉我应该通过什么现象、Console 信息或代码检查逐一验证。 ### AI给出的关键建议 最可能的3个原因: 1. `drawArrays` 的顶点数量参数错误(例如四边形仍写 3); 2. 绑定新 Buffer 后没有重新调用 `vertexAttribPointer`,属性仍指向三角形 Buffer; 3. `vertices` 数组本身少写了顶点。 并建议:Console 里打印 count;把鼠标/坐标与四个预期角点对照;单独检查第二次 drawArrays 的最后一个参数。 ### 我实际进行了什么测试 1. 检查 `quad` Float32Array:8 个 float,4 个顶点齐全,排除原因3。 2. 核对第二次绘制前的 `bindBuffer/vertexAttribPointer`:均已正确执行,排除原因2。 3. 定位到第二次绘制被我误写成 `gl.drawArrays(gl.TRIANGLE_STRIP, 0, 3)`。 4. 为验证该假设,在页面 Console 中直接执行: ```javascript gl.clear(gl.COLOR_BUFFER_BIT); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 3); // 复现:只有半个四边形 gl.clear(gl.COLOR_BUFFER_BIT); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); // 对照:完整四边形 ``` (render 执行后当前绑定的 ARRAY_BUFFER 正是四边形 Buffer,vPosition 也指向它,故可直接重绘。) ### 测试结果 count = 3 时稳定复现“半个四边形”;改回 4 后四边形完整,假设被证实。 ### 最终原因 第二次 `drawArrays` 的顶点数量误写为 3,TRIANGLE_STRIP 只用前 3 个顶点生成了一个三角形。 ### 是否采纳AI建议及理由 采纳。AI 没有代写代码,而是给出可逐一证伪的排查清单;我通过“检查数组→检查属性→检查 count”的顺序和 Console 对照实验定位问题,其中 count 检查最快验证,与其建议一致。 任务3其余思考题结论: - uniform 是 Program 运行期可改的状态值,不参与编译,改 uniform 只需 `gl.uniform4f`,无需重新编译 Shader。 - 若只设置一次 `uColor`,两个对象会是同一种颜色(uniform 值一直保留到下次修改)。 - 绑定新 Buffer 后必须重新 `vertexAttribPointer`,否则属性仍按旧规则从旧 Buffer 读数据。 - “当前 WebGL 状态影响后续绘制”体现在:当前绑定的 ARRAY_BUFFER、uniform 当前值、图元模式、顶点数量都决定下一次 drawArrays 的结果,所以第二次绘制前要逐一更新状态。 --- ## AI协作3:顶点属性与颜色 ### 我的目标 理解为什么 vPosition 每顶点读 2 个 float、vColor 每顶点读 4 个 float,并通过对照实验验证。 ### 提示词 > 在 WebGL2 中,位置属性 vPosition 每个顶点提供2个 float,而颜色属性 vColor 每个顶点提供4个 float。请从“GPU怎样按 vertexAttribPointer 的参数读取 Buffer 中连续数据”的角度解释两个属性的区别,不要只列参数定义。 ### AI关键回答摘要 GPU 把属性对应的 Buffer 看作连续字节流:size 决定每几个 float 打包成一个顶点的该属性,stride=0 表示紧密排列。因此位置 Buffer 按 [x,y][x,y]… 切分,颜色 Buffer 按 [r,g,b,a][r,g,b,a]… 切分;两条流按下标在同一次绘制中配对成同一个顶点。若颜色 size 写成 3,则改按 [r,g,b][r,g,b]… 从同一个颜色数组重新切分,顶点间数据会“错位”,第 4 分量取默认值 1。 ### 对照实验 页面正常加载后,在 Console 中执行(颜色数组为 [1,0,0,1, 0,1,0,1, 0,0,1,1]): ```javascript var loc = gl.getAttribLocation(program, "vColor"); gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0); // 4 临时改为 3 gl.clear(gl.COLOR_BUFFER_BIT); gl.drawArrays(gl.TRIANGLES, 0, 3); ``` ### 实际现象 三角形没有报错,但颜色变成“红 → 品红 → 蓝”的渐变,而不是正确的“红 → 绿 → 蓝”。恢复 size = 4 后颜色恢复正常。 ### 我的解释 size=3 时 GPU 按 3 个 float 一组重新切分颜色流:第1顶点读到 (1,0,0) 红;第2顶点读到的是数组第 4~6 个数 (1,0,1) 品红;第3顶点读到 (0,0,1) 蓝;alpha 缺省为 1。错位恰好解释了绿色顶点变品红的现象,AI 的“按 size 重新切分连续数据”的解释能够说明观察结果。 ### 最终结论 - 位置是二维坐标,所以每顶点读 2 个 float;颜色是 RGBA,所以读 4 个 float。 - 两个 Buffer 分别在各自的 `vertexAttribPointer` 中登记给 `vPosition` 与 `vColor`,绘制时按顶点下标配对。 - 三角形内部为连续渐变而非三块纯色,是因为光栅化阶段对顶点属性做了重心插值;Fragment Shader 收到的 `aColor` 是**插值后**的颜色,不是顶点原始颜色,插值发生在光栅化阶段。 --- ## 附:任务2对照实验记录(只改图元,顶点数据不变) | draw mode | 实际结果 | |---|---| | gl.TRIANGLE_STRIP | 完整填充四边形(2个三角形) | | gl.POINTS | 只剩4个孤立的点(顶点位置) | | gl.LINE_STRIP | 左上→左下→右上→右下 的3条线段折线,出现一条对角线、不闭合、不填充 | | gl.TRIANGLES | 4个顶点中只有前3个组成1个填充三角形,第4个顶点被忽略 | 结论:相同顶点数据,图元类型决定 GPU 如何把顶点“组装”成图元,所以结果不同;TRIANGLE_STRIP 中顶点顺序决定每相邻三个顶点如何生成三角形,顺序错乱会得到扭曲或错误的图形;4个顶点在 TRIANGLE_STRIP 下实际生成 4−2 = 2 个三角形。 --- ## 附:任务5记录 - 我修改了什么:将任务2的 4 个顶点原样复制,只把 mode 由 `gl.TRIANGLE_STRIP` 改为 `gl.LINE_STRIP`(颜色也保持任务2的绿色)。 - 我原先预测:会看到四边形的线框轮廓。 - 实际结果:没有填充,也不是完整线框,只有 左边、对角线、右边 三条线段,首尾不闭合。 - 原因解释:LINE_STRIP 严格按顶点提交顺序连接相邻顶点;为三角形条带设计的“之”字形顺序在折线解释下产生对角线,且 LINE_STRIP 不自动连接首尾。改用 `gl.LINE_LOOP` 可得到闭合轮廓(但仍不填充)。