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

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

ただいまの
回答率

90.48%

  • JavaScript

    20908questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Three.js

    145questions

    Three.jsはWebGLをサポートしているJavaScriptの3D描画用ライブラリです。

  • WebGL

    119questions

    WebGL(ウェブジーエル)は、ウェブブラウザで 3次元コンピュータグラフィックスを表示させるための標準仕様です。

Three.jsで球体にcanvasを貼り付けたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,154

artistan

score 20

 前提・実現したいこと

Three.jsで作った球体SphereGeometryに 1024x512 のキャンバスをマッピングしたいと思っています。

 現状

以下のように実装してみましたが、うまく反映されません。

  container = document.getElementById("body");
  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  container.appendChild(renderer.domElement);

  camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
  camera.position.z = 500;

  var canvas = document.getElementById("canvas");
  geometry = new THREE.SphereGeometry(150, 30, 30);
  texture = new THREE.Texture(canvas);
  material = new THREE.MeshBasicMaterial({
      map: texture
  });
  mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);


球体自体は生成されますが、キャンバスの中身は描画されていません。
また、キャンバスも特に変化がありません。
(マッピングできた場合どうなるのかわかりませんが)

 補足情報

  • Windows10
  • three.js 最新

調べてみても、上記の方法しか紹介されておらず、どうしたものかと悩んでいます。
アドバイスをいただければ幸いです。

 Canvasの内容 ※追記

キャンバスには、世界規模の風速データを非同期で描画する処理を行っています。
http://www.techscore.com/blog/2015/12/13/wind_visualization/
↑データとコードはこちらを参考にしています。

キャンバスは、X:1024, Y:512のサイズで2D描画しています。

  var canvas = d3.select("body").append("canvas")
                  .attr("id", "canvas")
                  .attr("width", 1024)
                  .attr("height", 512);

  var xhr = new XMLHttpRequest();
  xhr.open('GET', './wind.ieee', true);
  // responseType="arraybuffer":サーバに期待するレスポンスタイプを変更できる。
  xhr.responseType = 'arraybuffer';
  xhr.onload = function(e) {
     var buffer   = this.response;
     var wind     = new Float32Array(buffer.byteLength / 4);
     var dataview = new DataView(buffer);
     for (var i = 0; i < wind.length; i++) {
       wind[i] = dataview.getFloat32(i * 4);
     }
     App.run(canvas, wind);
  }
xhr.send();

稚拙な文章で申し訳ないのですが、アドバイスや解決へのアプローチ方法などいただければ幸いです。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • defghi1977

    2018/03/12 23:59

    canvas要素に対する描画の内容について追記して下さい.

    キャンセル

回答 2

check解決した方法

+1

canvas = d3.select("body").append("canvas")
                  .attr("id", "canvas")
                  .attr("width", 1024)
                  .attr("height", 512);
// ↓は別ファイルに記述していた文
context = canvas.node().getContext('2d');


として、描画していたのを

canvas = document.createElement('canvas');
canvas.width = 1024;
canvas.height = 512;
context = canvas.getContext('2d');`


とすることで、テキスチャーにすることが可能となりました!(何故かはわかりませんが)

しかし、指定していた
context.fillStyle()
context.fillRect()
context.globalCompositeOperation
context.strokeStyle
の動作が不安定、或いは完全に効かなくなってしまいました。。。

そういった問題はありますが、取り合えずマッピングできるようにはなったので、質問を解決済みとしたいと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

NOTE:
回答者はThree.jsについてはさほど知りません. 対処策についても実際の動作を試したわけではありません.


おそらくあなたは(2D)canvas上のアニメーションをThree.jsのテクスチャ画像として使おうとしているのでしょう. であればTextureオブジェクトの使い方に対する理解が不足しています.

Three.jsのドキュメントによれば, 

To use video as a texture you need to have a playing HTML5 video element as a source for your texture image and continuously update this texture as long as video is playing - the VideoTexture class handles this automatically. 

https://threejs.org/docs/#api/textures/Texture

「動画をテクスチャとして貼り付けたければ継続的にテクスチャ画像を書き換えよ」とあります. つまりcanvas要素によるアニメーションを貼り付ける場合も同様にしなければならないのです.


ここでTextureのAPI表をみると,

needsUpdate
Set this to true to trigger an update next time the texture is used. Particularly important for setting the wrap mode. 

とあるので, 定期的にneedsUpdateの値をtrueに設定すれば良さそうです.

texture = new THREE.Texture(canvas);
(function update(){
  texture.needsUpdate = true;
  requestAnimationFrame(update);
})();

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/03/13 13:14

    ご回答ありがとうございます!
    確かに、アニメーション処理で有れば、逐次更新をしないとですね
    needsUpdateを追加しましたが、状況変わらずです。。
    エラーはでていません。

    キャンセル

  • 2018/03/13 13:17

    あとはThree.js側もアニメーションしている必要がありますね.

    キャンセル

  • 2018/03/13 13:25

    そちらも
    ```
    function animate() {
    requestAnimationFrame(animate);
    render();
    }

    function render() {
    mesh2.rotation.y += 0.005;
    renderer.render(scene, camera);
    }
    ```
    このような処理をしているのですが、描画されません。
    相も変わらず、マッピングされていない黒い球が生成されるのみです。。

    キャンセル

  • 2018/03/13 13:39

    整理しましょう.

    スクリプトを実行すると二つのcanvas要素が表示されている.
    - 一つはd3.jsによる2Dアニメーション(アニメーションまで表示できている)
    - もう一つはthree.jsによる3Dアニメーション(テクスチャの貼り付けを除き表示できている)
    であるとします.

    であれば次に試すことはcanvas要素をテクスチャとするのではなく別の静的な画像をテクスチャとして正しく動作するかです(テクスチャの貼り付け処理・パラメータが正しいかどうかを確認する).

    キャンセル

  • 2018/03/13 23:36

    結局夜まで返信できず申し訳ありません。
    静止画は、map: THREE.ImageUtils.loadTexture('img')という風にマッピングをすることで、貼り付けできてます!

    アドバイスをいただいる途中でしたが、マッピングできるようになりました。
    できた後も色々と問題は残っているのですが、ひとまず『canvasを貼り付ける』という内容は完了したので、また別のところで質問をします。

    改めてdefghi1977さん
    アドバイスをくださり本当にありがとうございました!

    キャンセル

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

  • JavaScript

    20908questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Three.js

    145questions

    Three.jsはWebGLをサポートしているJavaScriptの3D描画用ライブラリです。

  • WebGL

    119questions

    WebGL(ウェブジーエル)は、ウェブブラウザで 3次元コンピュータグラフィックスを表示させるための標準仕様です。