Three.js project: Uncaught TypeError: Failed to resolve module specifier “three”. Relative references must start with either “/”, “./”, or “../”

I’m attempting to use cdn to import the three library as well as several add ons and N8AO. As stated in the title I’m encountering the listed error:

Uncaught TypeError: Failed to resolve module specifier “three”. Relative references must start with either “/”, “./”, or “../”..

I’m getting the error in Chrome however I have not tried any other browser yet. I’m also using WebStorm as my development environment.
I have node.js version 22.12.0 installed however I am just scripting the entirety of the functionality in the html file rather than creating a separate javascript file for the sake of having everything in one spot.
I presume it’s coming from one of the import statements given here. Also including the rest of the project as it may provide other insights:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js Terrain with Grass and N8AO</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { display: block; }
</style>
</head>
<body>
<script type="module">
import * as THREE from 'https://unpkg.com/[email protected]/build/three.module.js';
import { OrbitControls } from 'https://unpkg.com/[email protected]/examples/jsm/controls/OrbitControls.js';
import { EffectComposer } from 'https://unpkg.com/[email protected]/examples/jsm/postprocessing/EffectComposer.js';
import { N8AOPass } from "https://unpkg.com/n8ao@latest/dist/N8AO.js";
// Scene, Camera, Renderer
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(15, 15, 10);
const 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);
// Controls
const controls = new OrbitControls(camera, renderer.domElement);
controls.minPolarAngle = Math.PI / 2.5;
controls.maxPolarAngle = Math.PI / 2.5;
// Sky and lighting
scene.background = new THREE.Color(0xaabbff); // Sky color
scene.add(new THREE.AmbientLight(0x404040)); // Soft ambient light
const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.position.set(10, 10, 10);
pointLight.castShadow = true;
scene.add(pointLight);
// Terrain
const width = 100;
const terrainGeometry = new THREE.PlaneGeometry(width, width, 64, 64);
terrainGeometry.rotateX(-Math.PI / 2);
// Generate elevation for terrain
const simplex = new THREE.SimplexNoise();
for (let i = 0; i < terrainGeometry.attributes.position.count; i++) {
const x = terrainGeometry.attributes.position.array[i * 3];
const z = terrainGeometry.attributes.position.array[i * 3 + 2];
const y = 2 * simplex.noise2D(x / 10, z / 10) + 3 * simplex.noise2D(x / 15, z / 15);
terrainGeometry.attributes.position.array[i * 3 + 1] = y;
}
terrainGeometry.computeVertexNormals();
const terrainMaterial = new THREE.MeshStandardMaterial({ color: 0x228b22 });
const terrain = new THREE.Mesh(terrainGeometry, terrainMaterial);
terrain.receiveShadow = true;
scene.add(terrain);
// Grass
const grassGroup = new THREE.Group();
const bladeGeometry = new THREE.PlaneGeometry(0.12, 1, 1, 4).translate(0, 0.5, 0);
const grassMaterial = new THREE.MeshStandardMaterial({ color: 0x32cd32, side: THREE.DoubleSide });
for (let i = 0; i < 50000; i++) {
const blade = new THREE.Mesh(bladeGeometry, grassMaterial);
blade.position.set(
Math.random() * width - width / 2,
0,
Math.random() * width - width / 2
);
blade.rotation.y = Math.random() * Math.PI * 2;
blade.scale.y = 0.5 + Math.random() * 0.5;
grassGroup.add(blade);
}
scene.add(grassGroup);
// Post-Processing with N8AOPass
const composer = new EffectComposer(renderer);
const n8aoPass = new N8AOPass(scene, camera, window.innerWidth, window.innerHeight);
composer.addPass(n8aoPass);
// Adjust N8AOPass Parameters
n8aoPass.configuration.aoRadius = 5.0; // Set AO radius
n8aoPass.configuration.distanceFalloff = 1.0; // Distance attenuation
n8aoPass.configuration.intensity = 3.0; // AO intensity
n8aoPass.configuration.color = new THREE.Color(0, 0, 0); // AO color
n8aoPass.configuration.halfRes = false; // Full resolution for better quality
// Animation loop
function animate() {
requestAnimationFrame(animate);
// Simulate grass swaying in the wind
grassGroup.children.forEach((blade) => {
blade.rotation.x = 0.1 * Math.sin(performance.now() / 1000 + blade.position.x);
});
composer.render();
}
animate();
// Handle resizing
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
composer.setSize(window.innerWidth, window.innerHeight);
});
</script>
</body>
</html>
</code>
<code><!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Three.js Terrain with Grass and N8AO</title> <style> body { margin: 0; overflow: hidden; } canvas { display: block; } </style> </head> <body> <script type="module"> import * as THREE from 'https://unpkg.com/[email protected]/build/three.module.js'; import { OrbitControls } from 'https://unpkg.com/[email protected]/examples/jsm/controls/OrbitControls.js'; import { EffectComposer } from 'https://unpkg.com/[email protected]/examples/jsm/postprocessing/EffectComposer.js'; import { N8AOPass } from "https://unpkg.com/n8ao@latest/dist/N8AO.js"; // Scene, Camera, Renderer const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(15, 15, 10); const 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); // Controls const controls = new OrbitControls(camera, renderer.domElement); controls.minPolarAngle = Math.PI / 2.5; controls.maxPolarAngle = Math.PI / 2.5; // Sky and lighting scene.background = new THREE.Color(0xaabbff); // Sky color scene.add(new THREE.AmbientLight(0x404040)); // Soft ambient light const pointLight = new THREE.PointLight(0xffffff, 1); pointLight.position.set(10, 10, 10); pointLight.castShadow = true; scene.add(pointLight); // Terrain const width = 100; const terrainGeometry = new THREE.PlaneGeometry(width, width, 64, 64); terrainGeometry.rotateX(-Math.PI / 2); // Generate elevation for terrain const simplex = new THREE.SimplexNoise(); for (let i = 0; i < terrainGeometry.attributes.position.count; i++) { const x = terrainGeometry.attributes.position.array[i * 3]; const z = terrainGeometry.attributes.position.array[i * 3 + 2]; const y = 2 * simplex.noise2D(x / 10, z / 10) + 3 * simplex.noise2D(x / 15, z / 15); terrainGeometry.attributes.position.array[i * 3 + 1] = y; } terrainGeometry.computeVertexNormals(); const terrainMaterial = new THREE.MeshStandardMaterial({ color: 0x228b22 }); const terrain = new THREE.Mesh(terrainGeometry, terrainMaterial); terrain.receiveShadow = true; scene.add(terrain); // Grass const grassGroup = new THREE.Group(); const bladeGeometry = new THREE.PlaneGeometry(0.12, 1, 1, 4).translate(0, 0.5, 0); const grassMaterial = new THREE.MeshStandardMaterial({ color: 0x32cd32, side: THREE.DoubleSide }); for (let i = 0; i < 50000; i++) { const blade = new THREE.Mesh(bladeGeometry, grassMaterial); blade.position.set( Math.random() * width - width / 2, 0, Math.random() * width - width / 2 ); blade.rotation.y = Math.random() * Math.PI * 2; blade.scale.y = 0.5 + Math.random() * 0.5; grassGroup.add(blade); } scene.add(grassGroup); // Post-Processing with N8AOPass const composer = new EffectComposer(renderer); const n8aoPass = new N8AOPass(scene, camera, window.innerWidth, window.innerHeight); composer.addPass(n8aoPass); // Adjust N8AOPass Parameters n8aoPass.configuration.aoRadius = 5.0; // Set AO radius n8aoPass.configuration.distanceFalloff = 1.0; // Distance attenuation n8aoPass.configuration.intensity = 3.0; // AO intensity n8aoPass.configuration.color = new THREE.Color(0, 0, 0); // AO color n8aoPass.configuration.halfRes = false; // Full resolution for better quality // Animation loop function animate() { requestAnimationFrame(animate); // Simulate grass swaying in the wind grassGroup.children.forEach((blade) => { blade.rotation.x = 0.1 * Math.sin(performance.now() / 1000 + blade.position.x); }); composer.render(); } animate(); // Handle resizing window.addEventListener("resize", () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); composer.setSize(window.innerWidth, window.innerHeight); }); </script> </body> </html> </code>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Three.js Terrain with Grass and N8AO</title>
  <style>
    body { margin: 0; overflow: hidden; }
    canvas { display: block; }
  </style>
</head>
<body>
<script type="module">
  import * as THREE from 'https://unpkg.com/[email protected]/build/three.module.js';
  import { OrbitControls } from 'https://unpkg.com/[email protected]/examples/jsm/controls/OrbitControls.js';
  import { EffectComposer } from 'https://unpkg.com/[email protected]/examples/jsm/postprocessing/EffectComposer.js';
  import { N8AOPass } from "https://unpkg.com/n8ao@latest/dist/N8AO.js";

  // Scene, Camera, Renderer
  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.set(15, 15, 10);

  const 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);

  // Controls
  const controls = new OrbitControls(camera, renderer.domElement);
  controls.minPolarAngle = Math.PI / 2.5;
  controls.maxPolarAngle = Math.PI / 2.5;

  // Sky and lighting
  scene.background = new THREE.Color(0xaabbff); // Sky color
  scene.add(new THREE.AmbientLight(0x404040)); // Soft ambient light

  const pointLight = new THREE.PointLight(0xffffff, 1);
  pointLight.position.set(10, 10, 10);
  pointLight.castShadow = true;
  scene.add(pointLight);

  // Terrain
  const width = 100;
  const terrainGeometry = new THREE.PlaneGeometry(width, width, 64, 64);
  terrainGeometry.rotateX(-Math.PI / 2);

  // Generate elevation for terrain
  const simplex = new THREE.SimplexNoise();
  for (let i = 0; i < terrainGeometry.attributes.position.count; i++) {
    const x = terrainGeometry.attributes.position.array[i * 3];
    const z = terrainGeometry.attributes.position.array[i * 3 + 2];
    const y = 2 * simplex.noise2D(x / 10, z / 10) + 3 * simplex.noise2D(x / 15, z / 15);
    terrainGeometry.attributes.position.array[i * 3 + 1] = y;
  }
  terrainGeometry.computeVertexNormals();

  const terrainMaterial = new THREE.MeshStandardMaterial({ color: 0x228b22 });
  const terrain = new THREE.Mesh(terrainGeometry, terrainMaterial);
  terrain.receiveShadow = true;
  scene.add(terrain);

  // Grass
  const grassGroup = new THREE.Group();
  const bladeGeometry = new THREE.PlaneGeometry(0.12, 1, 1, 4).translate(0, 0.5, 0);
  const grassMaterial = new THREE.MeshStandardMaterial({ color: 0x32cd32, side: THREE.DoubleSide });

  for (let i = 0; i < 50000; i++) {
    const blade = new THREE.Mesh(bladeGeometry, grassMaterial);
    blade.position.set(
            Math.random() * width - width / 2,
            0,
            Math.random() * width - width / 2
    );
    blade.rotation.y = Math.random() * Math.PI * 2;
    blade.scale.y = 0.5 + Math.random() * 0.5;
    grassGroup.add(blade);
  }
  scene.add(grassGroup);

  // Post-Processing with N8AOPass
  const composer = new EffectComposer(renderer);
  const n8aoPass = new N8AOPass(scene, camera, window.innerWidth, window.innerHeight);
  composer.addPass(n8aoPass);

  // Adjust N8AOPass Parameters
  n8aoPass.configuration.aoRadius = 5.0; // Set AO radius
  n8aoPass.configuration.distanceFalloff = 1.0; // Distance attenuation
  n8aoPass.configuration.intensity = 3.0; // AO intensity
  n8aoPass.configuration.color = new THREE.Color(0, 0, 0); // AO color
  n8aoPass.configuration.halfRes = false; // Full resolution for better quality

  // Animation loop
  function animate() {
    requestAnimationFrame(animate);

    // Simulate grass swaying in the wind
    grassGroup.children.forEach((blade) => {
      blade.rotation.x = 0.1 * Math.sin(performance.now() / 1000 + blade.position.x);
    });

    composer.render();
  }
  animate();

  // Handle resizing
  window.addEventListener("resize", () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
    composer.setSize(window.innerWidth, window.innerHeight);
  });
</script>
</body>
</html>

The version of Chrome I am using is 131.0.6778.109
The version of Webstorm I’m using is #WS-242.21829.149

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật