Newer
Older
Three.js / threeJsTemplate.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      body {
        margin: 0;
        overflow: hidden;
      }
    </style>
  </head>

  <body>
    <div id="WebGL-output"></div>

    <script type="module">
      import * as THREE from "https://unpkg.com/three@0.126.1/build/three.module.js";
      import { PointerLockControls } from "https://unpkg.com/three@0.126.1/examples/jsm/controls/PointerLockControls.js";
      import { GLTFLoader } from "https://unpkg.com/three@0.126.1/examples/jsm/loaders/GLTFLoader.js";
      import { FBXLoader } from "https://unpkg.com/three@0.126.1/examples/jsm/loaders/FBXLoader.js";

      let camera;
      let scene;
      let renderer;
      let model;
      let mixer;
      let clock;
      let moveForward = false;
      let moveBackward = false;
      let moveLeft = false;
      let moveRight = false;
      let controls;

      function init() {
        //シーンの作成--
        scene = new THREE.Scene();
        scene.background = new THREE.Color(0x111111); // 背景色
        //--

        //カメラの作成--
        camera = new THREE.PerspectiveCamera(
          45,
          window.innerWidth / window.innerHeight,
          0.1,
          1000
        );
        //カメラセット
        camera.position.set(100, 500, 500); // カメラの位置
        camera.lookAt(new THREE.Vector3(0, 5, 0));

        //ライトの作成
        const light = new THREE.SpotLight(0xffffff, 1.0);
        light.position.set(100, 500, 500);
        scene.add(light);
        light.castShadow = true;
        console.log(light);

        // 補助線
        const axesHelper = new THREE.AxesHelper(500);
        scene.add(axesHelper);
        const gridHelper = new THREE.GridHelper(1, 1);
        scene.add(gridHelper);

        // カメラコントロールの作成
        controls = new PointerLockControls(camera, document.body);

        document.addEventListener("click", function () {
          controls.lock();
          fAudio();
        });
        // controls.addEventListener("lock", function () { });
        // controls.addEventListener("unlock", function () { });

        // キーボードのキーを押したの際の処理
        document.addEventListener("keydown", function (event) {
          switch (event.key) {
            case "w":
            case "ArrowUp":
              moveForward = true;
              break;
            case "s":
            case "ArrowDown":
              moveBackward = true;
              break;
            case "a":
            case "ArrowLeft":
              moveLeft = true;
              break;
            case "d":
            case "ArrowRight":
              moveRight = true;
              break;
          }
        });

        // キーボードのキーを離した際の処理
        document.addEventListener("keyup", function (event) {
          switch (event.key) {
            case "w":
            case "ArrowUp":
              moveForward = false;
              break;
            case "s":
            case "ArrowDown":
              moveBackward = false;
              break;
            case "a":
            case "ArrowLeft":
              moveLeft = false;
              break;
            case "d":
            case "ArrowRight":
              moveRight = false;
              break;
          }
        });

        // レンダラーの作成
        renderer = new THREE.WebGLRenderer({
          alpha: true,
          antialias: true,
        });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.physicallyCorrectLight = true;

        //glbファイルの読み込み
        const gloader = new GLTFLoader();
        gloader.load("model/tohokukoekiGis.glb", function (gltf) {
          model = gltf.scene;
          model.position.set(0, 0.02, 0);
          scene.add(model);
        });

        // fbxファイルの読み込み
        clock = new THREE.Clock();
        //fbxファイルの読み込み
        const loader = new FBXLoader();

        loader.load("model/box_move.fbx", function (object) {
          object.scale.set(0.01, 0.01, 0.01);
          object.position.set(0, 1, 0);
          mixer = new THREE.AnimationMixer(object);
          let action = mixer.clipAction(object.animations[0]);
          action.play();
          scene.add(object);
        });

        // ビデオテクスチャの作成
        const video = document.createElement("video");
        video.src = "video/OkinawaSea.mp4";
        video.src = "video/OkinawaSea.webm";
        video.autoplay = true;
        video.loop = true;
        video.muted = true;
        video.load();
        video.play();
        const texture = new THREE.VideoTexture(video);
        // 動画の表示されているオブジェクトをなめらかにする。
        texture.minFilter = THREE.LinearFilter;
        texture.magFilter = THREE.LinearFilter;
        texture.wrapS = THREE.ClampToEdgeWrapping;
        texture.wrapT = THREE.ClampToEdgeWrapping;
        // ------------------------------------------------
        const textureMaterial = new THREE.MeshBasicMaterial({ map: texture });
        const textureGeometry = new THREE.PlaneGeometry(12, 8);
        const mesh = new THREE.Mesh(textureGeometry, textureMaterial);
        mesh.position.set(0, 5, 0);
        scene.add(mesh);

        // オーディオの作成
        const listener = new THREE.AudioListener();
        camera.add(listener);
        const audioGeometry = new THREE.BoxGeometry(100, 100, 100);
        const audioMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff });
        const cube = new THREE.Mesh(audioGeometry, audioMaterial);
        scene.add(cube);
        const audioLoader = new THREE.AudioLoader();
        const positionalAudio = new THREE.PositionalAudio(listener);

        audioLoader.load("./mp3/OkinawaSea.mp3", function (buffer) {
          positionalAudio.setBuffer(buffer);
          positionalAudio.setRefDistance(100);
          positionalAudio.play();
          positionalAudio.setLoop(true);
        });
        cube.add(positionalAudio);

        document
          .getElementById("WebGL-output")
          .appendChild(renderer.domElement);
      }

      // カメラの移動設定
      function updateCameraPosition() {
        const speed = 10; // 移動速度
        const direction = new THREE.Vector3();
        const { x, y, z } = controls.getObject().position;
        direction.x = Number(moveRight) - Number(moveLeft);
        direction.z = Number(moveBackward) - Number(moveForward);
        direction.normalize();
        const delta = speed * 0.1; // 移動距離
        controls.getObject().translateX(direction.x * delta);
        controls.getObject().translateZ(direction.z * delta);
      }

      function animate() {
        requestAnimationFrame(animate);
        updateCameraPosition();
        if (mixer) mixer.update(clock.getDelta());
        renderer.render(scene, camera);
      }

      // クリックしたら呼ばれる
      function OnClick(event) {
        event.preventDefault();
        const raycaster = new THREE.Raycaster();
        const mouse = new THREE.Vector2();
        // マウスポインタの位置情報の取得
        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
        // 光線を発射
        raycaster.setFromCamera(mouse, camera);
        // 光線と交わるオブジェクトを収集
        const intersects = raycaster.intersectObjects(scene.children, true);
        // 交わるオブジェクトが1個以上の場合
        if (intersects.length > 0) {
          if (intersects[0].object.name == "球") {
            window.open("https://openai.com/blog/chatgpt");
          }
          console.log(intersects[0]);
        }
      }

      // 関数の実行
      init();
      animate();
    </script>
  </body>
</html>