LoginSignup

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

テクスチャをCSSスプライトのように使う方法

前提

CSSスプライトのように複数の画像を並べたcanvas要素を使って効率よくテクスチャを作りたいです(そもそも「そんなことをしても効率化出来ない」ということであればその旨教えて下さい)。

記述その1

const texture = new THREE.CanvasTexture( canvas );
{
  const geometry = new THREE.BoxGeometry( 50, 50, 50 );
  const material = new THREE.MeshLambertMaterial({
    map: texture
  });
  const mesh = new THREE.Mesh( geometry, material );
  mesh.material.map.repeat.set( 0.5, 0.5 );
  mesh.material.map.offset.set( 0.5, 0.5 );
  mesh.position.set( -50, -50, 0 );
  scene.add( mesh );
}
{
  const geometry = new THREE.BoxGeometry( 50, 50, 50 );
  const material = new THREE.MeshLambertMaterial({
    map: texture
  });
  const mesh = new THREE.Mesh( geometry, material );
  mesh.material.map.repeat.set( 0.5, 0.5 );
  mesh.material.map.offset.set( 0, 0.5 );
  mesh.position.set( 50, 50, 0 );
  scene.add( mesh );
}

上記のように記述すると1つ目のmeshと2つ目のmeshが同じ絵で描かれてしまいました。texture情報を参照として保持しているのだろうと思います。

記述その2

const texture = new THREE.CanvasTexture( canvas );
{
  const geometry = new THREE.BoxGeometry( 50, 50, 50 );
  const material = new THREE.MeshLambertMaterial({
    map: texture.clone()
  });
  const mesh = new THREE.Mesh( geometry, material );
  mesh.material.map.repeat.set( 0.5, 0.5 );
  mesh.material.map.offset.set( 0.5, 0.5 );
  mesh.position.set( -50, -50, 0 );
  scene.add( mesh );
}
{
  const geometry = new THREE.BoxGeometry( 50, 50, 50 );
  const material = new THREE.MeshLambertMaterial({
    map: texture.clone()
  });
  const mesh = new THREE.Mesh( geometry, material );
  mesh.material.map.repeat.set( 0.5, 0.5 );
  mesh.material.map.offset.set( 0, 0.5 );
  mesh.position.set( 50, 50, 0 );
  scene.add( mesh );
}

texture.clone()で結果として期待通りの絵は描かれました。

考察

texture.clone()はテクスチャをコピーしているのだと思いますが、これだとそもそもcanvasに複数の画像を含めるよりも、それぞれ別のcanvasを作ってtextureに割り当てるのと変わらないのでは?、と考えました。

知りたいこと

記述その2の書き方(texture.clone())で描くよりも、使用メモリが少なかったり、プログラム的に軽量な記述方法があれば知りたいです。
スライドパズル(15パズル)の元絵があって、元絵を分割せず各コマに貼り付けるイメージです。

どうぞよろしくお願いします。

0

1Answer

Comments

  1. @UsagiLabo

    Questioner

    ありがとうございます。なるほど。頂点情報を変更すれば対応できそうですね。
    uvは手動で変更するのか、と思いますが、もし便利なメソッドがあるようでしたら教えていただけると嬉しいのですがいかがでしょうか。

  2. @UsagiLabo

    Questioner

    Geometryに設定された頂点データのうちテクスチャ座標(uv)を直接指定することで、map: texture.clone()せずに直接map: textureの指定で希望通りの結果を得ることが出来ました。
    座標の値を自前で作る必要がありますがgeometry.attributes.uv.set( value )で指定できることもわかりました。
    教えていただき、どうもありがとうございました。

Your answer might help someone💌