Three.js 程序化地形生成 | 三维可视化 / AI 提示词

📋 AI 提示词

prompt
1
使用 Three.js 和自定义着色器噪声函数生成 3D 地形,实现程序化地形生成和高度映射效果。

🖼️ 效果预览

Three.js 程序化地形生成

🎮 案例演示

立即体验


效果拆解

效果 实现方式
地形生成 使用PlaneGeometry和噪声函数生成高度变化
噪声着色器 在着色器中实现Perlin噪声算法
高度映射 将噪声值映射到顶点位置
颜色渐变 根据高度值应用不同的颜色
实时渲染 使用ShaderMaterial实现实时地形生成
细节控制 通过噪声参数控制地形细节

核心技术点

1. 地形生成函数

javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
const generate_terrain = async () => {
  const planeGeo = new PlaneGeometry(50, 50, 500, 500);
  planeGeo.rotateX(-Math.PI / 2);
  
  const material = new THREE.ShaderMaterial({
    uniforms: {
      time: { value: 0 }
    },
    vertexShader: `
      vec3 hash(vec3 p) {
        p = vec3( dot(p, vec3(127.1, 311.7, 74.7)),
                  dot(p, vec3(269.5, 183.3, 246.1)),
                  dot(p, vec3(113.5, 271.9, 124.6)) );
        return fract(sin(p) * 43758.5453123);
      }

      float noise(in vec3 x) {
        vec3 p = floor(x);
        vec3 w = fract(x);
        vec3 u = w*w*w*(w*(w*6.0-15.0)+10.0);
        
        vec3 g = hash(p) - 0.5;
        float n = g.x;
        
        return n;
      }

      float fbm(vec3 p) {
        float f = 0.0;
        float w = 0.5;
        for (int i = 0; i < 5; i++) {
          f += w * noise(p);
          p *= 2.0;
          w *= 0.5;
        }
        return f;
      }

      varying float vHeight;
      
      void main() {
        vec3 pos = position;
        float height = fbm(pos * 0.1) * 5.0;
        pos.y += height;
        vHeight = height;
        
        gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
      }
    `,
    fragmentShader: `
      varying float vHeight;
      
      void main() {
        vec3 color = mix(vec3(0.2, 0.5, 0.2), vec3(0.8, 0.7, 0.5), vHeight / 5.0);
        gl_FragColor = vec4(color, 1.0);
      }
    `
  });
  
  const terrain = new THREE.Mesh(planeGeo, material);
  scene.add(terrain);
};

2. 噪声函数实现

javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
vec3 hash(vec3 p) {
  p = vec3( dot(p, vec3(127.1, 311.7, 74.7)),
            dot(p, vec3(269.5, 183.3, 246.1)),
            dot(p, vec3(113.5, 271.9, 124.6)) );
  return fract(sin(p) * 43758.5453123);
}

float noise(in vec3 x) {
  vec3 p = floor(x);
  vec3 w = fract(x);
  vec3 u = w*w*w*(w*(w*6.0-15.0)+10.0);
  
  vec3 g = hash(p) - 0.5;
  float n = g.x;
  
  return n;
}

3. 分形布朗运动

javascript
1
2
3
4
5
6
7
8
9
10
float fbm(vec3 p) {
  float f = 0.0;
  float w = 0.5;
  for (int i = 0; i < 5; i++) {
    f += w * noise(p);
    p *= 2.0;
    w *= 0.5;
  }
  return f;
}

4. 动画更新

javascript
1
2
3
4
5
function animate() {
  requestAnimationFrame(animate);
  
  material.uniforms.time.value += 0.01;
  
  renderer.render(scene, camera);
}

调试技巧

  1. 高度调整:修改fbm函数的乘数调整地形高度
  2. 细节控制:调整噪声频率参数改变地形细节
  3. 颜色映射:修改mix函数的颜色参数获得不同的地形效果
  4. 网格密度:调整PlaneGeometry的分段数获得更精细的地形

扩展思路

  1. 动态地形:实现地形的实时变化效果
  2. 多层噪声:结合多种噪声函数创建更复杂的地形
  3. 水体效果:添加水面和海岸线效果
  4. 植被生成:根据高度自动生成树木和草地
  5. 交互编辑:添加鼠标交互实时修改地形
  6. 纹理映射:使用纹理贴图增强地形细节