Three.js问题:PointLight无法照亮场景中的几何体
Three.js模型不响应光照问题修复
问题描述
通过BufferGeometry加载地形三角面模型,尝试多种光照材质(MeshStandardMaterial、MeshPhongMaterial、MeshLambertMaterial)、调用computeVertexNormals计算顶点法线、启用FlatShading后,模型仍不响应光照;新增的Torus模型同样无法被照亮,场景仅显示点光源辅助线和网格。
代码中的核心问题
- Torus模型创建参数错误:误用未定义的
boxGeometry和boxMaterial,而非声明好的torusGeometry和torusMaterial - 动画函数引用无效对象:操作的
box对象不存在,无对应模型实例 - 点光源照射范围不足:
PointLight的距离参数设为1000,但相机位于z=2000,模型位置超出灯光覆盖范围 - 缺少基础环境光:仅有点光源时,场景暗处会完全变黑,没有基础照明过渡
修复后的完整代码
import * as THREE from 'three'; import {OrbitControls} from 'three/addons/controls/OrbitControls.js'; const canvas = document.querySelector('#c') const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000000); const renderer = new THREE.WebGLRenderer({antialias: true, castShadow:true, canvas}); const controls = new OrbitControls(camera, canvas) renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement) // 添加环境光提供基础照明 const ambientLight = new THREE.AmbientLight(0xffffff, 0.2); scene.add(ambientLight); const topoGeometry = new THREE.BufferGeometry(); // 加载地形数据 await fetch('http://{localserver}/topography.json') .then((response) => response.json()) .then((json) => { const vertices = new Float32Array(json.geometry.vertices.map((coord) => { return [coord[0], coord[1], coord[2]] }).flat()) const indices = json.geometry.triangles.flat() topoGeometry.setIndex( indices ) topoGeometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3)) topoGeometry.computeVertexNormals() }); const topoMaterial = new THREE.MeshStandardMaterial({ wireframe: false, color: 0x00ff00, }); const topo = new THREE.Mesh( topoGeometry, topoMaterial ) scene.add(topo) camera.position.z = 2000; camera.position.x = 0; camera.position.y = 0; // 修复Torus模型创建参数,调整内半径避免自相交 const torusGeometry = new THREE.TorusGeometry(50,20) const torusMaterial = new THREE.MeshPhongMaterial({color: 0xff0000}) const torus = new THREE.Mesh(torusGeometry, torusMaterial) torus.position.setZ(400) scene.add(torus) // 扩大点光源范围,确保覆盖所有模型 const light = new THREE.PointLight( 0xffffff, 1, 5000 ); light.position.set( 0, 0, 600 ); light.castShadow = true; scene.add( light ); const lighthelper = new THREE.PointLightHelper(light,30, 0xffffff) const gridHelper = new THREE.GridHelper(3000,50) gridHelper.rotateX(Math.PI / 2) scene.add(lighthelper, gridHelper) function animate(){ requestAnimationFrame(animate) camera.updateProjectionMatrix() controls.update() // 修复动画对象引用 torus.rotateX(0.01) torus.rotateY(0.01) renderer.render(scene, camera) } animate()
原场景效果截图

内容的提问来源于stack exchange,提问作者Vetle Hofsøy-Woie
相关产品推荐
相关产品推荐

