Three.js自定义BufferGeometry搭配MeshLambertMaterial无光照效果问题
问题根源:缺失法线向量(Normal)
嘿,我一眼就揪出问题所在了——你手动创建的BufferGeometry没有添加法线属性!
MeshLambertMaterial这类依赖光照的材质,需要法线向量来计算每个顶点/面的光照方向。如果没有法线数据,Three.js根本没法正确计算漫反射光照,就会默认 fallback 成类似MeshBasicMaterial的无光照效果,也就是你看到的“不响应光照”的情况。
快速修复方案
你只需要在创建完position属性后,调用BufferGeometry的computeVertexNormals()方法,让Three.js自动帮你计算法线向量即可:
var geometry = new THREE.BufferGeometry(); var material = new THREE.MeshLambertMaterial( { color:0xff0000} ); vertices = new Float32Array([ 0,0,0, 0,1,0, 1,0,0, 0,0,0, 0,0,1, 0,1,0, 0,0,0, 1,0,0, 0,0,1, 0,1,0, 0,0,1, 1,0,0, ]); geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); // 核心修复:自动计算法线 geometry.computeVertexNormals(); OBJ = new THREE.Mesh(geometry,material);
原理说明
computeVertexNormals()会分析几何体的所有三角面,为每个顶点计算出合适的法线向量,这些法线会被自动存储到normal属性中。MeshLambertMaterial拿到法线数据后,就能正确根据光源方向计算漫反射光照,让你的金字塔屋顶和立方体、拉伸体一样正常显示明暗效果了。
如果以后你需要手动定义法线(比如做一些特殊的光照效果),也可以像添加position属性一样,手动创建一个Float32Array存储法线数据,再通过geometry.addAttribute( 'normal', ... )添加到几何体中。
内容的提问来源于stack exchange,提问作者C. Roux
相关产品推荐
相关产品推荐

