FC2ブログ

スラtmp

色々置き場

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
  1. --/--/--(--) --:--:--|
  2. スポンサー広告

ActionScript DepthPeeling(2Layer)

以前の記事で OIT に触れていたんですがそれの2層のみの簡易版実装です

とりあえず SWF です
三枚の半透明の板ポリを交差させてレンダリングしてます
描画順は RED -> GREEN -> BLUE
上が今回の実装
下が比較用の普通のアルファブレンディングです
DepthPeeling_00.png

ソース Main.as

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

OIT について

Yakiimo3D さん DX11 Order Independent Transparency
http://www.yakiimo3d.com/ja/2010/07/19/dx11-order-independent-transparency-2/

上記の linked list OIT は AGAL のシェーダーでは実装できそうにないので

床井研究室さん Depth Peeling
http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20081123

こちらの Depth Peeling の手法で実装してみます

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

真面目に実装したり、 3 層以上剥がすとなると独自 Z バッファが必要で
更にシェーダーもそれに合わせて書く必要があります

それだと他のフレームワークで使うときにかなり大掛かりなことになるので
できるだけ楽でそれなりの結果になる方法考えてました。

そこで最前面ピクセルとそれ以外の奥にあるピクセルの 2 層のみに限定しちゃいます

デメリットとして
1 ピクセル中で 3 層以上重なってる場合は奥側のソート次第では正確な色にはならない場合がある
(上のデモでも3層重なってる真ん中辺りの右側部分は緑成分が足りないです)

その代わり、メリットとして
・真面目にやるよりレンダリングコスト低下
・ Z テストとステンシルテストのみで実装できるので AGAL 自体はいじる必要が無い

この辺は作りたいものの仕様で使うかどうか選ぶことになります。
( 3 層以上半透明が重なっていて、かつその表現に正確性が求められる場合)

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

ソースから抜粋

---------------------------------------------------------------------------------------------------------------

//////////////////////////////////////////////////
// draw mesh

context3D.setBlendFactors( Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA );
context3D.setCulling( Context3DTriangleFace.NONE );

// 1 pass
context3D.setDepthTest( true, Context3DCompareMode.LESS );
context3D.setColorMask( false, false, false, false );
context3D.setStencilReferenceValue( 1 );
context3D.setStencilActions( Context3DTriangleFace.FRONT_AND_BACK, Context3DCompareMode.ALWAYS, Context3DStencilAction.SET );
drawAlphaMesh();

// 2 pass
context3D.setDepthTest( false, Context3DCompareMode.GREATER );
context3D.setColorMask( true, true, true, true );
context3D.setStencilReferenceValue( 1 );
context3D.setStencilActions( Context3DTriangleFace.FRONT_AND_BACK, Context3DCompareMode.EQUAL, Context3DStencilAction.KEEP );
drawAlphaMesh();

// 3 pass
context3D.setDepthTest( false, Context3DCompareMode.EQUAL );
context3D.setStencilActions();
drawAlphaMesh();

---------------------------------------------------------------------------------------------------------------

● 1 pass 目
Z バッファに半透明ポリゴンの最前面の Z 値書き込み
色は描画しない
ステンシルバッファに "1" を書き込んでおきます
この領域をマスクとして使います。これが無いと他に不透明オブジェクトが存在してる場合に困るので

● 2 pass 目
最前面より奥にあるピクセルを描画します。
Z テストを反転させます。Context3DCompareMode.GREATER
ステンシルテストで "1" の箇所のみに。

● 3 pass 目
最前面のピクセルを描画します
すでにこのピクセルの Z 値は書き込まれているので、Z テストは Context3DCompareMode.EQUAL

---------------------------------------------------------------------------------------------------------------

まとめると、
最前面以外を普通にアルファブレンディングで描画
(この為、2 層目以降の描画順ソートが正しくない場合、色が正確になりません)
最後に最前面をアルファブレンディングです

---------------------------------------------------------------------------------------------------------------

実はもう 1 点問題があって、マスク領域中に不透明オブジェクトがあると
2 層目以降の描画時に前後関係がおかしくなる場合があります。( Z テストが GREATER のため)
これは不透明オブジェクトの描画時にもステンシルでマスクをしておけば防げそうですが
他のフレームワークで使うときに影響範囲が大きくなるのが嫌でどうするかまだ決めてません。

---------------------------------------------------------------------------------------------------------------

スポンサーサイト
[PR]

デリヘルもソープもイメクラも気に入った子がきっと見つかる
超大型リニューアル中の大好評風俗情報サイト!
  1. 2012/12/28(金) 03:58:29|
  2. ActionScript
  3. | トラックバック:0
  4. | コメント:0

FlashPlayer 11.6 beta BASELINE_EXTENDED Multiple render targets

FP 11.6 beta の 新機能の Multiple render targets です

これは今まで一つだったピクセルシェーダーの出力先が最大 4 つまで使えるようになる拡張機能です

使い方は
レンダーターゲットテクスチャを指定する際の第 5 引数に 0 - 3 の数値を指定します

(ex.
context3D.setRenderToTexture( texture, enableDepthAndStencil, antiAlias, surfaceSelector, 0 );
context3D.setRenderToTexture( texture, enableDepthAndStencil, antiAlias, surfaceSelector, 1 );
context3D.setRenderToTexture( texture, enableDepthAndStencil, antiAlias, surfaceSelector, 2 );
context3D.setRenderToTexture( texture, enableDepthAndStencil, antiAlias, surfaceSelector, 3 );

これで、ピクセルシェーダー内でレジスタ oc0 - oc3 に対応します

この際これらのテクスチャフォーマット( Context3DTextureFormat )は同一にしておく必要があります

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

とにかく簡単なコードで試そうと思ったんですが、よく分からないエラーが出てしまい
動かすためににちょっと変な感じの clear() 等追加してるので
ここから下のサンプルはあまり信用せず、公式のサンプル待つのが無難だと思います

正しい書き方分かったらこの記事に追記しておきます

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

まず適当な画像テクスチャを4枚準備してそれらを貼った四角ポリを表示するだけのプログラムを書きました
この時点では Multiple render targets は全く関係ありません
FP11_6_MRT_00.jpg

次に、この4枚のテクスチャを Multiple render targets で同時に赤で塗りつぶすコード追加します
つまり画面に赤い四角ポリが 4 つ表示されれば成功です。地味ですが。
FP11_6_MRT_01.jpg

紆余曲折してとりあえず動かせました。

ソース Main.as

コード自体は非常にシンプルです
毎フレーム 4枚のテクスチャを赤で塗りつぶし、次にそのテクスチャ貼った四角ポリを表示してるだけです
Multiple render targets の描画部分は LINE 142 - 163 です。

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

ソース中のなんか微妙な感じのする箇所について。

---------------------------------------------------------------------------------------
exception, 情報=Error: Error #3728: 複数のテクスチャにレンダリングする場合は、
スロット 0 がアクティブである必要があります。巻き戻し用のバッファーに
レンダリングする場合は、テクスチャスロットへのすべてのレンダリングが
無効になっている必要があります。


最初このエラーが出たので

LINE161: context3D.present();

を追加してます。

---------------------------------------------------------------------------------------

exception, 情報=Error: Error #3692: 描画の前にフレームごとにすべてのバッファーをクリアする必要があります。

また怒られたので

LINE145: context3D.clear( 0, 0, 0, 1 );

を追加してます。

---------------------------------------------------------------------------------------
  1. 2012/12/26(水) 20:16:01|
  2. ActionScript
  3. | トラックバック:0
  4. | コメント:0

FlashPlayer 11.6 beta BASELINE_EXTENDED Depth Output

FP 11.6 beta の 新機能の深度バッファへの出力です

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

書き方はこんな感じです

mov od0.x fc0.x

ピクセルシェーダー用レジスタ
AGALMiniAssembler でのレジスタ名は od または od0
書き込み専用(多分)
使うときは od.x のマスク必須
値は 0.0 - 1.0 の範囲に丸められます
書き込む値で Depth テストを通れば書き込まれる

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

いつもダラダラと記事が長いんでたまには短く

  1. 2012/12/26(水) 00:56:30|
  2. ActionScript
  3. | トラックバック:0
  4. | コメント:0

FlashPlayer 11.6 beta BASELINE_EXTENDED AGAL

FP 11.6 beta の 新機能のうち
BASELINE_EXTENDED 指定で拡張される AGAL の命令見てみます

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

関連リンク再掲

akihiro kamijo
Flash Player の Stage3D の新しいプロファイル BASELINE_EXTENDED

http://cuaoar.jp/2012/12/flash-player-stage3d-bas.html#more

Adobe Flash Player 11.6 Beta
New features for browser-based, expressive content

http://labs.adobe.com/technologies/flashruntimes/flashplayer/

Folsom Prerelease Release Notes
Flash Player 11.6 and AIR 3.6 Release Notes

http://labsdownload.adobe.com/pub/labs/flashruntimes/shared/air3-6_flashplayer11-6_releasenotes.pdf

新しい AGALMiniAssembler
https://dl.dropbox.com/u/7009356/stage3d-extended-profile/AGALMiniAssembler.as


////////////////////////////////////////////////////////////////////////////////////////////////////////////////

akihiro kamijo さんのサイトに書いてあるとおり
requestContext3D の第二引数に Context3DProfile.BASELINE_EXTENDED を渡してみます。

stage3D.requestContext3D( Context3DRenderMode.AUTO, Context3DProfile.BASELINE_EXTENDED );

特に見た目は変わってないですが、
context3D.driverInfo の情報が
"DirectX9" から "DirectX9 (Baseline Extended)"
になりました。

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

リリースノートと新しい AGALMiniAssembler.as 眺めてみます

----------------------------------------------------------------------------------

拡張される命令

●条件分岐(頂点シェーダー、ピクセルシェーダー)
ife src1, src2     // if src1 == src2
ine src1, src2 // if src1 != src2
ifg src1, src2 // if src1 >= src2
ifl src1, src2 // if src1 < src2
els // else
eif // endif

// 上記リンクのPDFでは2012/12/25時点で "ilt" になってますが
// AGALMiniAssembler では "ifl" になってます。
// ilt が正しいなら ifg ではなく igt
// ifg が正しいなら ilt ではなく ifl のはずなので
// AGALMiniAssembler が正しいことにして進めます

●隣接ピクセルとの勾配取得(ピクセルシェーダー)
ddx dst, src1     // x 方向隣接ピクセルの src1 レジスタ間の勾配(差分値)を dst に代入
ddy dst, src1 // y 方向隣接ピクセルの src1 レジスタ間の勾配(差分値)を dst に代入

これらの挙動についてはいくつかリンクを

DirectXのシェーダ(HLSL)における勾配関数ddx ddyの挙動調査
http://mosapui.blog116.fc2.com/blog-entry-35.html

ddx, ddyの挙動を調べてみた
http://monsho.blog63.fc2.com/blog-entry-105.html

●ミップマップテクスチャからのサンプリング時にレベルを指定できる命令
ted dst, src1, src2 // tex 命令とほぼ同じ。src1.w で LOD 指定

● おまけ
seq, sne
11.6 の新機能ではないんですが AGALMiniAssembler に追加されてました

----------------------------------------------------------------------------------

●命令数

リリースノートでは 1024 になると書いてありますが
AGALMiniAssembler では 2048 までは一応通すようです

LINE558 : private static const MAX_OPCODES:int = 2048;

----------------------------------------------------------------------------------

●MAX_NESTING

AGALMiniAssembler
LINE557 : private static const MAX_NESTING:int = 4;

フロー制御のネスト深さチェック用の定数だと思うんですが
定義されているだけで使われていませんでした。
ちょっと覚えておきます。

----------------------------------------------------------------------------------

●レジスタ数

大体どれも使える数が増えてます
中でも目を引くのは、
Output colors : 1 -> 4 // 描画先が 4 つに
Depth output : 0 -> 1 // 深度バッファ
でしょうか

----------------------------------------------------------------------------------
●AGALMiniAssembler.assemble()

引数が変わってます

vs = new AGALMiniAssembler();
vs.assemble(
Context3DProgramType.VERTEX // 前と同じ
, "m44 op, va0, vc0\n" + "mov v0, va1\n" // 前と同じ
, 2 // AGAL のバージョンを指定。BASELINE_EXTENDED の場合は 2
, false // デフォルト値の false で。レジスタの使用可能数のチェック関係です
);


AGALMiniAssembler.assemble2() が追加されてました
頂点シェーダーとピクセルシェーダーのソースをまとめて渡せて、内部で upload もしてくれる関数です。
使うかは好みで。

var agalminiassembler:AGALMiniAssembler = new AGALMiniAssembler();
pg = agalminiassembler.assemble2(
context3D
, 2
, "m44 op, va0, vc0\n" + "mov v0, va1\n"
, "mov oc v0\n"
);


////////////////////////////////////////////////////////////////////////////////////////////////////////////////

余談ですがこれで命令のバイトコードが 0x00-0x21, 0x26-0x2d まで埋まりました。
残りの 0x22 - 0x25 の 4 つの空きがちょっと気になります。
loop, endloop, rep, endrep 辺りでしょうか?

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

目玉の Multiple render targets や Fragment Program Depth Output はまだ試してないです



  1. 2012/12/25(火) 08:23:51|
  2. ActionScript
  3. | トラックバック:0
  4. | コメント:0

FlashDevelop で FlashPlayer 11.6 beta

FlashPlayer 11.6 を試したくなったので環境構築してました

akihiro kamijo
Flash Player の Stage3D の新しいプロファイル BASELINE_EXTENDED

http://cuaoar.jp/2012/12/flash-player-stage3d-bas.html#more
引用:BASELINE よりも機能を若干拡張したプロファイル BASELINE_EXTENDED が利用可能となっています。
こちらは標準プロファイルよりも高機能な 3D 表現を実現するものです


Adobe Flash Player 11.6 Beta
New features for browser-based, expressive content

http://labs.adobe.com/technologies/flashruntimes/flashplayer/

Folsom Prerelease Release Notes
Flash Player 11.6 and AIR 3.6 Release Notes

http://labsdownload.adobe.com/pub/labs/flashruntimes/shared/air3-6_flashplayer11-6_releasenotes.pdf
英語版のリリースノート。PDF です。

AGALMiniAssembler も新しくなってました
https://dl.dropbox.com/u/7009356/stage3d-extended-profile/AGALMiniAssembler.as


////////////////////////////////////////////////////////////////////////////////////////////////////////////////

まず FlashDevelop が 4.0.0RC だったので現時点での最新版 4.2.2RTM にバージョンアップしておきます
デフォルトインストールでSDKもおまかせします

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

11.6 beta のスタンドアローン版 Debug player と playerglobal.swc ダウンロードしてきます
http://labs.adobe.com/downloads/flashplayer.html
下のほうの
Flash Player 11.6 Beta Standalone Debuggers
Flash Player 11.6 Beta Global SWC

です

落としてきた flashplayer11-6_playerglobal.swc を playerglobal.swc にリネーム
"11.6" のフォルダを作って突っ込んでおきます。
C:\Program Files\FlashDevelop\Tools\flexsdk\frameworks\libs\player\11.6\playerglobal.swc

デバッグプレーヤーはどこに置いてててもいいんですが
気分的にこれも flexsdk の方に移動させておきます
"11.6\win\" フォルダを作って移動
C:\Program Files\FlashDevelop\Tools\flexlibs\runtimes\player\11.6\win\flashplayer11-6_debugsa_win_32.exe

FlashDevelop 起動
"ツール" -> "環境設定"
左の "FlashViewer" 選択
"External Player Path" にさっき落としたデバッグプレーヤーのパスを入れます
ここでは
C:\Program Files\FlashDevelop\Tools\flexlibs\runtimes\player\11.6\win\flashplayer11-6_debugsa_win_32.exe
11_6_000.jpg

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

プロジェクト作成

"プロジェクト" -> "新規プロジェクト"
"AS3 Project" 選択
適当な名前、ここでは "Test11_6_00"にしておきます
"OK"

11_6_010.jpg


書き出しタブ選択

"プロジェクト" -> "プロジェクト設定"
FlashPlayer のバージョンを "11.6" にしたいのですが
選択肢に現れないのでとりあえず "11.5" にしておきます

プロジェクトをテストを
"再生:外部プレーヤー" 選択

11_6_020.jpg


コンパイラー設定タブ選択

"Additional Compiler Option" に "-swf-version=19" 追加

11_6_030.jpg


ここで1回 FlashDevelop 終了します

今作ったプロジェクトフォルダの中の "--------.as3proj" を適当なエディタで開きます

11_6_040.jpg


12 行目を 5 -> 6 に書き換えます


11_6_050.jpg


保存して閉じます

FlashDevelop 起動してプレーヤーのバージョンを確認すると空白になってますが
ちゃんと 11.6 の playerglobal.swc を見に行ってくれています
この辺は自己責任なのでご理解の上試してください
// むしろスマートに設定する方法知っている方いたら教えてください

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1. 2012/12/25(火) 08:08:44|
  2. ActionScript
  3. | トラックバック:0
  4. | コメント:0

雑記

雑記

今年も後1週間になったので1年のまとめなぞを

////////////////////////////////////////////////////////////////////

●お絵かき

時間がまとまってありそうな期間は livetube で配信してました。
やっぱり配信お絵かきは楽しいですね。

夏ぐらいから数年ぶりにお仕事させていただいてました。
昔と同じ「藤処」の名前でやらせていただいてます。
―――――――――――――――――――――
タイトル:創神のアルテミス
Web紹介サイト:http://artemis.legolab.jp/
配信元 :GREE
メーカー:レゴラボ
ケータイゲームアドレス:http://mpf.gree.jp/57632
―――――――――――――――――――――
キャラ30体ぐらいと小物30枚ぐらい描かせていただきました

―――――――――――――――――――――
タイトル:ダーツ戦士ダーツライバー
サイト:http://dartsbar.dlgames.jp/pc.html
配信元:モバゲー、GREE
メーカー:ダーツライブゲームズ
―――――――――――――――――――――
キャラ3体ほど描かせていただきました

後はクレジットの出せないお仕事ちょこちょこやらせていただきました。
来年も宜しくお願いいたします。


////////////////////////////////////////////////////////////////////

●ActionScript

今年はやりたいことが色々あったはずなのに
現実の仕事とお絵かきにリソースを使ってて何もやらずに1年が終わりそうです

最近気になった記事

akihiro kamijo
Flash Player の Stage3D の新しいプロファイル BASELINE_EXTENDED

http://cuaoar.jp/2012/12/flash-player-stage3d-bas.html#more
引用:BASELINE よりも機能を若干拡張したプロファイル BASELINE_EXTENDED が利用可能となっています。
こちらは標準プロファイルよりも高機能な 3D 表現を実現するものです


まだベータですが AGAL がパワーアップするようです
自分のビデオカードは大昔のものなんで試せるのかちょっと不安です
(読んだ感じでは HLSL のバージョン 2_x 相当っぽいんで大丈夫だと思うんですが)

////////////////////////////////////////////////////////////////////

●POP-CAKE!

プラグインが最新バージョンで動かないのを直そうと思ってたまま1年過ぎました
このサイトにあるプラグインは 2.0.4 用です。

////////////////////////////////////////////////////////////////////

●天鳳

昔使ってて放置で消えちゃったID名が新しく取り直せたのでちょこちょこ打ってました
つい先日秋刀魚で七段戻れました。
調子に乗って鳳凰卓で打ってたらすっかり養分になってます

////////////////////////////////////////////////////////////////////

●マインスイーパー

念願だったMine2000のマニアモードクリアできました
数年やってました。幸せ
mine_mania.png

来年の目標は上級1分以内で

////////////////////////////////////////////////////////////////////

それではみなさま良いお年を。
  1. 2012/12/24(月) 20:39:41|
  2. 日記 diary
  3. | トラックバック:0
  4. | コメント:0

お絵かき ONEPIECE ナミさん

ここ最近は特に忙しかったわけでもないのに何にもしてませんでした。

2012年は最低月に一枚は絵を描こうと決めていたので
久しぶりのお絵かき更新です。でもエロエロじゃないです。

ONEPIECE nami bath
  1. 2012/02/03(金) 01:10:23|
  2. 絵 picture
  3. | トラックバック:0
  4. | コメント:2

ActionScript FXComposerHLSLASM To AGAL Prev

年末年始は PixelBender3D の代わりになるものを探してました。

条件として

・高級言語
・すぐに結果が確認できること

高級言語から直接 AGAL 吐けるツールは残念ながら見当たりませんでした。
なので HLSL や GLSL 周りを調べてみると

・FX Composer
・Render Monkey

の 2 つがすぐに候補として出てきたので、
このうち FX Composer 2.5 を使って HLSL のアセンブラコードの AGAL 変換を試してました。

お正月に HLSL のリファレンスとにらめっこして
ようやくサンプルのフォンシェーディングと、ベルベットを
FX Composer の出力したアセンブラに手を入れずそのまま変換できるようになりました。

まだこの 2 つしか試してないんで Version 0.3 ぐらいです。
・Sample の HLSL アセンブラ選択
・"Convert" で AGAL に変換
・"Compile" で AGAL を Bytecode に変換。同時にコメントのレジスタ情報パース
HLSL 貼らずにそのまま AGAL のコーディングも一応できます。

画像クリックでテスト FLASH 実行には FlashPlayer11 以上が必要ですadobe から FlashPlayer ダウンロード
FXComposer HLSL ASM To AGAL test

まだ問題山積みですが、少し UI いじったら FX Composer についても合わせて別記事書きたいです。

  1. 2012/01/07(土) 13:47:33|
  2. ActionScript
  3. | トラックバック:0
  4. | コメント:0

新年明けましておめでとうございます

ちょっと油断していたらあっという間に 7 日になってました。恐ろしい。

去年の反省をしつつ、今年の目標を。

-------------------------------------------------------------------------
・絵

去年の目標だった同人再開は駄目でした。今年こそ。

-------------------------------------------------------------------------
・ POP-CAKE! プラグイン

久しぶりのプログラムが楽しかったです。
ただ途中からプラグインを作ること自体が目的になっちゃって、
自分でも使いそうに無いもの作ってたのはあまり良く無かったです。
もし今年新バージョンが出たらまた触ってみたいです。
// 公式サイトを見たらインポート・エクスポートプラグインが出来てるらしいです。

-------------------------------------------------------------------------
・ ActionScript

去年終盤のメイン更新ネタでした。 ActionScript 楽しいです。

今年は Away3D メインで、 Proscenium がバージョンアップしたら平行して触っていく感じにしたいです。
Unity は始める前に試用期限来ちゃいそう。

-------------------------------------------------------------------------
・3D

Blender をいいかげん倒さなければ・・・

////////////////////////////////////////////////////////////////////////

なにはともあれ今年もよろしくお願いします。


  1. 2012/01/07(土) 13:39:59|
  2. 日記 diary
  3. | トラックバック:0
  4. | コメント:0

ActionScript Stage3D 頂点バッファの BYTE_4

vertexBuffer.uploadFromVector()
より
vertexBuffer.uploadFromByteArray()
の方が速いそうです。

自分は uploadFromByteArray() の存在自体知りませんでした・・・やだ、恥ずかしい。

////////////////////////////////////////////////////////////////////////

知ったのはこちら、

JacksonDunstanさん Stage3D Upload Speed Tester
http://jacksondunstan.com/articles/1617
Texture, VertexBuffer3D, IndexBuffer3D それぞれについて各種パターンでアップロード速度の比較を行っています。
"Try out the test" クリックでテストが出来ます。(ソースコードもあります)

上記サイトコメント欄で色々な方の結果が見れます

そして自分もテスト。 環境は CPU Intel Core2Duo 2.33 GPU ATI Radeon HD 2600 PRO です。
ドライバテスト種類掛かった時間   1 秒辺りのバイト数
DirectX9 (Direct blitting) Texture from BitmapData w/o alpha101677721.60
DirectX9 (Direct blitting) Texture from BitmapData w/ alpha131290555.08
DirectX9 (Direct blitting) Texture from ByteArray121398101.33
DirectX9 (Direct blitting) VertexBuffer from Vector151118464.00
DirectX9 (Direct blitting) VertexBuffer from ByteArray111525178.18
DirectX9 (Direct blitting) IndexBuffer from Vector12097148.00
DirectX9 (Direct blitting) IndexBuffer from ByteArray12097148.00
Software (Direct blitting) Texture from BitmapData w/o alpha161048576.00
Software (Direct blitting) Texture from BitmapData w/ alpha111525201.45
Software (Direct blitting) Texture from ByteArray161048576.00
Software (Direct blitting) VertexBuffer from Vector28599177.14
Software (Direct blitting) VertexBuffer from ByteArray101677696.00
Software (Direct blitting) IndexBuffer from Vector3699049.33
Software (Direct blitting) IndexBuffer from ByteArray12097148.00


特に VertexBuffer について知りたいので更に何度かテストして平均取ってみました。
(結構ブレ幅あります。特に Software )
結果は
DirectX9 ByteArrayの方が 約 26% 速い
Software ByteArrayの方が 約 45% 速い
となりました。

他の方の結果に比べたらちょっと地味ですが、それでもかなり速度差があります。
// Mac + OPENGL の速度差が凄い・・・

なので、頻繁に頂点バッファアップロードするなら ByteArray がいいようです。
// そこから更に頂点バッファをダブルバッファリングしてみたいです。
-----------------------------------------------------------------------------

追記:2011/12/28

記事前半部分について

頂点バッファを毎フレーム更新するとなると
結局 byte.writeFloat() の書込みコストがあるので
更新するのに uploadFromByteArray() を使うのは頂点数が増えるほど不利になりました。

// guest さんコメントありがとうございます。

テストするまでも無さそうですが一応簡単なコードで確認しておきました。
10000 頂点データの入ってる Vector. と ByteArray を用意
・Vector 全データ書き換えて uploadFromVector() 、これを n ループした経過時間
・ByteArray 全データ書き換えて( .writeFloat() )uploadFromByteArray()、これを n ループした経過時間
大体二倍の差になりました。

ついでに記事後半部分と合わせたまとめを最後に追記しておきました。

-----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////

vertexBuffer.uploadFromByteArray() 知らなかったことで
改めてリファレンス見直してたら他にも知らないことがありました。

Context3D setVertexBufferAt
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display3D/Context3D.html#setVertexBufferAt%28%29

setVertexBufferAt(index:int, buffer:VertexBuffer3D, bufferOffset:int = 0, format:String = "float4"):void
第三引数の format
引用:
position:
x float32
y float32
z float32
color:
r unsigned byte
g unsigned byte
b unsigned byte
a unsigned byte

color は rgba(32bit) で投げていいんですね。
というよりも何も考えずずっと Vector. の FLOAT_3 でやってました。

////////////////////////////////////////////////////////////////////////

ということで、vertexBuffer.uploadFromByteArray() と BYTES_4 試してみました。

シンプルに頂点情報は座標とカラーのみ
三角形が大きくひとつ描画されるだけで色は暗め。

// vertex
// v0 頂点座標
// v1 頂点カラー
// vc0 ローカル座標系からスクリーン座標系への変換行列
m44 op, va0, vc0
mov v0, va1

// fragment
mov oc v0

---------------------------------------------------------
TypeA

今までのパターンです。

座標も色も同じバッファで全情報 float
// vBuf_A[ v0[ float x, float y, float z] , v1[ float r, float g, float b] ][ ...
// 1 頂点辺り 32 * 6 = 192 bit

// 頂点バッファ生成
vBuf_A = context3D.createVertexBuffer( 3, 6 );
vBuf_A.uploadFromVector(
Vector.([
-1.0, -1.0, 0.0, 0.5, 0.0, 0.0 // x, y, z, r, g, b
, 0.0, 1.0, 0.0, 0.0, 0.5, 0.0
, 1.0, -1.0, 0.0, 0.0, 0.0, 0.5
])
, 0
, 3
);

// set v0, v1
context3D.setVertexBufferAt( 0, vBuf_A, 0, Context3DVertexBufferFormat.FLOAT_3 );
context3D.setVertexBufferAt( 1, vBuf_A, 3, Context3DVertexBufferFormat.FLOAT_3 );

普通です。

---------------------------------------------------------
TypeB

次に、BYTE_4 型使ってみます
まずは楽なのでバッファを座標と色で分けたパターン
// vBuf_B_pos[ v0[ float x, float y, float z] ][ ...
// vBuf_B_col[ v1[ uByte r, uByte g, uByte b, uByte a ] ][ ...
// 1 頂点辺り 32 * 3 + 8 * 4 = 128 bit

// 頂点バッファ(座標情報)生成
vBuf_B_pos = context3D.createVertexBuffer( 3, 3 );
vBuf_B_pos.uploadFromVector(
Vector.([
-1.0, -1.0, 0.0 // x, y, z
, 0.0, 1.0, 0.0
, 1.0, -1.0, 0.0
])
, 0
, 3
);
// 頂点バッファ(色情報)生成
vBuf_B_col = context3D.createVertexBuffer( 3, 1 );
bytes = new ByteArray();
bytes.endian = Endian.LITTLE_ENDIAN;
bytes.length = 4 * 3; // r,g,b,a * 3vertex
bytes[ 0 ] = 128; bytes[ 1 ] = 0; bytes[ 2 ] = 0; bytes[ 3 ] = 255;
bytes[ 4 ] = 0; bytes[ 5 ] = 128; bytes[ 6 ] = 0; bytes[ 7 ] = 255;
bytes[ 8 ] = 0; bytes[ 9 ] = 0; bytes[ 10 ] = 128; bytes[ 11 ] = 255;
bytes.position = 0;
vBuf_B_col.uploadFromByteArray( bytes, 0, 0, 3 );

// set v0, v1
context3D.setVertexBufferAt( 0, vBuf_B_pos, 0, Context3DVertexBufferFormat.FLOAT_3 );
context3D.setVertexBufferAt( 1, vBuf_B_col, 0, Context3DVertexBufferFormat.BYTES_4 );

表示結果は TypeA と同じでした。(変わったら困るんですが)

Context3DVertexBufferFormat.BYTES_4 はシェーダ内で取得される時
0 -> 255 が 0.0 -> 1.0 にちゃんとマッピングされてますね。

ただ、頂点バッファを属性ごとに分けることによって
GPU 上で読み取り先が分散されてパフォーマンスが落ちる気がします。

// ByteArray の話とは関係ないんですが
// 例えば、動作を CPU で計算するパーティクルや物理演算の時とかに
// 頂点バッファを更新する部分(例えば座標)と更新されない部分に分けて
// 更新部だけアップロードする方が有利とか無いでしょうか。
// つまり、アップロード時に減るコストと読み取り先分散で増えるコストの比較。

---------------------------------------------------------
TypeC

座標も色も同じバッファ、RGB は unsigned byte
// vBuf_C[ v0[ float x, float y, float z] , v1[ uByte r, uByte g, uByte b, uByte a ] ][ ...
// 1 頂点辺り 32 * 3 + 8 * 4 = 128 bit

// 頂点バッファ生成
vBuf_C = context3D.createVertexBuffer( 3, 4 );
bytes = new ByteArray();
bytes.endian = Endian.LITTLE_ENDIAN;
bytes.writeFloat( -1.0 ); bytes.writeFloat( -1.0 ); bytes.writeFloat( 1.0 );
bytes.writeByte( 128 ); bytes.writeByte( 0 ); bytes.writeByte( 0 ); bytes.writeByte( 255 );
bytes.writeFloat( 0.0 ); bytes.writeFloat( 1.0 ); bytes.writeFloat( 0.0 );
bytes.writeByte( 0 ); bytes.writeByte( 128 ); bytes.writeByte( 0 ); bytes.writeByte( 255 );
bytes.writeFloat( 1.0 ); bytes.writeFloat( -1.0 ); bytes.writeFloat( 0.0 );
bytes.writeByte( 0 ); bytes.writeByte( 0 ); bytes.writeByte( 128 ); bytes.writeByte( 255 );
bytes.position = 0;
vBuf_C.uploadFromByteArray( bytes, 0, 0, 3 );

// set v0, v1
context3D.setVertexBufferAt( 0, vBuf_C, 0, Context3DVertexBufferFormat.FLOAT_3 );
context3D.setVertexBufferAt( 1, vBuf_C, 3, Context3DVertexBufferFormat.BYTES_4 );

これも表示結果は TypeA と同じでした。大丈夫そうです。

////////////////////////////////////////////////////////////////////////

TypeA/B/C でのパフォーマンステスト

パフォーマンス差は頂点シェーダーでの
・1 頂点辺りのデータサイズ
・読み取り先バッファの数
・0-255 -> 0.0-1.0
なので

フラグメントシェーダーには全く仕事させないように描画サイズは極小さく。
// 見えないですが scale( 0.001 ) 倍に縮小してあります
Z バッファの負荷も無くすため。false, ALWAYS
1 BUFFER に 10000 三角ポリゴン入れときます。
これを描画時に n 回 drawTriangles() して
10000 * n 三角ポリゴン分の仕事をバーテックスシェーダーにしてもらいます。

-----------------------------------------------------------------------------

テストフラッシュ(Wonderful)
http://wonderfl.net/c/1XOr

・ラジオボタンで Type 切替
・スライダーで描画する三角ポリゴン数増減
適当にスライダーをいじって頂点シェーダーの負荷上げてください。
FPS が 60 をある程度下回ったら、Type を変更して差を確認してください。

-----------------------------------------------------------------------------

自分の結果はドライバーが DirectX で、

C > A > B

でした。

C と A の違いは 1 頂点辺りのデータサイズで、当然小さい C の方が速いですね。
データサイズの小さい B が A に負けてるので、読取先バッファ数が多い事の方が不利のようです。

ただ、やはりフラグメントシェーダーの負荷に比べて頂点シェーダーの負荷は恐ろしく低いです。
少し三角形を大きくするだけでも A/B/C の違いは誤差にしかなりませんでした。
(どれもほぼ同じ FPS になります)

なので、 BYTE_4 使うメリットはパフォーマンス的にはあまり無く、
バッファサイズ使用量を少し抑えられる程度という気がします。
-----------------------------------------------------------------------------

追記:2011/12/28

まとめ

BYTE_4 も uploadFromByteArray() はあまり使い道が無さそうです。

頻繁にアップロードしない(初期化時の一度程度とか)バッファで BYTE_4 混在でデータサイズを小さくした方が
頂点シェーダーのパフォーマンスは上がりますが、非現実的な頂点数で差が確認できる程度です。
// フラグメントシェーダーのテクスチャでも小さくする方がずっと効果が高いです。
やるとしたら最後の最後ぐらいでしょうか。(最後でもやらないかな・・・)

-----------------------------------------------------------------------------
  1. 2011/12/28(水) 03:37:03|
  2. ActionScript
  3. | トラックバック:0
  4. | コメント:4
次のページ

検索フォーム

プロフィール

Author:藤丸
色々と描いたり、分かったことを覚書しておくサイトです

カテゴリ

絵 picture (14)
ActionScript (35)
POP-CAKE! (10)
3D (2)
麻雀 mahjhong (2)
マインスイーパー minesweeper (1)
未分類 (0)
日記 diary (2)
その他 other (0)

タグ

ActionScript 
Proscenium 
 
POP-CAKE! 
livetube 
天鳳 
プログラミング 
Away3D 
マインスイーパー 
3D 
sculptris 

リンク

このブログをリンクに追加する

最新コメント

最新トラックバック

RSSリンクの表示

ブロとも申請フォーム

この人とブロともになる

QRコード

QR

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。