Why not login to Qiita and try out its useful features?

We'll deliver articles that match you.

You can read useful information later.

0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Three.jsでディスプレイによってオブジェクトのスピード感が違うのをなんとかしたい

Last updated at Posted at 2024-10-16

概要

Three.jsでディスプレイによって動きのスピードが早かったり遅かったりといったことが起こると思います。
その対応策を調べました。

問題のコード

公式サイトのコード
  import * as THREE from "three";

  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

  const renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setAnimationLoop(animate); //⭐️
  document.body.appendChild(renderer.domElement);

  const geometry = new THREE.BoxGeometry(1, 1, 1);
  const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
  const cube = new THREE.Mesh(geometry, material);
  scene.add(cube);

  camera.position.z = 5;

  function animate() {
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    renderer.render(scene, camera);
  }

上記は公式のコードです。
このままの状態だと cubeの動きがブラウザによって早かったり遅かったりします。

仕組みとしては、⭐️をつけた行の setAnimationLoop関数で animate関数を呼び出しています。
その呼び出し方がブラウザのリフレッシュレートに基づいているため、ブラウザごとに早かったり遅かったりします。

対応策

追加編集したコード
  import * as THREE from "three";

  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

  const renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setAnimationLoop(animate);
  document.body.appendChild(renderer.domElement);

  const geometry = new THREE.BoxGeometry(1, 1, 1);
  const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
  const cube = new THREE.Mesh(geometry, material);
  scene.add(cube);

  camera.position.z = 5;

+ const clock = new THREE.Clock(); //①

  function animate() {
+   const elapsedTime = clock.getElapsedTime(); //②

-   cube.rotation.x += 0.01;
+   cube.rotation.x = elapsedTime; //③
-   cube.rotation.y += 0.01;
+   cube.rotation.y = elapsedTime; //③

    renderer.render(scene, camera);
  }

Clockのインスタンスを作成(①の箇所)し、
そこから getElapsedTime メソッドの値を elapsedTime に代入(②の箇所)、
その値を cubeのrotation に代入(③の箇所)しました。

これで、cubeの動きは時間で制御されるようになったので、
リフレッシュレートに関わらず一定の速さで動くようになりました。

おわりに

すごい細かいこだわりかもしれませんが、何も疑問に思わず requastAnimationFrame で動かしたりしていたので、勉強になりました :baby:

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
mnishina

@mnishina

主に勉強した内容や備忘録を投稿します

Comments

diywmk9
@diywmk9

その呼び出し方がブラウザのリフレッシュレートに基づいているため、ブラウザごとに早かったり遅かったりします。

ディスプレイのリフレッシュレートでは?

0

Let's comment your feelings that are more than good

Qiita Conference 2024 Autumn will be held!: 11/14(Thu) - 11/15(Fri)

Qiita Conference is the largest tech conference in Qiita!

Keynote Speaker

Takahiro Anno, Masaki Fujimoto, Yukihiro Matsumoto(Matz)

View event details

Being held Article posting campaign

0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Login to continue?

Login or Sign up with social account

Login or Sign up with your email address