Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

<!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

like image 329
Zodiac Avatar asked Sep 29 '25 10:09

Zodiac


1 Answers

if you open e.g. https://unpkg.com/n8ao@latest/dist/N8AO.js you may notice:

import {Color as $5Whe3$Color, ...a lot of stuff here} from "three";
import {Pass as $5Whe3$Pass} from "three/examples/jsm/postprocessing/Pass.js";
import {Pass as $5Whe3$Pass1} from "postprocessing";

That is the root of the error you see. A browser can import a module using a module specifier that is either an absolute URL, or a relative URL that is resolved using the base URL. To solve it you may use importmap:

<script type="importmap">

In your case that importmap should work:

<script type="importmap">
        {
            "imports": {
                "three": "https://unpkg.com/[email protected]/build/three.module.js",
                "three/examples/": "https://unpkg.com/[email protected]/examples/",
                "postprocessing"   : "https://unpkg.com/[email protected]/build/index.js"            
            }
        }
</script>
<script type="module">
  // your code here
<script>

like image 61
Andrey Smolko Avatar answered Oct 02 '25 04:10

Andrey Smolko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!