5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Next.jsのアプリでThree.jsの3Dモデルを使用

Last updated at Posted at 2023-01-18

@TK-Cさんの"Next.jsにThree.jsを導入して表示させるまでの手順【TypeScript】"には、Next.jsアプリにThree.jsを導入する手順が書いてある。本記事は、Three.jsの3DモデルをNext.jsのサイトに描写する方法を解説していきます。

3Dモデルを表示するコンポーネント

最初に、3Dモデルを表示するコンポーネントを作成します。アプリのルートにcomponentsフォルダーを作ります。3Dモデルを表示するコンポーネントはcomponents/tokyo-model.tsxである。

今回は、Glen FoxLittlest Tokyoモデルを使用します。

components/tokyo-model.tsx
import { useEffect } from 'react'
import * as THREE from 'three'
import Stats from 'three/addons/libs/stats.module.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';

import path from 'path'

const TokyoModel = () => {
  useEffect(() => {
	let mixer;

	const clock = new THREE.Clock();
	const container = document.getElementById( 'container' );

	const stats = new Stats();
	container.appendChild( stats.dom );

	const renderer = new THREE.WebGLRenderer( { antialias: true } );
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );
	renderer.outputEncoding = THREE.sRGBEncoding;
	container.appendChild( renderer.domElement );

	const pmremGenerator = new THREE.PMREMGenerator( renderer );

	const scene = new THREE.Scene();
	scene.background = new THREE.Color( 0xbfe3dd );
	scene.environment = pmremGenerator.fromScene( new RoomEnvironment(), 0.04 ).texture;

	const camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 100 );
	camera.position.set( 5, 2, 8 );

	const controls = new OrbitControls( camera, renderer.domElement );
	controls.target.set( 0, 0.5, 0 );
	controls.update();
	controls.enablePan = false;
	controls.enableDamping = true;

	const dracoLoader = new DRACOLoader();
	dracoLoader.setDecoderPath( 'jsm/libs/draco/gltf/' );

	const loader = new GLTFLoader();
	loader.setDRACOLoader( dracoLoader );
	loader.load('models/gltf/LittlestTokyo.glb', function ( gltf ) {

		const model = gltf.scene;
		model.position.set( 1, 1, 0 );
		model.scale.set( 0.01, 0.01, 0.01 );
		scene.add( model );

		mixer = new THREE.AnimationMixer( model );
		mixer.clipAction( gltf.animations[ 0 ] ).play();

		animate();

	}, undefined, function ( error ) {
		console.error( error );

	} );


	window.onresize = function () {

		camera.aspect = window.innerWidth / window.innerHeight;
		camera.updateProjectionMatrix();

		renderer.setSize( window.innerWidth, window.innerHeight );

	};


	function animate() {

		requestAnimationFrame( animate );

		const delta = clock.getDelta();

		mixer.update( delta );

		controls.update();

		stats.update();

		renderer.render( scene, camera );

	}

  })
  return (
    <div id='container'></div>
  )
}

export default TokyoModel

アプリにコンポーネントを追加

以上の作成したコンポーネントをindex.tsxに入れます。

pages/index.tsx
import type { NextPage } from 'next'
import TokyoModel from '../components/tokyo-model'

const Home: NextPage = () => {

  return (
   <>
      <TokyoModel></TokyoModel>
    </>
  )
}

export default Home

結果

3Dモデルは以下のように表示される。
ezgif.com-gif-maker.gif

本記事に使用したソースコードは以下のgit repositoryに保存しますので、お気軽にご参照ください。

5
2
0

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?