Three.jsBuilderSkill threejs-builder

专注于使用现代ES模块模式创建简单、高性能的Three.js网络应用程序。 ## 理念:场景图心智模型 Three.js建立在**场景图**上——一个对象的层次树,其中父变换影响子对象。理解这个心智模型是有效的3D网络开发的关键。 **在创建Three.js应用之前,问自己**: - 核心视觉元素是什么?(几何体、形状、模型) - 用户需要什么交互?(无、轨道控制、自定义输入) - 存在哪些性能约束?(移动设备、桌面、WebGL能力) - 什么动画使其栩栩如生?(旋转、移动、过渡) **核心原则**: 1. **场景图优先**:所有添加到`scene`的内容都会渲染。使用`Group`进行层次变换。 2. **原语作为构建块**:内置几何体(Box、Sphere、Torus)覆盖80%的简单用例。 3. **动画作为变换**:使用`requestAnimationFrame`或`renderer.setAnimationLoop`随时间改变位置/旋转/缩放。 4. **通过简单实现性能**:更少的对象,更少的绘制调用,可重用的几何体/材质。 --- ## 快速开始:基本设置 ### 最小HTML模板 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Three.js App</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { overflow: hidden; background: #000; } canvas { display: block; } </style> </head> <body> <script type="module"> import * as THREE from 'https://unpkg.com/three@0.160.0/build/three.module.js'; // 场景设置 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); document.body.appendChild(renderer.domElement); // 你的3D内容在这里 // ... camera.position.z = 5; // 动画循环 renderer.setAnimationLoop((time) => { renderer.render(scene, camera); }); // 处理调整大小 window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); </script> </body> </html> ``` --- ## 几何体 内置原语覆盖大多数简单应用需求。仅对自定义形状使用`BufferGeometry`。 **常见原语**: - `BoxGeometry(width, height, depth)` - 立方体,盒子 - `SphereGeometry(radius, widthSegments, heightSegments)` - 球体,行星 - `CylinderGeometry(radiusTop, radiusBottom, height)` - 管子,圆柱体 - `TorusGeometry(radius, tube)` - 甜甜圈,环 - `PlaneGeometry(width, height)` - 地板,墙壁,背景 - `ConeGeometry(radius, height)` - 尖刺,圆锥体 - `IcosahedronGeometry(radius, detail)` - 低多边形球体(detail=0) **用法**: ```javascript const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x44aa88 }); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh); ``` --- ## 材质 根据照明需求和视觉风格选择材质。 **材质选择指南**: - `MeshBasicMaterial` - 无照明,平面颜色。用于:UI,线框,未照明效果 - `MeshStandardMaterial` - PBR照明。现实表面默认 - `MeshPhysicalMaterial` - 高级PBR,带清漆,透射。玻璃,水 - `MeshNormalMaterial` - 调试,基于法线的彩虹色 - `MeshPhongMaterial` - 遗留,光泽度控制。比标准快 **常见材质属性**: ```javascript { color: 0x44aa88, // 十六进制颜色 roughness: 0.5, // 0=光泽,1=亚光(标准/物理) metalness: 0.0, // 0=非金属,1=金属(标准/物理) emissive: 0x000000, // 自发光颜色 wireframe: false, // 仅显示边缘 transparent: false, // 启用透明 opacity: 1.0, // 0=不可见,1=不透明(需要transparent:true) side: THREE.FrontSide // FrontSide, BackSide, DoubleSide } ``` --- ## 照明 没有灯光=黑屏(除了BasicMaterial/NormalMaterial)。 **灯光类型**: - `AmbientLight(intensity)` - 基础照明无处不在。使用0.3-0.5 - `DirectionalLight(color, intensity)` - 类似太阳,平行光线。投射阴影 - `PointLight(color, intensity, distance)` - 灯泡,向所有方向发射 - `SpotLight(color, intensity, angle, penumbra)` - 手电筒,光锥 **典型照明设置**: ```javascript const ambientLight = new THREE.AmbientLight(0xffffff, 0.4); scene.add(ambientLight); const mainLight = new THREE.DirectionalLight(0xffffff, 1); mainLight.position.set(5, 10, 7); scene.add(mainLight); const fillLight = new THREE.DirectionalLight(0x88ccff, 0.5); fillLight.position.set(-5, 0, -5); scene.add(fillLight); ``` **阴影**(高级,需要时使用): ```javascript renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; mainLight.castShadow = true; mainLight.shadow.mapSize.width = 2048; mainLight.shadow.mapSize.height = 2048; mesh.castShadow = true; mesh.receiveShadow = true; ``` --- ## 动画 使用动画循环随时间变换对象。 **动画模式**: 1. **连续旋转**: ```javascript renderer.setAnimationLoop((time) => { mesh.rotation.x = time * 0.001; mesh.rotation.y = time * 0.0005; renderer.render(scene, camera); }); ``` 2. **波浪/浮动运动**: ```javascript renderer.setAnimationLoop((time) => { mesh.position.y = Math.sin(time * 0.002) * 0.5; renderer.render(scene, camera); }); ``` 3. **鼠标交互**: ```javascript const mouse = new THREE.Vector2(); window.addEventListener('mousemove', (event) => { mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; }); renderer.setAnimationLoop(() => { mesh.rotation.x = mouse.y * 0.5; mesh.rotation.y = mouse.x * 0.5; renderer.render(scene, camera); }); ``` --- ## 相机控制 导入examples中的OrbitControls进行交互式相机移动: ```html <script type="module"> import * as THREE from 'https://unpkg.com/three@0.160.0/build/three.module.js'; import { OrbitControls } from 'https://unpkg.com/three@0.160.0/examples/jsm/controls/OrbitControls.js'; // ...场景设置... const controls = new OrbitControls(camera, renderer.domElement); controls.enableDamping = true; controls.dampingFactor = 0.05; renderer.setAnimationLoop(() => { controls.update(); renderer.render(scene, camera); }); </script> ``` --- ## 常见场景模式 ### 旋转立方体(Hello World) ```javascript const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x00ff88 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); renderer.setAnimationLoop((time) => { cube.rotation.x = time * 0.001; cube.rotation.y = time * 0.001; renderer.render(scene, camera); }); ``` ### 浮动粒子场 ```javascript const particleCount = 1000; const geometry = new THREE.BufferGeometry(); const positions = new Float32Array(particleCount * 3); for (let i = 0; i < particleCount * 3; i += 3) { positions[i] = (Math.random() - 0.5) * 50; positions[i + 1] = (Math.random() - 0.5) * 50; positions[i + 2] = (Math.random() - 0.5) * 50; } geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); const material = new THREE.PointsMaterial({ color: 0xffffff, size: 0.1 }); const particles = new THREE.Points(geometry, material); scene.add(particles); ``` ### 带前景对象的动画背景 ```javascript // 背景网格 const gridHelper = new THREE.GridHelper(50, 50, 0x444444, 0x222222); scene.add(gridHelper); // 前景对象 const mainGeometry = new THREE.IcosahedronGeometry(1, 0); const mainMaterial = new THREE.MeshStandardMaterial({ color: 0xff6600, flatShading: true }); const mainMesh = new THREE.Mesh(mainGeometry, mainMaterial); scene.add(mainMesh); ``` --- ## 颜色 Three.js使用十六进制颜色格式:`0xRRGGBB` 常见十六进制颜色: - 黑色:`0x000000`,白色:`0xffffff` - 红色:`0xff0000`,绿色:`0x00ff00`,蓝色:`0x0000ff` - 青色:`0x00ffff`,品红色:`0xff00ff`,黄色:`0xffff00` - 橙色:`0xff8800`,紫色:`0x8800ff`,粉红色:`0xff0088` --- ## 避免的反模式 ### 基本设置错误 ❌ **从错误路径导入OrbitControls** 为什么不好:控件无法加载,现代Three.js中`THREE.OrbitControls`未定义 更好:使用`import { OrbitControls } from 'three/addons/controls/OrbitControls.js'`或unpkg examples/jsm路径 ❌ **忘记将对象添加到场景中** 为什么不好:对象不会渲染,静默失败 更好:创建网格/灯光后总是调用`scene.add(object)` ❌ **使用旧的`requestAnimationFrame`模式而不是`setAnimationLoop`** 为什么不好:更冗长,不自动处理XR/WebXR 更好:`renderer.setAnimationLoop((time) => { ... })` ### 性能问题 ❌ **在动画循环中创建新的几何体** 为什么不好:大量内存分配,帧速率崩溃 更好:一次创建几何体,重用它。仅变换位置/旋转/缩放 ❌ **在原语上使用太多段** 为什么不好:不必要的顶点,GPU开销 更好:默认段通常可以。`SphereGeometry(1, 32, 16)`而不是`SphereGeometry(1, 128, 64)` ❌ **不设置像素比上限** 为什么不好:4K/5K显示器以全分辨率运行,性能差 更好:`Math.min(window.devicePixelRatio, 2)` ### 代码组织 ❌ **一切都在一个巨大的函数中** 为什么不好:难以修改,难以调试 更好:将设置分成函数:`createScene()`, `createLights()`, `createMeshes()` ❌ **硬编码所有值** 为什么不好:调整和实验困难 更好:在顶部定义常量:`const CONFIG = { color: 0x00ff88, speed: 0.001 }` --- ## 变化指导 **重要**:每个Three.js应用应该感觉独特且适合上下文。 **根据场景变化**: - **作品集/展示**:优雅,平滑动画,柔和色彩 - **游戏/互动**:鲜艳色彩,快速控制,粒子效果 - **数据可视化**:清晰线条,网格助手,清晰标签 - **背景效果**:微妙,慢速移动,深色/渐变背景 - **产品查看器**:现实照明,PBR材质,平滑轨道 **变化视觉元素**: - **几何体选择**:不是一切都需要是立方体。探索球体,环面,二十面体 - **材质风格**:混合平面阴影,光泽,金属,线框 - **色彩调色板**:使用互补色,类似色或单色方案 - **动画风格**:旋转,振荡,波动运动,鼠标跟踪 **避免收敛于**: - 默认绿色立方体作为第一次示例 - 相同相机角度(正面,z=5) - 相同的照明设置(总是1,1,1处的方向光) --- ## 记住 **Three.js是网络互动3D的工具。** 有效的Three.js应用: - 从场景图心智模型开始 - 使用原语作为构建块 - 保持动画简单且高性能 - 根据目的变化视觉风格 - 从现代ES模块路径导入 **现代Three.js (r150+)使用`three`包或CDN的ES模块。** 通用JS模式和全局`THREE`变量是遗留的。 对于高级主题(GLTF模型,着色器,后处理),请参阅references/advanced-topics.md。 **Claude能够创建优雅,高性能的3D网络体验。这些模式指导方式——它们不限制结果。**

游戏开发 0 次安装 0 次浏览 更新于 3/3/2026

创建简单的Three.js网络应用,场景设置、照明、几何体、材质、动画和响应式渲染。用于:"创建一个threejs场景/应用/展示"或当用户想要3D网络内容时。支持ES模块,现代Three.js r150+ API。