質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.06%

WebGL(Three.js)の読み込みを早くしたい。div要素内(別窓)で描画して、その間にページのスクロールやクリックができるようにしたい。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 2,017

score 17

Three.jsでdraco圧縮したモデルを表示することができました。
しかし、まだ読み込みに時間がかかるため、もっと高速化して快適にページを見れるようにしたいです。
今はdraco圧縮したgltfデータ(圧縮後4,346kB)を下記のコードのようにして表示しています。現段階でページを開いてから読み込みに13秒くらいかかっています。

<!-------------------THREE.js------------------------>

<script type="text/javascript">
    // once everything is loaded, we run our Three.js stuff.
    function init() {
        // create a scene
        var scene = new THREE.Scene();

        // create a camera
        var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);

        // create a render and set the size
        var webGLRenderer = new THREE.WebGLRenderer();
        webGLRenderer.setClearColor(new THREE.Color(0xdddddd));
        webGLRenderer.setSize(window.innerWidth / 2.38, window.innerHeight / 2.5);
        webGLRenderer.shadowMap.enabled = true;
        /*カクツキ防止? 解像度は下がる?*/
        webGLRenderer.setPixelRatio(1);
        console.log(window.innerWidth);
        // position and point the camera
        camera.position.x = -1.0;
        camera.position.y = 1.2;
        camera.position.z = 0.80;
        camera.lookAt(new THREE.Vector3(0, 0, 0));

        // add spotlight for the shadows
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.castShadow = true;
        spotLight.position.set(-5, 7, 6);
        spotLight.intensity = 1;
        scene.add(spotLight);

        var dirLight = new THREE.DirectionalLight(0xffffff);
        dirLight.position.set(30, 30, 30);
        dirLight.intensity = 0.8;
        scene.add(dirLight);
        // add the output of the renderer to the html element
        wrapper = document.getElementById("threejs");
        wrapper.appendChild(webGLRenderer.domElement);


        var controls = new THREE.OrbitControls(camera, wrapper);
        var mesh, mixer;
        var clock = new THREE.Clock();
        /*****************ローディングマネジャー***********************/
        var loadingManager = new THREE.LoadingManager(function() {
            var loadScreen = document.getElementById("loading-screen");
            loadScreen.classList.add('fade-out');
            loadScreen.addEventListener('transitioned', onTransitionEnd);
        });

        function onTransitionEnd(event) {

            event.target.remove();
        }
        /*****DracoLoder追加します*****/
        THREE.DRACOLoader.setDecoderPath('threejs/js/libs/draco/gltf/');
        var dracoLoder = new THREE.DRACOLoader();
        var loader = new THREE.GLTFLoader(loadingManager);
        loader.setDRACOLoader(dracoLoder);

        loader.load('threejs/models/gltf/modelDraco.gltf', function(data) {
            var gltf = data;
            object = gltf.scene;
            var animations = gltf.animations;

            if (animations && animations.length) {
                var i;

                mixer = new THREE.AnimationMixer(object);

                for (i = 0; i < animations.length; i++) {
                    mixer.clipAction(animations[i]).play();
                }
            }

            scene.add(object);
            render();
        });

        var step = 0;

        function render() {
            var delta = clock.getDelta();

            // on-offスイッチ用
            if (params) {
                mixer.update(delta);
            }

            webGLRenderer.render(scene, camera);
            controls.update();

            // render using requestAnimationFrame
            requestAnimationFrame(render);
            webGLRenderer.render(scene, camera);
            window.addEventListener('resize', onWindowResize, false);
        }

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            webGLRenderer.setSize(window.innerWidth / 2.38, window.innerHeight / 2.5);
            var onwidth = 650;
            var windowWidth = window.innerWidth;

            if (windowWidth <= onwidth) {
                webGLRenderer.setSize(window.innerWidth / 2.38, window.innerHeight / 4.0);
            }
        }

    }
    window.onload = init();
</script>
<!--------------------------------------------------->

また、このthree.jsはページの一部分のdiv要素内で描画するようにしています。window.onload = (関数)  の記述によってhtmlページを読み込んでからthree.jsの読み込みと描画をし始めるはずなので、モデルの読み込み中にページのスクロール等ができると思っていたのですが、できませんでした。そのようにすることはできないのでしょうか?
(Firefox, edge, safari では内容の表示はページ上部に限りますが、スクロールができました。Chromeだとモデルが完全に読み込まれるまでスクロール等ができず、読み終わるまで固まってしまいました。)
setpixelratioも上記コードのように付け足してみましたが、Google PageSpeed Insightsで確認したところ効果がありませんでした。

なにか良い方法がありましたら教えていただきたいです。

よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

3Dモデルは、PNGやJpegといった2D画像と違い、「ダウンロードする⇒ダウンロードしたデータを解析し、画面に表示できる形に変換する」というステップが必要になります。
ダウンロード中のステップは、ブラウザ側で平行してその処理が行えるようになっているのですが、データ解析&変換ステップはCPUのスレッドを使ってしまうため、ひと工夫しないと、上記で試されたように画面の更新をブロックしてしまいます。

これをブロックしないようにする仕組みはいくつかあるのですが、その中の一つである「WebWorker可」に、今Three.jsの貢献者たちが尽力してくれているそうです。

https://rawgit.com/kaisalmen/three.js/WorkerLoader_OBJLoader/examples/webgl_loader_worker_draco.html

上記はThree.jsの貢献者の一人が、Draco&GLTFローダーを、WebWorkerを使用して画面をブロックしないようにしてくれている途中(ほぼ完了かも)の段階のものです。
この後、そう遠くない未来(3カ月とか半年とか?)に、公式のサンプルローダーとして上げられると思います。
もし、そのThree.jsのバージョン更新まで待てない!というのでしたら、上記を使って試してみるのもいいかもしれません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/18 12:56

    ありがとうございます。
    とりあえずモデルの解像度を落とすことで対応しようかと思います!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.06%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • トップ
  • JavaScriptに関する質問
  • WebGL(Three.js)の読み込みを早くしたい。div要素内(別窓)で描画して、その間にページのスクロールやクリックができるようにしたい。