Three.js球体/地球光晕效果实现问题
解决Three.js球体光晕(Glow)效果的问题
嘿,我看你尝试给球体添加光晕效果,但代码写到一半卡住了对吧?这种外层发光的效果在Three.js里通常需要用自定义ShaderMaterial配合一个额外的“发光层”网格来实现,我给你补全完整的实现方案,顺便解释关键细节:
首先,先保留你已经写好的球体基础代码,然后咱们补上光晕的部分:
// 你的原有球体代码 var sphereGeom = new THREE.SphereGeometry(3, 40, 40); var moonTexture = new THREE.TextureLoader().load("../../assets/moon-map.png"); var moonMaterial = new THREE.MeshPhongMaterial({ map: moonTexture }); var moon = new THREE.Mesh(sphereGeom, moonMaterial); moon.position.set(0, 0, 0); this.add(moon); // 补全光晕效果的代码 var glowGeometry = new THREE.SphereGeometry(3.2, 40, 40); // 比原球体大一点,作为光晕载体 var customMaterial = new THREE.ShaderMaterial({ uniforms: { c: { type: "f", value: 0.4 }, // 光晕强度衰减系数,越小光晕越淡 p: { type: "f", value: 2.3 }, // 光晕扩散指数,越大光晕越集中 glowColor: { type: "c", value: new THREE.Color(0x4488ff) } // 光晕颜色 }, vertexShader: ` varying vec3 vNormal; void main() { vNormal = normalize(normalMatrix * normal); gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragmentShader: ` uniform float c; uniform float p; uniform vec3 glowColor; varying vec3 vNormal; void main() { float intensity = pow(c - dot(vNormal, vec3(0.0, 0.0, 1.0)), p); gl_FragColor = vec4(glowColor, intensity); } `, transparent: true, // 开启透明,让光晕只显示渐变部分 side: THREE.BackSide // 从背面渲染,让光晕包裹住内层球体 }); var glowMesh = new THREE.Mesh(glowGeometry, customMaterial); moon.add(glowMesh); // 把光晕挂载到球体上,跟着球体一起移动
关键细节解释:
- 光晕用了一个比原球体稍大的SphereGeometry,这样才能覆盖在原球体外面形成发光层
- ShaderMaterial里的
c和p参数:c控制光晕的基础强度,数值越大光晕越亮p控制光晕的扩散范围,数值越小光晕越分散,越大越集中在球体边缘
- 设置
side: THREE.BackSide是因为我们要让着色器从球体的背面计算发光强度,这样光晕是从球体向外发散的效果 - 别忘了给场景添加光源!你用了
MeshPhongMaterial,必须有AmbientLight或者DirectionalLight才能看到球体的纹理和颜色
如果光晕效果不够明显,可以试试这些调整:
- 增大光晕球体的半径(比如改成3.5)
- 调大
c的值(比如0.6)或者调小p的值(比如1.5) - 更换更亮的
glowColor
内容的提问来源于stack exchange,提问作者user2689193
相关产品推荐
相关产品推荐

