0

一連の医療画像 (jpg) を読み込み、各画像のテクスチャ オブジェクトを作成し、それらのテクスチャを 3D 平面に表示するアプリケーションがあります。画像の量は CT スキャナーの解像度に依存しますが、私のプロトタイプは最大 512 で動作するはずです。

追加のタスクとして、これらのテクスチャを使用して、別の 3D キャンバスでボリューム レンダリングを実行したいと考えています。

WebGL の 3D テクスチャの欠如に対処するすべてのアルゴリズムには、画像形式のテクスチャ アトラスが既に存在しているという「暗黙の」前提条件があります。

ただし、私の場合、そのようなアトラスはありません。

  1. ハードウェアがこの 2D テクスチャ アトラスの結果のサイズをサポートすると仮定すると、既に読み込まれているテクスチャを 1 つの 2D テクスチャに調整してシェーダーに供給するにはどうすればよいでしょうか?

  2. 各画像のデータを 1 つの配列にマージし、それを使用して THREE.DataTexture を作成することを考えました。しかし、それを使用するテクスチャから画像のデータを読み取る方法が見つかりませんでした。ロードされた画像のデータを抽出する別の方法はありますか?

4

1 に答える 1

1

おそらく最も簡単な方法は、テクスチャを 2D キャンバスにロードしてアトラスを構築することです。

512 個のテクスチャをダウンロードする関数があり、それらを 32 x 16 のグリッドに配置するとします。

var width = 128;  // just assuming this is the size of a single texture
var height = 128; 
var across = 32;
var down = 16;

asyncLoad512Images(useLoaded512Images);

function useLoaded512Images(arrayOfImages) {
  var canvas = document.createElement("canvas");
  canvas.width = width * across;
  canvas.height = height * down;
  var ctx = canvas.getContext("2d");

  // draw all the textures into the canvas
  arrayOfImagess.forEach(function(image, ndx) {
    var x = ndx % across;
    var y = Math.floor(ndx / across);

    ctx.drawImage(image, x * width, y * height);
  }

  // now make a texture from canvas.
  var atlasTex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, atlasTex);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
                canvas);
}

いくつかの最適化: コードを変更して、最初にキャンバスを作成し、各画像が読み込まれるときに正しい場所で 2D キャンバスに描画するようにします。利点は、ブラウザが 512 個の画像すべてをメモリに保持する必要がないことです。あなたがそれを描いた直後に、それはそれぞれを捨てることができます。

var width = 128;  // just assuming this is the size of a single texture
var height = 128; 
var across = 32;
var down = 16;
var numImages = 32 * 16;
var numImagesDownloaded = 0;

// make a canvas to hold all the slices
var canvas = document.createElement("canvas");
canvas.width = width * across;
canvas.height = height * down;
var ctx = canvas.getContext("2d");

// assume the images are named image-x.png
for (var ii = 0; ii < numImages; ++ii) {
  loadImage(ii);
}

function loadImage(num) {
  var img = new Image();
  img.onload = putImageInCanvas(img, num);
  img.src = "image-" + num + ".png";
}

function putImageInCanvas(img, num) {
  var x = num % across;
  var y = Math.floor(num / across);

  ctx.drawImage(img, x * width, y * height);

  ++numImagesDownloaded;
  if (numImagesDownloaded === numImages) {
    // now make a texture from canvas.
    var atlasTex = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, atlasTex);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
                  canvas);
    ....
  }
}

または、各画像をテクスチャに変換し、フレーム バッファにアタッチされたテクスチャを使用して、画像テクスチャをアトラス テクスチャにレンダリングすることもできます。それはもっと仕事です。シェーダーの単純な 2D ペアを作成し、各画像テクスチャを正しい場所でアトラス テクスチャにレンダリングする必要があります。

頭のてっぺんからそれを行う唯一の理由は、2D キャンバスは常に事前に乗算されたアルファを使用するため、2D キャンバスで 4 つのチャネルすべてを使用する方法がないため、テクスチャに 3 つ以下ではなく 4 つのチャネルのデータがある場合です。

テクスチャをテクスチャに描画することは、描画期間と同じです。texture に描画する例を参照してください

three.js の短いバージョンは、

レンダー ターゲットを作成する

rtTexture = new THREE.WebGLRenderTarget( 
      width * across, height * down, { 
        minFilter: THREE.LinearFilter, 
        magFilter: THREE.NearestFilter, 
        format: THREE.RGBFormat,
        depthBuffer: false,
        stencilBuffer: false,
    } ); 
 rtTexture.generateMipmaps = false;

レンダリングするプレーンとマテリアルを設定し、シーンに配置します。各画像テクスチャに対して、その画像テクスチャを使用するようにマテリアルを設定し、他のパラメータを設定して、アトラス テクスチャに描画したい場所にクワッドを描画します。私は正投影カメラがそれを最も簡単にするだろうと推測しています. 次に、レンダー ターゲットを指定して render を呼び出します。

renderer.autoClear = false;
renderer.render( sceneRTT, cameraRTT, rtTexture, false );

それはにレンダリングされrtTextureます。

完了しrtTextureたら、アトラス テクスチャです。他のテクスチャと同じようにテクスチャを使用してください。マテリアルに割り当てます。

于 2015-06-16T08:20:46.907 に答える