1

画像を WebGL に読み込んでから GPU にアップロードしようとしています。元の画像は圧縮されていない/可逆ですが、圧縮されたテクスチャ形式を使用したいと思います。

アップロードするには、これが私がやっていることです:

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureSource);

上記のコードでtextureSourceは、読み込まれた ("texture.png" など) です。

それはすべてうまくいきますが、画像を圧縮して保存するためにWEBGL_compressed_texture_s3tcフォーマット ( )をロードしたいと思います。COMPRESSED_RGB_S3TC_DXT1_EXT

拡張機能が利用可能で有効になっていることを確認します...

var ext = gl.getExtension("WEBGL_compressed_texture_s3tc");
var fmt = ext.COMPRESSED_RGBA_S3TC_DXT5_EXT;
console.log(fmt); // 33779

しかし、それではフォーマットとして使用できません。使用texImage2D()しても機能しません:

gl.texImage2D(gl.TEXTURE_2D, 0, fmt, fmt, gl.UNSIGNED_BYTE, textureSource);
// WebGL: INVALID_ENUM: texImage2D: invalid texture format
// [.WebGLRenderingContext]RENDER WARNING: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'

期待される方法は ですがcompressedTexImage2D()、それもあまり役に立ちません:

gl.compressedTexImage2D(gl.TEXTURE_2D, 0, fmt, 256, 256, 0, texture.source);
// Uncaught TypeError: Failed to execute 'compressedTexImage2D' on 'WebGLRenderingContext': parameter 7 is not of type 'ArrayBufferView'.

これは明らかに、私が渡しているような JavaScript イメージではなく、実際の DDS/DXT データをcompressedTexImage2D()期待しているためです。Uint8Array

明らかな解決策は、ファイルをネイティブの DDS 形式 (別の場所で圧縮されたファイル) でアップロードすることです。しかし、それは私が避けようとしているものです。現在のワークフローでは、画像を事前に圧縮する (または複製する) よりも、元の形式で画像を保持する方が理にかなっています。

私の質問は次のとおりです。元のPNG画像を引き続き使用してロードし、圧縮形式でGPUにアップロードできますか? つまり、テクスチャをオンザフライで DXT1/5 形式に圧縮できますか?

私がやっていることは、ビデオ メモリによって少し制限されているので、節約できれば素晴らしいことです。と他のデータ型を使用して、テクスチャが使用するスペースを最小限に抑えることができましたUNSIGNED_SHORT_4_4_4_4。これは良いスタートですが、ネイティブ圧縮も使用してみたいと思います。

このトピックに関するドキュメントはあまり見つかりませんし、他の人気のあるライブラリ (Three.js、Pixi など) に関連するコードも見つかりませんでした。このページは、ライセンスの問題を示唆しています。これが、WebGL がファイルを適切に圧縮する方法を備えておらず、画像オブジェクトのブラウザー サポートを許可していない理由である可能性があります。

4

2 に答える 2

2

元の PNG 画像を引き続き使用してロードし、圧縮形式で GPU にアップロードすることはできますか? つまり、テクスチャをオンザフライで DXT1/5 形式に圧縮できますか?

私が知る限り:いいえ

私はデスクトップと組み込み GL でしか作業していませんが、専用のコードやライブラリがなければ、オンザフライでテクスチャを圧縮する機会さえありません。

(そして、これらの DXT 形式は、テクスチャが詳細すぎる場合や、小さなバケット内にさまざまな色がたくさん含まれている場合にも、あまり適していません。ほとんどの場合、DXT1 は 1/ 8th と DXT5 を元のサイズの 1/4 にします (テクスチャの解像度を半分にするようなものです)。

于 2014-11-13T23:30:57.163 に答える
0

理論的には、Javascript を使用して PNG を DXT に圧縮できると思います。私はそれがただ怒っていると思います:)

ネイティブ コードで事前にエンコードすることをお勧めします。PNG コンテンツをサポートするためのオプションは、サーバー側でオンザフライで変換を行うためのアセット プロキシを用意することです ( http://www.meshmoon.com/をホストするパートナー企業はまさにそれを行います)。

于 2014-11-15T23:57:24.850 に答える