アルゴリズムでどうにかする方法が思い浮かばないので、
小手先でなんとかしてみる。
とりあえず、テーブルのインデックス計算で
RGB各値で別に誤差計算するのではなく、
あらかじめ計算した輝度値だけで行う。
元々のフォーマットが輝度値の誤差をベースカラーに
載せる形式だから、それほど悪くない解だと思う。
浮動小数点数を固定小数点数に直す。
小手先の極みである、計算時間はどうやっても線形にしか減らない。
浮動小数点なら、汚いが見れる範囲だなと思うアルゴリズムでも、
かなり汚くなる。そこまで汚くなるほど精度が足りていないとは思えないので
どこか間違っている。
もう少し思考錯誤の必要がある。
満足いく速度と品質は得られそうにないので、
ユーザが設定するオプションという扱いになりそうだ。
それはプログラマの敗北宣言。
2011年5月23日月曜日
2011年5月20日金曜日
Ericsson Texture Compressionへの圧縮方法
ETC1のフォーマット概要と圧縮法について。
問題は、ETC1へ圧縮するにあたり計算時間が許容できないので、
速い計算方法はないものかというもの。
詳細は、Open GL ES の拡張OES_compressed_ETC1_RGB8_textureの仕様に説明されている。
RGB 24bitの4x4ピクセルを、64ビットに圧縮する。
4x4を、2x4又は4x2のサブブロックに分割し、
サブブロック2つ分のベースカラーにRGB 8bit、
サブブロックそれぞれに差分テーブルのインデックス 3bit、
16ピクセルそれぞれに2bitの、差分テーブルの要素を示すビット 2bit、
残りは、サブブロックの割り方に1bit、ベースカラーの表現方法に1bit、
となる。
base color = 8x3 = 24bit
color table = 3bit x 2 = 6bit
bits for color table = 2bit x 16 = 32 bit
mode flags = 2bit
解凍する場合、計算イメージとしては以下のようになる。
ピクセルの色 = ベースカラー + 差分テーブル[ 2ビットインデックス ]
どう圧縮するかが悩むところ。
差分テーブルは以下左から、テーブル番号、2bit値で11、10、00、01、
0 -8 -2 2 8
1 -17 -5 5 17
2 -29 -9 9 29
3 -42 -13 13 42
4 -60 -18 18 60
5 -80 -24 24 80
6 -106 -33 33 106
7 -183 -47 47 183
テーブル値をどう算出したか妄想すると、統計ではないかと。
計算すべきものは以下の3つ。
・各サブブロックのベースカラーの計算
・ベースカラーに対して、テーブルの決定
・テーブルとベースカラーに対して、2ビットインデックスの計算
発見的手法しかないのかこれは。
問題は、ETC1へ圧縮するにあたり計算時間が許容できないので、
速い計算方法はないものかというもの。
詳細は、Open GL ES の拡張OES_compressed_ETC1_RGB8_textureの仕様に説明されている。
RGB 24bitの4x4ピクセルを、64ビットに圧縮する。
4x4を、2x4又は4x2のサブブロックに分割し、
サブブロック2つ分のベースカラーにRGB 8bit、
サブブロックそれぞれに差分テーブルのインデックス 3bit、
16ピクセルそれぞれに2bitの、差分テーブルの要素を示すビット 2bit、
残りは、サブブロックの割り方に1bit、ベースカラーの表現方法に1bit、
となる。
base color = 8x3 = 24bit
color table = 3bit x 2 = 6bit
bits for color table = 2bit x 16 = 32 bit
mode flags = 2bit
解凍する場合、計算イメージとしては以下のようになる。
ピクセルの色 = ベースカラー + 差分テーブル[ 2ビットインデックス ]
どう圧縮するかが悩むところ。
差分テーブルは以下左から、テーブル番号、2bit値で11、10、00、01、
0 -8 -2 2 8
1 -17 -5 5 17
2 -29 -9 9 29
3 -42 -13 13 42
4 -60 -18 18 60
5 -80 -24 24 80
6 -106 -33 33 106
7 -183 -47 47 183
テーブル値をどう算出したか妄想すると、統計ではないかと。
計算すべきものは以下の3つ。
・各サブブロックのベースカラーの計算
・ベースカラーに対して、テーブルの決定
・テーブルとベースカラーに対して、2ビットインデックスの計算
発見的手法しかないのかこれは。
2011年5月9日月曜日
VBOの修正と頂点の転送
毎フレーム頂点を書き換える必要があるとして、
Vertex Buffer Object(VBO)の書き換えと、
毎フレーム頂点バッファを転送して描画するのはどちらが速いか。
データによりけりではある。
ここからは妄想。
----
VBOの書き換えを行った場合、
描画前にglFlushで書き換えを反映する必要があるGPUと、
そうでないGPUがある。Windows上のエミュレータは後者。
前者は描画時にバッファの書き込みを待たず、
後者は終わるまで待つ。
glFlushを呼ばない場合、
表示からするとバッファが壊れている。
このことから、VBOの書き換え時に
別のバッファを用意している。
仕様上はglFinishでなければ解決できない。
glFlushで上手くいっているように見えるのは、
単にglFlushに時間がかかって転送が完了しているだけなのか。
----
ここまで妄想。
glFlushを毎フレーム呼べば解決する。
しかし、重量級のglFlushは使いたくない、VBOの書き換えもしたい。
VBOのダブルバッファリングを行い、glFlushを呼ばない実装を試してみたところ、
一見上手く動作しているように見える。
swapBuffers等どこかのタイミングで、
そのフレームのコマンドが全て終了するのを待っている(glFinish)
と考えてよいものか。そうであるはずなのだが、自信を持てない。
Vertex Buffer Object(VBO)の書き換えと、
毎フレーム頂点バッファを転送して描画するのはどちらが速いか。
データによりけりではある。
ここからは妄想。
----
VBOの書き換えを行った場合、
描画前にglFlushで書き換えを反映する必要があるGPUと、
そうでないGPUがある。Windows上のエミュレータは後者。
前者は描画時にバッファの書き込みを待たず、
後者は終わるまで待つ。
glFlushを呼ばない場合、
表示からするとバッファが壊れている。
このことから、VBOの書き換え時に
別のバッファを用意している。
仕様上はglFinishでなければ解決できない。
glFlushで上手くいっているように見えるのは、
単にglFlushに時間がかかって転送が完了しているだけなのか。
----
ここまで妄想。
glFlushを毎フレーム呼べば解決する。
しかし、重量級のglFlushは使いたくない、VBOの書き換えもしたい。
VBOのダブルバッファリングを行い、glFlushを呼ばない実装を試してみたところ、
一見上手く動作しているように見える。
swapBuffers等どこかのタイミングで、
そのフレームのコマンドが全て終了するのを待っている(glFinish)
と考えてよいものか。そうであるはずなのだが、自信を持てない。
Adreno SDKとAdreno Profiler
Radeon HD 5770 Windows XP上で、
PowerVR SDKのOpengl ES2エミュレータが動かなくなった。
Windows 7では元から動かない。
というのが以前の話。
代わりにAdreno SDKとProfilerを導入。
Adrenoでの開発はこちらの方がよいか、快適である。
AdrenoがATI Z430だっただけあり、Radeonとの相性がよいらしい。
ドキュメントもRadeon対応状況の記載に比べて、
Geforceは2,3個動作するのは確認したという感じになっている。
次はTegra2かと思うが、Radeonと相性悪そうだな。動くのかな。
Tegra2の性能が頭ひとつ出ているのだから早急にすることでもない。
PowerVR SDKのOpengl ES2エミュレータが動かなくなった。
Windows 7では元から動かない。
というのが以前の話。
代わりにAdreno SDKとProfilerを導入。
Adrenoでの開発はこちらの方がよいか、快適である。
AdrenoがATI Z430だっただけあり、Radeonとの相性がよいらしい。
ドキュメントもRadeon対応状況の記載に比べて、
Geforceは2,3個動作するのは確認したという感じになっている。
次はTegra2かと思うが、Radeonと相性悪そうだな。動くのかな。
Tegra2の性能が頭ひとつ出ているのだから早急にすることでもない。
PowerVRとeglChooseConfig
Galaxy Sでおきたこと。
eglChooseConfigで返ってきたconfigをそのまま使用すると,
eglCreateWindowSurfaceで、BAD_MATCHとなりこける。
問題解決のために検索していると、Motrola Droidでも
似た現象が起きているらしい。
PowerVR系は返ってきたconfigの中から、
depthとstencilが要求以上で、
RGBAが要求とマッチするものを選ぶ必要があるのではないか。
Adreno 200とTegra 250では起きていない。
eglChooseConfigの仕様ってそういうものでした?
要求を満たして使用可能なconfigを返すのではないのか。
Googleのサンプルにあるようにすればよい。
eglChooseConfigで返ってきたconfigをそのまま使用すると,
eglCreateWindowSurfaceで、BAD_MATCHとなりこける。
問題解決のために検索していると、Motrola Droidでも
似た現象が起きているらしい。
PowerVR系は返ってきたconfigの中から、
depthとstencilが要求以上で、
RGBAが要求とマッチするものを選ぶ必要があるのではないか。
Adreno 200とTegra 250では起きていない。
eglChooseConfigの仕様ってそういうものでした?
要求を満たして使用可能なconfigを返すのではないのか。
Googleのサンプルにあるようにすればよい。
登録:
投稿 (Atom)