three.js 创建3D地球 特效描边
时间: 2025-01-04 19:27:16 浏览: 8
### 创建带有描边效果的3D地球模型
为了实现带有描边效果的3D地球模型,可以采用两种主要方法之一:一种是在几何体周围创建一个稍微放大并应用纯色材质的副本作为轮廓;另一种则是利用着色器来模拟描边效果。这里提供基于第二种方案的一个简单实例。
#### 方法一:使用两个同心球体模拟描边
这种方法涉及创建两个SphereGeometry对象,其中较大的那个用于呈现描边部分。通过调整内外层的颜色和透明度设置,可以获得良好的视觉效果。
```javascript
// 导入three.js库
import * from 'three';
function createEarthWithOutline(radius, outlineThickness) {
const scene = new THREE.Scene();
// 主地球
let earthMaterial = new THREE.MeshPhongMaterial({ color: 0x2b6cb0 });
let earthGeometry = new THREE.SphereBufferGeometry(radius, 32, 32);
let earthMesh = new THREE.Mesh(earthGeometry, earthMaterial);
// 描边(外部更大的半径)
let outlineRadius = radius + outlineThickness;
let outlineMaterial = new THREE.MeshBasicMaterial({
color: 0x000000,
side: THREE.BackSide
});
let outlineGeometry = new THREE.SphereBufferGeometry(outlineRadius, 32, 32);
let outlineMesh = new THREE.Mesh(outlineGeometry, outlineMaterial);
// 将两者加入场景中
scene.add(outlineMesh); // 先添加外框以确保渲染顺序正确
scene.add(earthMesh);
return {scene, earthMesh};
}
```
上述代码片段展示了如何构建一个基础版本的带描边地球[^1]。请注意,在实际应用场景下可能还需要考虑光照条件等因素的影响,并相应地调整材料属性。
#### 方法二:运用ShaderMaterial实现实时描边
对于更复杂的交互需求或是追求更高的效率来说,直接操作GPU可能是更好的选择。这可以通过编写自定义GLSL着色器并在Three.js中使用`THREE.ShaderMaterial`类来达成目的。
下面是一个简化版的例子:
```javascript
const vertexShaderSource = `
varying vec3 vNormal;
void main() {
vNormal = normalize(normalMatrix * normal);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0 );
}`;
const fragmentShaderSource = `
uniform float uEdgeWidth; // 边缘宽度参数
uniform sampler2D textureSampler; // 纹理采样器
varying vec3 vNormal;
float edgeFactor(vec3 n){
return smoothstep(-uEdgeWidth, uEdgeWidth, dot(n,-vec3(0.,0.,1.)));
}
void main(){
vec4 texColor = texture2D(textureSampler, uv);
if(texColor.a<0.5) discard;
float factor=edgeFactor(vNormal)*texColor.r*0.8+0.2*texColor.g;
gl_FragColor=vec4(mix(vec3(0.),vec3(1.),factor),1.);
}`;
let shaderMaterial = new THREE.ShaderMaterial({
uniforms:{
"uEdgeWidth":{value:.01},
"textureSampler":{ value:new THREE.TextureLoader().load('path/to/your/image.jpg')}
},
vertexShader:vertexShaderSource,
fragmentShader:fragmentShaderSource
});
let geometry=new THREE.SphereBufferGeometry(1,32,32);
let mesh=new THREE.Mesh(geometry,shaderMaterial);
scene.add(mesh);
```
这段脚本实现了更加灵活可控的效果,允许动态调节边缘厚度和其他特性[^2]。不过需要注意的是,这种方式通常会增加一定的编程复杂性和硬件资源消耗。
阅读全文