Advertisement
EugeneFitz

Untitled

Mar 17th, 2023
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.27 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>Voxel Terrain Generation with Three.js</title>
  7. <style>
  8. body {
  9. margin: 0;
  10. }
  11. canvas {
  12. display: block;
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <script type="module">
  18. import * as THREE from "./js/three.module.js";
  19. import { ImprovedNoise } from "./js/ImprovedNoise.js";
  20. import { FirstPersonControls } from "./js/FirstPersonControls.js";
  21. import { OrbitControls } from "./js/OrbitControls.js";
  22.  
  23. const TERRAIN_SIZE = 200;
  24. const VOXEL_SIZE = 1;
  25.  
  26. let scene = new THREE.Scene();
  27. let camera = new THREE.PerspectiveCamera(
  28. 75,
  29. window.innerWidth / window.innerHeight,
  30. 0.1,
  31. 1000
  32. );
  33.  
  34. let renderer = new THREE.WebGLRenderer();
  35. renderer.setSize(window.innerWidth, window.innerHeight);
  36. document.body.appendChild(renderer.domElement);
  37.  
  38. let light = new THREE.HemisphereLight(0xffffff, 0x666666, 1);
  39. scene.add(light);
  40.  
  41. let directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
  42. directionalLight.position.set(
  43. (TERRAIN_SIZE * VOXEL_SIZE) / 2,
  44. 50,
  45. (TERRAIN_SIZE * VOXEL_SIZE) / 2
  46. );
  47. scene.add(directionalLight);
  48.  
  49. function lerp(a, b, t) {
  50. return a + (b - a) * t;
  51. }
  52.  
  53. function smoothstep(edge0, edge1, x) {
  54. let t = Math.min(Math.max((x - edge0) / (edge1 - edge0), 0), 1);
  55. return t * t * (3 - 2 * t);
  56. }
  57.  
  58. function generateVoxelTerrain() {
  59. let noise = new ImprovedNoise();
  60. let noise2 = new ImprovedNoise();
  61. let terrain = new THREE.Group();
  62.  
  63. let geometry = new THREE.BoxGeometry(
  64. VOXEL_SIZE,
  65. VOXEL_SIZE,
  66. VOXEL_SIZE
  67. );
  68. let materials = {
  69. plains: new THREE.MeshLambertMaterial({ color: 0x8dc63f }),
  70. desert: new THREE.MeshLambertMaterial({ color: 0xf0e68c }),
  71. forest: new THREE.MeshLambertMaterial({ color: 0x228b22 }),
  72. snowy: new THREE.MeshLambertMaterial({ color: 0xffffff }),
  73. };
  74.  
  75. for (let x = 0; x < TERRAIN_SIZE; x++) {
  76. for (let z = 0; z < TERRAIN_SIZE; z++) {
  77. let biomeValue = noise2.noise(x / 50, 0, z / 50);
  78. let biome = getBiome(biomeValue);
  79. let height = getBiomeHeight(x, z, noise, biome);
  80.  
  81. for (let y = 0; y < height; y++) {
  82. let voxel = new THREE.Mesh(geometry, materials[biome]);
  83.  
  84. voxel.position.set(
  85. x * VOXEL_SIZE,
  86. y * VOXEL_SIZE,
  87. z * VOXEL_SIZE
  88. );
  89. terrain.add(voxel);
  90. }
  91. }
  92. }
  93.  
  94. return terrain;
  95. }
  96.  
  97. function getBiomeHeight(x, z, noise, biome) {
  98. let height = 0;
  99. if (biome === "plains") {
  100. height = Math.floor((noise.noise(x / 25, 0, z / 25) + 1) * 1.5) + 12;
  101. } else if (biome === "desert") {
  102. height = Math.floor((noise.noise(x / 10, 0, z / 10) + 1) * 4) + 10;
  103. } else if (biome === "forest") {
  104. height = Math.floor((noise.noise(x / 10, 0, z / 10) + 1) * 5) + 15;
  105. } else if (biome === "snowy") {
  106. height = Math.floor((noise.noise(x / 10, 0, z / 10) + 1) * 3) + 18;
  107. }
  108. return height;
  109. }
  110.  
  111. function getBiome(value) {
  112. if (value < -0.5) {
  113. return "desert";
  114. } else if (value < 0) {
  115. return "plains";
  116. } else if (value < 0.5) {
  117. return "forest";
  118. } else {
  119. return "snowy";
  120. }
  121. }
  122.  
  123. let terrain = generateVoxelTerrain();
  124. scene.add(terrain);
  125.  
  126. camera.position.set(1, 1, 1);
  127.  
  128. let controls = new OrbitControls(camera, renderer.domElement);
  129. controls.target.set(
  130. (TERRAIN_SIZE * VOXEL_SIZE) / 2,
  131. 0,
  132. (TERRAIN_SIZE * VOXEL_SIZE) / 2
  133. );
  134. controls.update();
  135.  
  136. function animate() {
  137. requestAnimationFrame(animate);
  138.  
  139. controls.update(1 / 60);
  140. renderer.render(scene, camera);
  141. }
  142.  
  143. animate();
  144. </script>
  145. </body>
  146. </html>
  147.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement