4
6

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 3 years have passed since last update.

スマートフォンブラウザでAR(前半)

Last updated at Posted at 2020-05-18

#はじめに
Nest+Visualのある案件で、スマートフォンのカメラでARを行うことになりました。
スマートフォンのカメラを特定の物(マーカー)にかざすと、スマートフォンの画面に3Dモデルが表示される仕掛けです。

ただしアプリケーションを配布するとした場合、

  1. 配布手段
  2. ユーザーにインストールして頂く手間を掛けることになる

という問題があります。

1について、ストアを通して配布する場合、審査を受ける手間や期間が問題になります。
Androidではapkファイルを自前で配布するという手段もありますが、デフォルトの設定では行えませんし、セキュリティ的に問題になり得ます。
iOSではそもそも野良アプリを配布する手段がありません。
2についてですが、突然ご自身のスマホにアプリのインストールを促された場合、応じる方は少ないと思われます。

そこで、スマートフォンのブラウザでARを行うことにしました。

#システム概要
ここでスマートフォンブラウザ(AndroidではChrome、iOSではSafari)において、
次のことを行います。

1.スマホのカメラを使ってマーカーを読みたい
2.マーカーを読み込まれたら、3Dオブジェクトを表示したい
3.ある特定のマーカーが読み込まれたら、演出を行いたい

おそらくA-Frameを用いるのが簡単で手っ取り早いです。
A-Frame

ただし今回はカメラの動作を多少変更したい、マテリアルを直接弄ったりしたいなどあり、よく分かんなくなってきたので
3Dの描画に敢えてThree.jsを直接使うことにしました。(A-FrameはThree.jsを内包しています。)
Three.js
AR.js
また、カメラはWebRTCのAPIを呼び出して起動させています。

#作り始め
まず、ブラウザでローカルファイルにアクセスするため、Chromeのショートカットを新しく作り、以下の起動オプションを追加します。
--args -allow-file-access-from-files
※セキュリティが弱くなるので、このまま外部サイトにアクセスしないように!
※ApatchやIISなどで内部にサーバーを立てて動作確認する場合は不要です。
Chrome_Setting.png

ここでは実験用に、blenderで作った(最初からシーンに置かれている)単位キューブを使用します。
Blenderを開き、cube.glbという名前でエクスポートします。
(Blender2.8.2だと何もプラグインを追加しなくてもgltf 2.0で出力出来て便利です)

次に同じフォルダに新しいhtmlファイルを作り、以下のコードを入力します。

sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<title>モデル表示サンプル</title>
</head>

<body style="margin : 0px; overflow: hidden;">
	<canvas id="myCanvas"></canvas>
	<!-- Three.js -->
	<script src="https://unpkg.com/three@0.110.0/build/three.min.js"></script>
	<script src="https://unpkg.com/three@0.110.0/examples/js/controls/OrbitControls.js"></script>
	<script src="https://unpkg.com/three@0.110.0/examples/js/loaders/GLTFLoader.js"></script>
	<script>
		//////////////////////////////////////////////////////////////////////////////////
		//		Init
		//////////////////////////////////////////////////////////////////////////////////
		// キャンバスの作成
		var width = 640;
		var height = 640;
		var canvasSize = new THREE.Vector2(width, height);
		
		// renderer
		var renderer	= new THREE.WebGLRenderer({
			canvas: document.querySelector('#myCanvas'),
			antialias: true,
		});
		renderer.setClearColor(0x000033, 1.0);
		renderer.setPixelRatio(window.devicePixelRatio);
		renderer.setSize( width, height );
		
		//////////////////////////////////////////////////////////////////////////////////
		//		シーンの初期化
		//////////////////////////////////////////////////////////////////////////////////
		var scene = new THREE.Scene();
		
		//////////////////////////////////////////////////////////////////////////////////
		//		カメラの作成
		//////////////////////////////////////////////////////////////////////////////////
		const camera = new THREE.PerspectiveCamera(60, width / height, 0.01, 100);
		camera.position.set(0, 0.0, 5.0);
		
		//////////////////////////////////////////////////////////////////////////////////
		//		マウス操作(OrbitControls)
		//////////////////////////////////////////////////////////////////////////////////
		controls = new THREE.OrbitControls( camera, renderer.domElement );
		controls.target.set( 0, 0, 0 );
		controls.update();
		
		//////////////////////////////////////////////////////////////////////////////////
		//		オブジェクトのロード
		//////////////////////////////////////////////////////////////////////////////////
		var obj;
		var loader = new THREE.GLTFLoader();
		var url = "cube.glb";
		loader.load( url, function(data) {
			obj = data.scene;
			scene.add( obj );
		}, undefined, function ( error ) {
			console.error( error );
		} );
		
		//////////////////////////////////////////////////////////////////////////////////
		//		ライティング
		//////////////////////////////////////////////////////////////////////////////////
		// 平行光源を作成
		const directionalLight = new THREE.DirectionalLight(0xFFFFFF);
		directionalLight.position.set(1, 1, 5);
		scene.add(directionalLight);
		// 環境光を追加
		const light = new THREE.HemisphereLight(0xFFFFFF, 0x333333, 2.0);
		light.position.set(1, 5, 1);
		scene.add(light);
		
		//////////////////////////////////////////////////////////////////////////////////
		//		毎フレームの描画処理
		//////////////////////////////////////////////////////////////////////////////////
		drawFrame();
		function drawFrame() {
			renderer.render(scene, camera);
			requestAnimationFrame(drawFrame);
		}
	</script>
</body>

</html>

このhtmlファイルをChromeで開くと、このようになります。
ブラウザ上で3Dオブジェクトが表示され、マウスドラッグで視点が回転することを確認しました。
ar_cube.png

次回はカメラ機能、AR機能を追加していきます。
後半:https://qiita.com/NestVisual/items/7d494acf6cdcbd02d45e

参考
https://qiita.com/ta-ke-no-bu/items/b7cd4b4719249a9c365e

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?