LoginSignup
17
11

More than 3 years have passed since last update.

three.jsをスマホアプリで動かして暖をとる(react-native-webglの導入手順)

Last updated at Posted at 2019-02-11

追記

react-native-webgl は deprecated となりました...

RNの新しいバージョンではreact-native-webglは動かないと思うので、お勧めされているexpo-glを使いましょう!

はじめに

この記事では、react-native-webglというライブラリの導入手順について書きます。

react-native-webglは、React NativeWebGLを使うためのライブラリです。
これを使えばネイティブアプリでthree.jsが使えるようになるので、試しに作ってみました!

とりあえずスマホカイロにしてみましたが、誰かかっこいいアプリ作ってくれないかな・・・

iOS: https://itunes.apple.com/us/app/three-js-native/id1447928256
Android: https://play.google.com/store/apps/details?id=com.three

Simulator Screen Shot - iPhone 8 Plus - 2019-02-06 at 20.52.51.png Simulator Screen Shot - iPhone 8 Plus - 2019-02-06 at 21.02.12.png

  • アプリ内の4種類のシーンのうち、Octahedronをたくさん表示するものが一番あったまれます。
  • segments(ポリゴンの分割数)などのパラメータは、最大にするとメモリが足らずアプリが落ちることがありますので、徐々に上げてみてください。

React Nativeの準備

公式のgetting-started通りに準備しましょう。
今回はexpoを使わないので、”Quick Start”ではなく、”Building Projects with Native Code”のタブに従ってください。

react-native-webglのインストール

React Nativeの最新はこの記事の執筆時点で0.58ですが、このバージョンではビルドが通らないため、0.57にします。

# init
react-native init threejsNative --version 0.57
cd threejsNative

その後、react-native-webglのパッケージをインストールしてリンクします。

yarn add react-native-webgl
react-native link react-native-webgl

iOS

New Build SystemではGPUImageというプロジェクト周りでエラーが出てしまうため、Legacy Build Systemに変更します。

File -> Workspace Settings... -> Build System -> Legacy Build System

Screen Shot 2019-02-08 at 1.35.54.png
Screen Shot 2019-02-08 at 1.36.12.png

Android

issueを読みつつ諸々を書き換えます。

android/build.gradle
  buildscript {

    ext {

-     minSdkVersion = 16
+     minSdkVersion = 17

    }

    dependencies {

+     classpath 'de.undercouch:gradle-download-task:3.1.2'

    }
node_modules/react-native-webgl/android/src/main/jni/Application.mk
- APP_PLATFORM := android-9
+ APP_PLATFORM := android-16

- APP_STL := gnustl_shared
+ APP_STL := c++_shared

- NDK_TOOLCHAIN_VERSION := 4.9
node_modules/react-native-webgl/android/build.gradle
  task packageRNWebGLLibs(dependsOn: buildRNWebGLLib, type: Copy) {

-   exclude '**/gnustl_shared.so'
+   exclude '**/libc++_shared.so'

  }

  android {

-   buildToolsVersion '25.0.0'
+   buildToolsVersion '27.0.3'

  }

  dependencies {
-   compile "com.facebook.react:react-native:+"  // From node_modules
+   implementation "com.facebook.react:react-native:+"  // From node_modules
  }

exclude '**/libc++_shared.so'でビルドが通らない時はinclude '**/libc++_shared.so'でうまくいく場合があります。

three.jsを読み込む

あとは公式のexampleの通りです。

yarn add three
three.js
const THREE = require("three");
global.THREE = THREE;
if (!window.addEventListener)
    window.addEventListener = () => { };
require("three/examples/js/renderers/Projector");
export default THREE;
App.js
import React from "react";
import { View } from "react-native";
import { WebGLView } from "react-native-webgl";
import THREE from "./three";

export default class App extends React.Component {
  requestId: *;
  componentWillUnmount() {
    cancelAnimationFrame(this.requestId);
  }
  onContextCreate = (gl: WebGLRenderingContext) => {
    const rngl = gl.getExtension("RN");

    const { drawingBufferWidth: width, drawingBufferHeight: height } = gl;
    const renderer = new THREE.WebGLRenderer({
      canvas: {
        width,
        height,
        style: {},
        addEventListener: () => {},
        removeEventListener: () => {},
        clientHeight: height
      },
      context: gl
    });
    renderer.setSize(width, height);
    renderer.setClearColor(0x000000, 1);

    let camera, scene;
    let cube;

    function init() {
      // ここにcameraやsceneのコードを書く
      camera = new THREE.PerspectiveCamera(75, width / height, 1, 1100);
      camera.position.y = 150;
      camera.position.z = 500;
      scene = new THREE.Scene();

      let geometry = new THREE.BoxGeometry(200, 200, 200);
      for (let i = 0; i < geometry.faces.length; i += 2) {
        let hex = Math.random() * 0xffffff;
        geometry.faces[i].color.setHex(hex);
        geometry.faces[i + 1].color.setHex(hex);
      }

      let material = new THREE.MeshBasicMaterial({
        vertexColors: THREE.FaceColors,
        overdraw: 0.5
      });

      cube = new THREE.Mesh(geometry, material);
      cube.position.y = 150;
      scene.add(cube);
    }
    const animate = () => {
      this.requestId = requestAnimationFrame(animate);
      renderer.render(scene, camera);

      // ここにアニメーションのコードを書く
      cube.rotation.y += 0.05;

      gl.flush();
      rngl.endFrame();
    };

    init();
    animate();
  };
  render() {
    return (
      <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
        <WebGLView
          style={{ width: 300, height: 300 }}
          onContextCreate={this.onContextCreate}
        />
      </View>
    );
  }
}

three.jsの部分は通常とほとんど同じように書けます!

実行

iOS/Androidそれぞれでオブジェクトが表示されれば成功です。

react-native run-ios
react-native run-android

まとめ

react-native-webglを使って、スマホアプリでthree.jsを動かす方法について書きました。
three.jsを使ったかっこいいアプリがさらに増えていくと嬉しいですね!

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