запускать буду лакально адаптируй код для ndoejs , одним файлом 
<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <title>3D Игра на Three.js</title>
  <style>
    body { margin: 0; overflow: hidden; }
    canvas { display: block; }
    #overlay {
      position: absolute;
      top: 50%;
      width: 100%;
      text-align: center;
      z-index: 1;
      display: flex;
      justify-content: center;
      align-items: center;
      transform: translateY(-50%);
      background: rgba(0, 0, 0, 0.5);
      height: 100vh;
      color: white;
      font-family: Arial, sans-serif;
    }
    #overlay button {
      padding: 15px 30px;
      font-size: 24px;
      cursor: pointer;
      background-color: #28a745;
      border: none;
      border-radius: 5px;
      color: white;
    }
    #gui-container {
      position: absolute;
      top: 10px;
      right: 10px;
      z-index: 2;
    }
  </style>
</head>
<body>
  <div id="overlay">
    <button id="startButton">Нажмите, чтобы начать</button>
  </div>
  
  <div id="gui-container"></div>
  
  <!-- Главный скрипт -->
  <script type="module">
    // Импортируйте необходимые модули из CDN
    import * as THREE from 'https://unpkg.com/three@0.152.0/build/three.module.js';
    import { PointerLockControls } from 'https://unpkg.com/three@0.152.0/examples/jsm/controls/PointerLockControls.js';
    import { EffectComposer } from 'https://unpkg.com/three@0.152.0/examples/jsm/postprocessing/EffectComposer.js';
    import { RenderPass } from 'https://unpkg.com/three@0.152.0/examples/jsm/postprocessing/RenderPass.js';
    import { ShaderPass } from 'https://unpkg.com/three@0.152.0/examples/jsm/postprocessing/ShaderPass.js';
    import { FXAAShader } from 'https://unpkg.com/three@0.152.0/examples/jsm/shaders/FXAAShader.js';
    import { GUI } from 'https://cdn.jsdelivr.net/npm/dat.gui@0.7.9/build/dat.gui.module.js';

    let scene, camera, renderer, controls, composer;
    let move = { forward: false, backward: false, left: false, right: false };
    let velocity = new THREE.Vector3();
    let direction = new THREE.Vector3();
    const speed = 5.0;
    const objects = [];

    init();
    animate();

    function init() {
      // Создание сцены
      scene = new THREE.Scene();
      scene.background = new THREE.Color(0x87ceeb); // Небесно-голубой цвет
      scene.fog = new THREE.Fog(0x87ceeb, 0, 100); // Туман для перспективы

      // Создание камеры (Перспективная камера с FOV 75)
      const aspect = window.innerWidth / window.innerHeight;
      camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 1000);
      camera.position.set(20, 20, 20);
      camera.lookAt(0, 0, 0);

      // Создание рендерера
      renderer = new THREE.WebGLRenderer({ antialias: true });
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.shadowMap.enabled = true;
      renderer.shadowMap.type = THREE.PCFSoftShadowMap;
      document.body.appendChild(renderer.domElement);

      // Добавление освещения
      const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 1.0);
      hemiLight.position.set(0, 50, 0);
      scene.add(hemiLight);

      const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
      dirLight.position.set(20, 50, 10);
      dirLight.castShadow = true;
      dirLight.shadow.camera.top = 50;
      dirLight.shadow.camera.bottom = -50;
      dirLight.shadow.camera.left = -50;
      dirLight.shadow.camera.right = 50;
      dirLight.shadow.mapSize.width = 2048;
      dirLight.shadow.mapSize.height = 2048;
      scene.add(dirLight);

      // Создание пола
      const floorGeometry = new THREE.PlaneGeometry(200, 200);
      const floorMaterial = new THREE.MeshPhongMaterial({ color: 0x999999, depthWrite: false });
      const floor = new THREE.Mesh(floorGeometry, floorMaterial);
      floor.rotation.x = -Math.PI / 2;
      floor.receiveShadow = true;
      scene.add(floor);

      // Добавление сетки
      const grid = new THREE.GridHelper(200, 40, 0x000000, 0x000000);
      grid.material.opacity = 0.2;
      grid.material.transparent = true;
      scene.add(grid);

      // Создание кубов мира
      const boxGeometry = new THREE.BoxGeometry(1, 1, 1);
      const boxMaterial = new THREE.MeshStandardMaterial({ color: 0x00ff00 });

      for (let i = -10; i <= 10; i++) {
        for (let j = -10; j <= 10; j++) {
          const box = new THREE.Mesh(boxGeometry, boxMaterial);
          box.position.set(i * 2, 0.5, j * 2);
          box.castShadow = true;
          box.receiveShadow = true;
          scene.add(box);
          objects.push(box);
        }
      }

      // Создание персонажа
      const playerGeometry = new THREE.BoxGeometry(1, 2, 1);
      const playerMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 });
      const player = new THREE.Mesh(playerGeometry, playerMaterial);
      player.position.set(0, 1, 0);
      player.castShadow = true;
      player.receiveShadow = true;
      scene.add(player);

      // Настройка контролов PointerLock
      controls = new PointerLockControls(camera, document.body);

      const overlay = document.getElementById('overlay');
      const startButton = document.getElementById('startButton');

      startButton.addEventListener('click', () => {
        controls.lock();
      }, false);

      controls.addEventListener('lock', () => {
        overlay.style.display = 'none';
      });

      controls.addEventListener('unlock', () => {
        overlay.style.display = 'flex';
      });

      scene.add(controls.getObject());

      // Настройка пост-обработки
      setupPostProcessing();

      // Настройка GUI
      setupGUI();

      // Обработчики событий
      window.addEventListener('resize', onWindowResize, false);
      document.addEventListener('keydown', onKeyDown, false);
      document.addEventListener('keyup', onKeyUp, false);
    }

    function setupPostProcessing() {
      const renderPass = new RenderPass(scene, camera);

      const fxaaPass = new ShaderPass(FXAAShader);
      fxaaPass.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight);

      composer = new EffectComposer(renderer);
      composer.addPass(renderPass);
      composer.addPass(fxaaPass);
    }

    function setupGUI() {
      const gui = new GUI({ autoPlace: false });
      document.getElementById('gui-container').appendChild(gui.domElement);

      const params = {
        FOV: 75,
        'Скрыть кубы': false
      };

      gui.add(params, 'FOV', 50, 100).onChange((value) => {
        camera.fov = value;
        camera.updateProjectionMatrix();
      });

      gui.add(params, 'Скрыть кубы').onChange((value) => {
        objects.forEach(obj => obj.visible = !value);
      });
    }

    function onWindowResize() {
      const aspect = window.innerWidth / window.innerHeight;
      camera.aspect = aspect;
      camera.updateProjectionMatrix();

      renderer.setSize(window.innerWidth, window.innerHeight);
      composer.setSize(window.innerWidth, window.innerHeight);

      // Обновление разрешения FXAA
      composer.passes.forEach(pass => {
        if (pass instanceof ShaderPass && pass.uniforms['resolution']) {
          pass.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight);
        }
      });
    }

    function onKeyDown(event) {
      switch (event.code) {
        case 'ArrowUp':
        case 'KeyW':
          move.forward = true;
          break;
        case 'ArrowLeft':
        case 'KeyA':
          move.left = true;
          break;
        case 'ArrowDown':
        case 'KeyS':
          move.backward = true;
          break;
        case 'ArrowRight':
        case 'KeyD':
          move.right = true;
          break;
      }
    }

    function onKeyUp(event) {
      switch (event.code) {
        case 'ArrowUp':
        case 'KeyW':
          move.forward = false;
          break;
        case 'ArrowLeft':
        case 'KeyA':
          move.left = false;
          break;
        case 'ArrowDown':
        case 'KeyS':
          move.backward = false;
          break;
        case 'ArrowRight':
        case 'KeyD':
          move.right = false;
          break;
      }
    }

    function animate() {
      requestAnimationFrame(animate);

      const delta = 0.016; // Предполагаемая частота кадров ~60fps

      velocity.x -= velocity.x * 10.0 * delta;
      velocity.z -= velocity.z * 10.0 * delta;

      direction.z = Number(move.forward) - Number(move.backward);
      direction.x = Number(move.right) - Number(move.left);
      direction.normalize(); // Важно для предотвращения ускорения

      if (move.forward || move.backward) velocity.z -= direction.z * speed * delta;
      if (move.left || move.right) velocity.x -= direction.x * speed * delta;

      controls.moveRight(-velocity.x * delta);
      controls.moveForward(-velocity.z * delta);

      composer.render();
    }
  </script>
</body>
</html>