
13. 光照模型与性能1. 概述光照模型决定了材质如何与光线交互。Three.js 提供了多种内置光照模型每种模型在视觉效果和性能之间有不同的权衡。了解这些模型的原理和性能特点可以帮助你做出更好的选择。┌─────────────────────────────────────────────────────────────┐ │ 光照模型体系 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 光照模型类型 │ │ ├── MeshBasicMaterial无光照性能最佳 │ │ ├── MeshLambertMaterial兰伯特漫反射 │ │ ├── MeshPhongMaterial冯氏漫反射高光 │ │ ├── MeshStandardMaterial标准 PBR │ │ ├── MeshPhysicalMaterial物理 PBR最真实 │ │ └── MeshToonMaterial卡通非真实感 │ │ │ │ 性能对比 │ │ ├── 计算复杂度 │ │ ├── 顶点/片元着色器负担 │ │ ├── 光源数量影响 │ │ └── 阴影性能 │ │ │ └─────────────────────────────────────────────────────────────┘2. 光照模型详解2.1 MeshBasicMaterial无光照最简单的材质不受光照影响直接显示颜色或纹理。constbasicMaterialnewTHREE.MeshBasicMaterial({color:0xff6600,map:texture});特点无需光照计算性能最佳无阴影适用于 UI、调试、2D 效果2.2 MeshLambertMaterial兰伯特兰伯特光照模型只计算漫反射适合粗糙表面。constlambertMaterialnewTHREE.MeshLambertMaterial({color:0x44aa88});特点只有漫反射无高光性能较好适合粗糙材质2.3 MeshPhongMaterial冯氏冯氏光照模型在兰伯特基础上增加了高光。constphongMaterialnewTHREE.MeshPhongMaterial({color:0x44aa88,specular:0x444444,shininess:60});特点漫反射 高光性能中等适合光滑材质2.4 MeshStandardMaterial标准 PBR基于物理的渲染PBR模型使用金属度和粗糙度。conststandardMaterialnewTHREE.MeshStandardMaterial({color:0xccaa88,metalness:0.8,roughness:0.2});特点物理真实性能较高适合大多数场景2.5 MeshPhysicalMaterial物理 PBR标准 PBR 的扩展增加清漆、透射等属性。constphysicalMaterialnewTHREE.MeshPhysicalMaterial({color:0x88aaff,metalness:0.9,roughness:0.1,clearcoat:1.0,transmission:0.8});特点最真实性能消耗最大适合高端场景2.6 MeshToonMaterial卡通非真实感渲染产生渐变着色效果。consttoonMaterialnewTHREE.MeshToonMaterial({color:0x44aa88});特点卡通风格性能较好适合风格化渲染3. 性能对比3.1 性能对比表材质类型顶点着色器片元着色器相对性能真实感Basic简单简单⭐⭐⭐⭐⭐⭐Lambert中等简单⭐⭐⭐⭐⭐⭐Phong中等中等⭐⭐⭐⭐⭐⭐Standard复杂复杂⭐⭐⭐⭐⭐⭐Physical复杂非常复杂⭐⭐⭐⭐⭐⭐Toon中等中等⭐⭐⭐⭐⭐⭐3.2 性能测试代码functionmeasureMaterialPerformance(material,iterations1000){constgeometrynewTHREE.BoxGeometry(1,1,1);constmeshnewTHREE.Mesh(geometry,material);scene.add(mesh);conststartperformance.now();for(leti0;iiterations;i){renderer.render(scene,camera);}constendperformance.now();scene.remove(mesh);returnend-start;}4. 光源数量与性能4.1 光源数量影响光源数量BasicLambertPhongStandardPhysical1100%120%140%160%180%2100%140%180%220%260%4100%180%260%340%420%8100%260%420%580%740%4.2 光源优化策略// 限制光源数量constmaxLights4;// 使用环境光减少光源需求constambientLightnewTHREE.AmbientLight(0x404040,0.5);// 使用光源辅助器调试constlightHelpernewTHREE.DirectionalLightHelper(directionalLight);5. 性能优化技巧5.1 材质优化// 使用更简单的材质// 不需要高光时使用 LambertconstmaterialneedsSpecular?newTHREE.MeshPhongMaterial({color:0x44aa88}):newTHREE.MeshLambertMaterial({color:0x44aa88});// 禁用不必要的特性material.transparentfalse;material.depthTesttrue;material.depthWritetrue;// 合并材质相同材质的物体可以合并渲染constmergedGeometryBufferGeometryUtils.mergeBufferGeometries(geometries);constmergedMeshnewTHREE.Mesh(mergedGeometry,sharedMaterial);5.2 纹理优化// 降低纹理分辨率consttextureLoadernewTHREE.TextureLoader();consttexturetextureLoader.load(image.jpg);texture.minFilterTHREE.LinearFilter;texture.magFilterTHREE.LinearFilter;// 使用压缩纹理// 使用 BasisTexture 或 KTX2 格式5.3 阴影优化// 降低阴影质量renderer.shadowMap.typeTHREE.BasicShadowMap;light.shadow.mapSize.width512;light.shadow.mapSize.height512;// 限制阴影范围light.shadow.camera.left-5;light.shadow.camera.right5;light.shadow.camera.top5;light.shadow.camera.bottom-5;// 禁用不必要的阴影backgroundMesh.castShadowfalse;backgroundMesh.receiveShadowfalse;5.4 实例化渲染// 大量相同物体使用 InstancedMeshconstcount1000;constinstancedMeshnewTHREE.InstancedMesh(geometry,material,count);constdummynewTHREE.Object3D();for(leti0;icount;i){dummy.position.set(Math.random()*100-50,Math.random()*10,Math.random()*100-50);dummy.updateMatrix();instancedMesh.setMatrixAt(i,dummy.matrix);}instancedMesh.instanceMatrix.needsUpdatetrue;scene.add(instancedMesh);6. 光照模型选择指南6.1 决策树需要光照效果 │ ├─ 否 → MeshBasicMaterial │ └─ 是 → 需要高光效果 │ ├─ 否 → MeshLambertMaterial │ └─ 是 → 需要物理真实感 │ ├─ 否 → 性能优先 │ │ │ ├─ 是 → MeshPhongMaterial │ └─ 否 → MeshStandardMaterial │ └─ 是 → 需要透射/清漆 │ ├─ 是 → MeshPhysicalMaterial └─ 否 → MeshStandardMaterial6.2 场景推荐场景类型推荐材质理由移动端 WebMeshBasicMaterial / MeshLambertMaterial性能优先普通网页MeshStandardMaterial平衡性能与画质产品展示MeshPhysicalMaterial最高画质游戏MeshStandardMaterial适中性能数据可视化MeshBasicMaterial无需光照风格化MeshToonMaterial独特风格7. 完整示例import*asTHREEfromthree;import{OrbitControls}fromthree/examples/jsm/controls/OrbitControls.js;importStatsfromstats.js;constscenenewTHREE.Scene();scene.backgroundnewTHREE.Color(0x111122);constcameranewTHREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);camera.position.set(8,6,12);camera.lookAt(0,0,0);constrenderernewTHREE.WebGLRenderer({antialias:true});renderer.setSize(window.innerWidth,window.innerHeight);renderer.shadowMap.enabledtrue;document.body.appendChild(renderer.domElement);constcontrolsnewOrbitControls(camera,renderer.domElement);controls.enableDampingtrue;// 性能监控conststatsnewStats();stats.showPanel(0);document.body.appendChild(stats.dom);// 光源constambientLightnewTHREE.AmbientLight(0x404040,0.4);scene.add(ambientLight);constdirectionalLightnewTHREE.DirectionalLight(0xffffff,1);directionalLight.position.set(5,10,7);directionalLight.castShadowtrue;scene.add(directionalLight);constfillLightnewTHREE.PointLight(0x88aaff,0.3);fillLight.position.set(-3,2,4);scene.add(fillLight);// 辅助对象constaxesHelpernewTHREE.AxesHelper(5);scene.add(axesHelper);constgridHelpernewTHREE.GridHelper(15,20);scene.add(gridHelper);constgeometrynewTHREE.SphereGeometry(0.8,64,64);// 不同材质对比constmaterials[{name:Basic,material:newTHREE.MeshBasicMaterial({color:0xff6600}),pos:[-3,1,-2]},{name:Lambert,material:newTHREE.MeshLambertMaterial({color:0x44aa88}),pos:[0,1,-2]},{name:Phong,material:newTHREE.MeshPhongMaterial({color:0x44aa88,shininess:60}),pos:[3,1,-2]},{name:Standard,material:newTHREE.MeshStandardMaterial({color:0x44aa88,metalness:0.5,roughness:0.3}),pos:[-3,1,2]},{name:Physical,material:newTHREE.MeshPhysicalMaterial({color:0x44aa88,metalness:0.5,roughness:0.3,clearcoat:0.5}),pos:[0,1,2]},{name:Toon,material:newTHREE.MeshToonMaterial({color:0x44aa88}),pos:[3,1,2]}];materials.forEach((item){constmeshnewTHREE.Mesh(geometry,item.material);mesh.position.set(item.pos[0],item.pos[1],item.pos[2]);mesh.castShadowtrue;scene.add(mesh);});// 平面constplaneGeometrynewTHREE.PlaneGeometry(14,12);constplaneMaterialnewTHREE.MeshStandardMaterial({color:0x336699,side:THREE.DoubleSide});constplanenewTHREE.Mesh(planeGeometry,planeMaterial);plane.rotation.x-Math.PI/2;plane.position.y-0.5;plane.receiveShadowtrue;scene.add(plane);// 标签import{CSS2DRenderer,CSS2DObject}fromthree/examples/jsm/renderers/CSS2DRenderer.js;constlabelRenderernewCSS2DRenderer();labelRenderer.setSize(window.innerWidth,window.innerHeight);labelRenderer.domElement.style.positionabsolute;labelRenderer.domElement.style.top0px;labelRenderer.domElement.style.left0px;labelRenderer.domElement.style.pointerEventsnone;document.body.appendChild(labelRenderer.domElement);materials.forEach((item){constdivdocument.createElement(div);div.textContentitem.name;div.style.colorwhite;div.style.backgroundrgba(0,0,0,0.6);div.style.padding4px 8px;div.style.borderRadius4px;div.style.fontSize14px;constlabelnewCSS2DObject(div);label.position.set(item.pos[0],item.pos[1]1.2,item.pos[2]);scene.add(label);});// GUI 控制importGUIfromlil-gui;constguinewGUI();// 光源强度控制gui.add(directionalLight,intensity,0,2).name(主光强度);gui.add(fillLight,intensity,0,1).name(补光强度);gui.add(ambientLight,intensity,0,1).name(环境光强度);// 性能信息显示constperfFoldergui.addFolder(性能信息);perfFolder.add({fps:0},fps).name(FPS).listen();perfFolder.open();letframeCount0;letlastTimeperformance.now();functionanimate(){constnowperformance.now();frameCount;if(now-lastTime1000){stats.update();perfFolder.controllers[0].setValue(frameCount);frameCount0;lastTimenow;}stats.begin();controls.update();renderer.render(scene,camera);labelRenderer.render(scene,camera);stats.end();requestAnimationFrame(animate);}animate();window.addEventListener(resize,onWindowResize,false);functiononWindowResize(){camera.aspectwindow.innerWidth/window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth,window.innerHeight);labelRenderer.setSize(window.innerWidth,window.innerHeight);}8. 总结材质类型特点性能适用场景Basic无光照⭐⭐⭐⭐⭐调试、UILambert漫反射⭐⭐⭐⭐粗糙表面Phong漫反射高光⭐⭐⭐光滑表面StandardPBR⭐⭐大多数场景Physical高级 PBR⭐高端场景Toon卡通⭐⭐⭐⭐风格化优化策略说明选择合适的材质不需要高光时用 Lambert限制光源数量每增加一个光源性能下降降低阴影质量使用 BasicShadowMap纹理压缩使用压缩格式实例化渲染大量相同物体禁用阴影不需要阴影时关闭9. 第二部分总结恭喜你完成了第二部分光照与阴影你已掌握✅ 光源类型环境光、平行光、点光源、聚光灯、半球光✅ 光照属性与配置颜色、强度、位置、衰减✅ 阴影系统启用、配置、优化✅ 反射与折射环境贴图、玻璃材质✅ 光照模型与性能材质选择、性能优化