1. 三个模型同台做3D游戏我为什么选了这个题目最近圈子里讨论度比较高的几款模型Step 5 Preview、DeepSeek V4 Pro、GLM5.3单看跑分和榜单其实拉不开太大差距真正能看出功力的还是让它们干同一件脏活累活。我这次选的题目是做一个能跑起来的3D游戏原型不是那种只输出一段代码片段就完事的演示而是从场景搭建、角色控制、碰撞检测到相机跟随一整套逻辑都要落地。为什么挑3D游戏因为3D游戏开发天然是个多面手测试场。它同时考验模型的几项能力空间几何理解、向量数学、状态机设计、渲染管线的基本认知还有最容易被忽略的——代码能不能真的跑起来。很多模型写2D小游戏很溜一到3D就开始胡编API把Three.js和Babylon.js的接口混着用或者把四元数和欧拉角搞反跑起来角色直接原地打转。我这次用的开发环境是WorkBuddy作为工作台来组织整个项目把三个模型的产出分别放在独立的会话里跑避免上下文互相污染。WorkBuddy的好处是它能跨对话记住项目结构我在一个会话里定义了目录约定和依赖版本后面几个会话都能直接复用不用每次重新交代一遍。这一点在做对比测试的时候特别关键否则光是环境描述就能把上下文窗口吃掉一大半。先说结论免得你看到最后才发现方向不对三个模型都能产出看起来像那么回事的3D游戏代码但能一次跑通、逻辑自洽、后续可扩展的只有Step 5 Preview。DeepSeek V4 Pro在数学计算上最扎实但工程组织偏弱GLM5.3的代码风格最讨喜注释写得像教科书可惜在3D空间变换上翻了几次车。下面我把整个实测过程拆开讲包括我怎么设计测试用例、每个模型具体卡在哪、以及最后怎么把能跑的版本整合起来。2. 测试用例设计一个3D游戏原型到底要包含什么2.1 需求清单的取舍逻辑我没有一上来就让模型做个3D游戏这种模糊指令只会得到一堆无法运行的碎片。我把需求拆成了六个必须落地的模块每个模块都有明确的验收标准场景初始化一个地面平面加若干障碍物方块使用基础几何体即可不追求美术效果角色控制WASD移动鼠标控制视角朝向移动方向要跟随相机朝向物理基础重力、跳跃、与地面的碰撞、与障碍物的水平碰撞相机系统第三人称跟随带平滑插值不能出现穿墙或抖动游戏循环固定时间步长的更新逻辑避免帧率波动导致物理异常可运行性给出完整的HTML文件或可执行的项目结构依赖通过CDN或明确版本号引入这六项里前三项是核心后三项是区分能跑和能玩的分水岭。我见过太多模型生成的3D代码角色能动但相机是死的或者物理更新直接绑在requestAnimationFrame上帧率一高角色就飞出去。2.2 为什么用Three.js而不是原生WebGL选Three.js作为渲染层是经过考虑的。原生WebGL的样板代码太多模型很容易在着色器编译或者缓冲区绑定上出错那样测出来的就不是逻辑能力而是记忆能力了。Three.js把渲染细节封装好了模型只需要关注场景图、变换矩阵和向量运算这恰好是3D游戏逻辑的核心。另外Three.js的API在训练数据里覆盖度足够高三个模型都应该见过大量示例。如果连Three.js都写不利索那说明模型在3D领域的泛化能力确实有问题。提示测试3D代码时一定要在需求里明确渲染库和版本。我这次统一指定Three.js r160通过CDN引入。不指定版本的话模型可能用已经废弃的Geometry类而不是BufferGeometry跑起来直接报错。2.3 验收标准的量化光说能跑太主观我定了几个可量化的检查点检查项通过标准检测方式页面加载无控制台报错打开DevTools看Console角色移动WASD四方向响应正确手动按键测试相机跟随角色移动时相机平滑跟随无抖动目视观察跳跃物理起跳后能落回地面不穿透连续跳跃测试碰撞检测撞墙停下不穿模朝障碍物移动帧率稳定60fps下物理不异常观察角色速度这套标准看起来简单但实际跑下来三个模型里只有Step 5 Preview全部通过。下面逐个拆解。3. Step 5 Preview一次跑通的工程化表现3.1 项目结构的第一印象Step 5 Preview给我的第一份产出就有点意外。它没有把所有代码塞进一个HTML文件而是主动拆成了几个模块index.html src/ main.js player.js camera.js world.js physics.js这个拆分不是花架子。main.js负责初始化和游戏循环player.js封装角色状态和输入处理camera.js单独处理相机插值world.js管理场景物体physics.js做碰撞和重力。每个文件职责清晰后续我要改跳跃高度只需要动physics.js里的一个常量。我在WorkBuddy里给它定的规则是模块化优先单文件不超过200行它确实遵守了。这一点在后续调试时省了大量时间因为报错信息能直接定位到具体模块。3.2 角色控制里的向量运算细节角色移动这块Step 5 Preview的处理方式值得单独说。它没有简单地把WASD映射到世界坐标的XYZ而是先获取相机的朝向向量然后把输入方向投影到相机所在的水平面上。核心逻辑大概是这样// 获取相机的前方向和右方向投影到水平面 const forward new THREE.Vector3(); camera.getWorldDirection(forward); forward.y 0; forward.normalize(); const right new THREE.Vector3(); right.crossVectors(forward, new THREE.Vector3(0, 1, 0)).normalize(); // 根据输入组合移动方向 const moveDir new THREE.Vector3(); if (keys.w) moveDir.add(forward); if (keys.s) moveDir.sub(forward); if (keys.d) moveDir.add(right); if (keys.a) moveDir.sub(right); moveDir.normalize();这段代码的关键在于forward.y 0这一步。如果不把Y分量清零当相机俯视时角色会往地下钻。这是个非常经典的坑很多模型生成的代码就栽在这里。Step 5 Preview不仅清零了还做了归一化保证斜向移动不会比直线移动快。3.3 相机平滑跟随的实现取舍相机跟随它用了球坐标加插值的方式。相机位置由角色位置加上一个偏移向量决定偏移向量用球坐标表示鼠标移动改变方位角和俯仰角。然后每帧用lerp把相机从当前位置插值到目标位置。const targetPos new THREE.Vector3().copy(player.position).add(offset); camera.position.lerp(targetPos, 1 - Math.pow(0.001, deltaTime));这里用1 - Math.pow(0.001, deltaTime)而不是固定系数是为了让插值速度与帧率无关。固定系数的话帧率越高相机跟得越紧帧率低就跟不上。这个细节说明模型对游戏循环的时间步长有正确认知。3.4 物理更新的固定时间步长物理这块它用了累加器模式let accumulator 0; const fixedStep 1 / 60; function animate() { const delta clock.getDelta(); accumulator delta; while (accumulator fixedStep) { updatePhysics(fixedStep); accumulator - fixedStep; } render(); }固定步长意味着无论显示器是60Hz还是144Hz物理表现完全一致。这是游戏开发的标准做法但能主动写出来的模型不多。DeepSeek V4 Pro和GLM5.3都是直接把delta传给物理更新在高刷屏上会出现跳跃高度不一致的问题。3.5 实测中唯一需要手动修的地方Step 5 Preview也不是完美。它生成的碰撞检测用的是AABB轴对齐包围盒对于方块障碍物没问题但角色本身是个胶囊体用AABB近似会导致贴墙时有一点视觉穿插。我手动把角色的碰撞盒缩小了10%问题就解决了。这个不算模型的锅AABB是原型阶段的合理选择OBB或者胶囊体碰撞的实现复杂度高很多在需求里我也没明确要求。整体来说Step 5 Preview的产出是三个里唯一做到打开就能玩的。4. DeepSeek V4 Pro数学最稳工程最散4.1 向量和矩阵运算的扎实功底DeepSeek V4 Pro在数学层面的表现是三个里最好的。它处理四元数旋转、向量投影、射线检测这些内容时公式推导完全正确没有出现轴向搞反或者归一化遗漏的问题。比如它实现角色朝向障碍物旋转时用的是四元数的slerp插值而不是简单地用atan2算角度再转欧拉角。slerp能避免万向节死锁在3D旋转里是更正确的做法。代码里还贴心地加了注释说明为什么不用欧拉角。// 使用四元数slerp避免万向节死锁 const targetQuat new THREE.Quaternion().setFromUnitVectors( new THREE.Vector3(0, 0, 1), direction.normalize() ); player.quaternion.slerp(targetQuat, 0.1);这段代码本身没问题但问题出在它把这段逻辑放在了渲染循环里每帧都重新计算一次targetQuat。虽然功能正常但多了一次不必要的向量归一化和四元数构造。在原型阶段无所谓但如果场景里有几十个角色这就是性能隐患。4.2 单文件堆砌带来的维护困境DeepSeek V4 Pro把所有代码写进了一个HTML文件总共800多行。功能是全的但结构上很难维护。我试图在WorkBuddy里让它拆分模块它的回应是把代码按注释分成了几大块但物理上还是在一个文件里。这带来一个实际问题调试的时候控制台报错的行号指向一个巨大的文件我得在800行里找对应的逻辑。而且它把场景初始化、角色控制、物理更新、渲染全部混在animate函数里想单独测试物理逻辑几乎不可能。注意如果你打算用模型生成的代码做后续开发一定要在需求里强制要求模块化。否则后期改一个功能可能牵动全身维护成本会指数级上升。4.3 相机跟随的抖动问题DeepSeek V4 Pro的相机跟随用的是直接赋值而不是插值camera.position.copy(player.position).add(offset); camera.lookAt(player.position);这样相机是硬跟随角色一动相机立刻到位。在角色匀速移动时看起来还行但一旦角色做跳跃或者急停相机会跟着瞬间上下或前后跳视觉上很生硬。而且它没有处理相机与障碍物的遮挡角色走到墙后面时相机穿墙直接看到场景外部。我手动加了lerp插值和射线检测才让相机可用。这部分工作量不小等于把相机系统重写了一遍。4.4 物理更新的帧率依赖前面提到过DeepSeek V4 Pro把delta直接传给物理更新function animate() { const delta clock.getDelta(); player.velocity.y - gravity * delta; player.position.y player.velocity.y * delta; // ... }这在60Hz下没问题但在144Hz显示器上delta变小重力累积变慢跳跃高度会明显变低。我实测在同一台机器上把浏览器刷新率从60切到144跳跃高度差了将近30%。这是个典型的帧率依赖bug在游戏开发里属于必须避免的问题。4.5 它的优势场景在哪虽然工程组织上扣分但DeepSeek V4 Pro在纯算法问题上非常可靠。我后来单独问它如何实现角色沿斜坡滑动和如何做胶囊体与三角形的碰撞检测它给出的数学推导和代码实现都正确且高效。所以我的建议是用DeepSeek V4 Pro做数学密集型的模块但别指望它帮你组织项目结构。5. GLM5.3代码漂亮但3D空间感有偏差5.1 代码风格和注释质量GLM5.3生成的代码是三个里读起来最舒服的。变量命名规范函数拆分合理注释详细到几乎可以当教程看。它甚至给每个模块都写了JSDoc风格的注释说明参数类型和返回值。/** * 计算角色在相机坐标系下的移动方向 * param {Object} input - 按键状态对象 {w, a, s, d} * param {THREE.Camera} camera - 当前相机 * returns {THREE.Vector3} 归一化后的移动方向 */ function getMoveDirection(input, camera) { // ... }这种代码风格在团队协作里很受欢迎新人接手能快速理解。如果这是个2D项目GLM5.3可能是最优选。5.2 空间变换的几次翻车问题出在3D空间变换上。GLM5.3在计算相机右方向时用了crossVectors(up, forward)而不是crossVectors(forward, up)导致右方向反了。结果是按D键角色往左走按A键往右走。这个错误很隐蔽因为代码逻辑看起来完全正确叉乘的顺序问题只有实际跑起来才能发现。我一开始以为是按键映射写反了查了半天才发现是叉乘顺序。另一个问题是它在处理角色朝向时把欧拉角的Y轴旋转和四元数混用导致角色在转向时偶尔会翻转180度。具体表现是鼠标快速转动视角时角色模型会突然倒过来。5.3 物理和碰撞的简化处理GLM5.3的物理实现比较简化它没有做重力累积而是用了一个如果角色Y坐标小于地面高度就设为地面高度的硬编码if (player.position.y 0) { player.position.y 0; player.velocity.y 0; }这在平地上能用但一旦场景里有台阶或者斜坡就完全失效。角色会直接穿过台阶因为台阶的高度不是0。我在需求里明确写了与障碍物的水平碰撞它实现了水平方向的AABB检测但垂直方向的碰撞处理得很粗糙。5.4 相机系统的亮点与不足GLM5.3的相机系统有一个亮点它实现了鼠标滚轮控制相机距离而且做了距离限制不会让相机穿到角色内部。这个细节说明它考虑到了用户体验。但不足也很明显相机没有做障碍物遮挡检测角色走到墙后相机依然穿墙。而且它的相机插值用的是固定系数没有做帧率无关处理在高刷屏上跟随速度会变快。5.5 适合什么样的任务GLM5.3适合做代码规范要求高、逻辑相对线性的任务。比如写一个配置系统、实现一个UI状态机、或者做数据转换层它的产出质量很高。但涉及3D空间推理、物理模拟、实时渲染这类需要强空间感的任务它的错误率明显高于另外两个模型。6. 把三个模型的产出整合成一个可玩版本6.1 整合策略取长补短三个模型各有优劣我没有只保留一个而是做了一次整合场景和角色控制用Step 5 Preview的模块化结构它的向量运算和输入处理最正确物理数学参考DeepSeek V4 Pro的公式特别是四元数旋转和碰撞检测的数学部分代码注释和命名借鉴GLM5.3的风格给关键函数补上JSDoc注释相机系统以Step 5 Preview的球坐标插值为基础加入GLM5.3的滚轮距离控制整合过程在WorkBuddy里完成我把三个模型的产出放在不同的会话里然后新建一个整合会话把需要的代码片段贴进去让WorkBuddy帮我做接口对齐。这里WorkBuddy的跨对话记忆能力帮了大忙它能记住我之前定义的模块接口整合时不会出现函数名对不上的问题。6.2 接口对齐的具体操作整合时最大的工作量是接口对齐。三个模型定义的函数签名不一样比如Step 5 Preview的物理更新叫updatePhysics(delta)DeepSeek V4 Pro叫stepPhysics(dt)GLM5.3叫physicsUpdate(time)。我在WorkBuddy里定了一条规则所有物理更新函数统一命名为updatePhysics参数为固定时间步长。然后让它扫描三个会话的代码自动做重命名和调用点替换。这个操作如果手动做几十个调用点很容易漏用WorkBuddy的批量处理省了不少事。6.3 实测整合版本的性能表现整合后的版本在Chrome里跑场景里有1个角色、20个障碍物方块、1个地面平面。帧率稳定在60fpsCPU占用率在15%左右。角色移动、跳跃、碰撞、相机跟随都正常。我特意做了压力测试把障碍物数量加到200个帧率降到45fps左右。瓶颈在碰撞检测因为用的是O(n)的遍历。如果要进一步优化需要引入空间分割结构比如四叉树或者网格哈希。这部分我让DeepSeek V4 Pro给了实现方案它的数学描述很清晰但代码需要自己写。6.4 整合过程中的三个坑第一个坑是坐标系约定不一致。Step 5 Preview用Y轴向上GLM5.3有一段代码假设Z轴向上整合时角色会躺在地上。解决办法是在整合前统一约定Y轴向上所有涉及轴向的代码都检查一遍。第二个坑是时间单位不统一。有的模型用秒有的用毫秒。Step 5 Preview的delta是秒GLM5.3有一段代码把delta乘以1000当毫秒用。整合后角色移动速度差了1000倍直接飞出场景。第三个坑是依赖版本冲突。三个模型都引入了Three.js但版本号不一样。Step 5 Preview用r160DeepSeek V4 Pro用r150GLM5.3没写版本号默认最新。整合时必须统一到一个版本否则API不兼容。提示多模型协作时一定要在项目初期就定好坐标系约定、时间单位、依赖版本这三件事。后期再统一成本会高很多。7. 关于WorkBuddy在这次实测里的实际作用7.1 跨会话记忆怎么用才顺手WorkBuddy的跨对话记忆是我这次能高效完成对比测试的关键。我建了一个项目约定会话在里面写清楚目录结构、依赖版本、命名规范、坐标系约定。后面每开一个新会话测试模型它都能自动读取这些约定不用我重复交代。但这里有个使用技巧约定要写得具体不能太抽象。比如代码要模块化这种规则模型理解起来有偏差。我改成每个文件不超过200行按功能拆分为main、player、camera、world、physics五个模块执行效果就好很多。7.2 自定义指令的生效范围WorkBuddy支持给工作台定规则规则对后续所有任务生效。我定了三条所有代码必须标注依赖版本号物理更新必须使用固定时间步长相机跟随必须做帧率无关的插值这三条规则在后续所有会话里都自动生效了省去了每次重复说明的麻烦。特别是第二条如果没有这条规则三个模型都会默认用可变时间步长。7.3 缓存目录和性能有朋友问过WorkBuddy的系统缓存目录能不能改到D盘。可以在设置里找到缓存路径选项改成目标盘符下的目录就行。我因为要同时跑三个模型的会话缓存增长比较快改到了空间更大的盘上。改完之后重启WorkBuddy生效之前的会话记录不会丢。7.4 安全审核对开发的影响WorkBuddy有安全审核机制我测试过程中有几段代码被拦了。一次是因为代码里包含了网络请求相关的逻辑另一次是因为变量命名触发了敏感词。解决办法是改命名和移除不必要的网络调用。对于纯本地的3D游戏开发这个影响不大但如果你做的是涉及网络通信的项目需要提前了解审核规则。8. 三个模型做3D游戏的选型建议8.1 按任务类型选模型任务类型推荐模型理由完整3D游戏原型Step 5 Preview工程化最好一次跑通率最高数学密集型模块DeepSeek V4 Pro向量、四元数、碰撞数学最扎实代码规范要求高的模块GLM5.3命名和注释质量最好快速验证想法Step 5 Preview模块化结构便于后续修改性能优化方案DeepSeek V4 Pro算法描述清晰数学推导正确8.2 组合使用的实际收益如果只用一个模型我推荐Step 5 Preview因为它的产出最接近可交付状态。但如果追求更高质量组合使用收益明显用Step 5 Preview搭骨架用DeepSeek V4 Pro补数学用GLM5.3润色代码风格。整合成本主要在接口对齐上用WorkBuddy的跨会话记忆能降低不少。8.3 什么情况下别用模型生成3D代码如果你的项目涉及复杂的骨骼动画、高级光照模型、或者自定义着色器模型生成的代码基本不可用。这些领域需要精确的图形学知识和大量的调试模型目前的能力还达不到。模型适合做的是原型验证、逻辑框架搭建、以及标准几何体的场景组织。9. 我在这次实测里踩过的几个坑第一个坑是没在需求里明确Three.js版本。第一次测试时GLM5.3用了已经废弃的THREE.Geometry页面直接白屏。后来我在WorkBuddy的规则里加了所有依赖必须标注版本号问题才解决。第二个坑是忽略了浏览器的自动播放策略。我让模型加了一个背景音效结果Chrome因为用户没有交互而拒绝播放控制台报错但游戏逻辑正常。这个不是模型的问题但如果你要做带音频的3D游戏需要处理这个策略。第三个坑是模型对平滑插值的理解不一致。Step 5 Preview用了帧率无关的指数插值DeepSeek V4 Pro用了固定系数lerpGLM5.3用了线性插值。在60Hz下三者看起来差不多但在144Hz下差异明显。后来我在规则里明确了插值公式才统一了行为。第四个坑是碰撞检测的精度。三个模型默认都用AABB对于方块障碍物够用但角色贴墙时会有视觉穿插。如果要做精确碰撞需要让模型实现胶囊体或者OBB但代码复杂度会上升不少。原型阶段AABB是合理选择但要在需求里说清楚。第五个坑是WorkBuddy的会话上下文长度。三个模型的代码加起来超过2000行如果放在同一个会话里上下文很快就会被占满后面的对话质量会下降。我的做法是每个模型独立会话整合时只贴关键片段不贴完整代码。10. 后续可以继续深挖的方向这次实测只覆盖了3D游戏的基础模块还有几个方向值得继续测。一个是多人联机同步这涉及网络状态同步和延迟补偿对模型的网络编程能力是个考验。另一个是移动端适配触屏控制和性能优化在移动端和桌面端差异很大。还有一个是AI行为树让NPC有自主决策能力这需要模型理解行为树的结构和节点逻辑。我打算下一步用同样的三模型对比方法测一下3D游戏里的寻路算法实现。A星寻路在3D网格上的变体、导航网格的生成、动态障碍物的避让这些都是3D游戏里的硬骨头。到时候再把结果整理出来。如果你也在用这几个模型做开发我的建议是别只看榜单排名拿一个具体项目跑一遍差异立刻就出来了。模型的能力边界只有在真实任务里才能摸清楚而3D游戏恰好是个不错的试金石。