Three.js 项目:未捕获类型错误:无法解析模块说明符“三”。相对引用必须以“/”、“./”或“../”开头

问题描述 投票:0回答:1

我正在尝试使用 cdn 导入三个库以及几个附加组件和 N8AO。正如标题中所述,我遇到了列出的错误:

未捕获的类型错误:无法解析模块说明符“三”。相对引用必须以“/”、“./”或“../”开头..

我在 Chrome 中收到错误,但我还没有尝试过任何其他浏览器。我也使用 WebStorm 作为我的开发环境。
我安装了 Node.js 版本 22.12.0,但是我只是在 html 文件中编写全部功能的脚本,而不是为了将所有内容集中在一处而创建单独的 javascript 文件。
我认为它来自此处给出的导入声明之一。 还包括项目的其余部分,因为它可能提供其他见解:

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

我使用的Chrome版本是131.0.6778.109
我使用的 Webstorm 版本是#WS-242.21829.149

javascript html three.js cdn
1个回答
0
投票

如果您打开例如https://unpkg.com/n8ao@latest/dist/N8AO.js你可能会注意到:

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";

这就是您看到的错误的根源。浏览器可以使用模块说明符导入模块,该模块说明符可以是绝对 URL,也可以是使用基本 URL 解析的相对 URL。要解决这个问题,您可以使用:

<script type="importmap">

您的情况:

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

© www.soinside.com 2019 - 2024. All rights reserved.