• HOME
  • SOFTWARE
  • Vue(Nuxt)でBlenderから書き出したglTFファイルを表示させるコーディング例

2020/05/22 20:01

Vue(Nuxt)でBlenderから書き出したglTFファイルを表示させるコーディング例

 

以前にgltfファイルをWP等で表示させる方法を書いたのですが、今回はVueバージョンです。

ちなみにNuxtを使った時の書き方になるので、生のVueとはちょっと違う点もあるかもしれません。

取り合えずこの方法で表示はできました!っていうコーディング例となります。

 

 

Nuxtの記述とかは割愛します

 

PHPerの私がいきなりVue関連の記事とかを上げるのはちょっと抵抗ありましたが、案件で仕方なくNuxtをさわっているついでで、以前にやったBlenderからglTFファイル書き出して表示させるっていうやり方のおさらいになったので。

 

ちなみにVueやNuxtについてのレクチャーは今回一切ありませんのでご了承ください。

 

ちなみに以前のgltfファイルを読み込ませる記事はコチラ

BlenderでglTFファイルとしてエクスポートしてWebGL(ThreeJS)を使ってサイト上に表示させる方法

https://phper.pro/483

 

Threejs系のモジュールのインストール

 

どれがいいのか分からなくて私は何種類かインストールしたんですが…

恐らくコレでいけるんじゃないかと。

 

【コマンドプロンプト】

npm i three

 

これでpackage.jsonにthreeナントカってのが何かしら追記されればOKかと思います。

 

 

Vueの記述例

 

 

後は以前の記事同様に「gltf」ファイルを用意して、それを読み込ませる記述を書いて、その他のアニメーションやらカメラやら照明やらの設定をすればOKです。

 

記述例はコチラ。

 

【〇〇.vue】

<template>

  <div id="scene-container" ref="sceneContainer" />

</template>

 

<script>

import Vue from "vue";

import * as THREE from "three";

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";

 

export default Vue.extend({

  data () {

    return {

      container: null,

      scene: null,

      renderer: null,

      camera: null,

      controls: null,

      url: null,

      width: null,

      height: null,

      mouseX: 0,

      rot: 0,

      targetRot: null,

      radian: null,

      directionalLight: null

    };

  },

  created () {

 

  },

  mounted () {

    this.init();

  },

  methods: {

    init () {

      // set container

      this.container = this.$refs.sceneContainer;

 

      // add camera

      this.width = this.container.clientWidth;

      this.height = this.container.clientHeight;

      if (this.width < 768) {

        this.width = this.container.clientWidth;

        this.height = this.container.clientHeight;

      }

      const fov = 45; // Field of view

      const aspect = this.width / this.height;

      const near = 0.001; // the near clipping plane

      const far = 10000; // the far clipping plane

      const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);

      camera.position.set(0, 0, 0);

      this.camera = camera;

 

      // create scene

      this.scene = new THREE.Scene();

 

      // light

      const directionalLight = new THREE.DirectionalLight(0xFFFFFF);

      directionalLight.position.set(1, 1, 1);

      this.scene.add(directionalLight);

 

      // add controls

      this.controls = new OrbitControls(this.camera, this.container);

      this.controls.enableDamping = true;

      this.controls.dampingFactor = 0.2;

 

      // create renderer

      this.renderer = new THREE.WebGLRenderer({ alpha: true });

      this.renderer.setPixelRatio(window.devicePixelRatio);

      this.renderer.gammaFactor = 2.2;

      this.renderer.outputEncoding = THREE.sRGBEncoding;

      this.renderer.physicallyCorrectLights = true;

 

      this.container.appendChild(this.renderer.domElement);

 

      // set aspect ratio to match the new browser window aspect ratio

      this.camera.aspect = this.width / this.height;

      this.camera.updateProjectionMatrix();

      this.renderer.setSize(this.width, this.height);

 

      const loader = new GLTFLoader();

      const url = "http://localhost:3000/threejs/【ファイル】.gltf";

      loader.load(url, (data) => {

        const gltf = data;

        const object = gltf.scene;

        this.scene.add(object);

      });

 

      const eventHandler = () => {

        this.mouseX = event.pageX;

      };

      // マウス座標はマウスが動いた時のみ取得できる

      document.addEventListener("mousemove", eventHandler);

      const tick = () => {

        this.renderer.render(this.scene, this.camera);

        this.targetRot = (this.mouseX / this.container.clientWidth) * 360;

        this.rot += (this.targetRot - this.rot) * 0.02;

        this.radian = (this.rot * Math.PI) / 180;

        // 角度に応じてカメラの位置を設定

        this.camera.position.x = 0.1 + 0.05 * Math.sin(this.radian);

        this.camera.position.y = 0.00 + 0.05 * Math.sin(this.radian);

        this.camera.position.z = 0.3 + 0.001 * Math.cos(this.radian);

        this.scene.rotation.y += 0.005;

        // camera.lookAt(new THREE.Vector3(0, 0, 0));

        this.controls.update();

        requestAnimationFrame(tick);

      };

      tick();

    }

 

  }

});

</script>

 

<style>

  #scene-container {

  display: block;

  position: absolute;

  top: 0;

  left: 0;

  width: 100%;

  height: 100%;

  z-index: 0;

  }

  #scene-container canvas {

  display: block !important;

  position:  absolute !important;

  top: 50% !important;

  left: 50% !important;

  transform: translate3d(-50%,-50%,0) perspective(0) !important;

  margin: 0 !important;

  padding: 0 !important;

  z-index: 0;

  }

</style>

 

なんせVue&Nuxt初心者なので書き方がどこまで合ってるのかは不明ですが、こんな感じで取り合えず表示させることはできました。

 

 

現場から以上です!

1935

PICK UP