<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>unbland.org blog &#187; Pixel Bender</title>
	<atom:link href="http://unbland.org/blog/tag/pixel-bender/feed" rel="self" type="application/rss+xml" />
	<link>http://unbland.org/blog</link>
	<description>発見の日々の備忘録。主に Web にまつまる技術ネタ。</description>
	<lastBuildDate>Wed, 18 Nov 2009 03:31:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>[Flash Player 10 #7]  シェーダ (Pixel Bender) を使った頂点計算の最適化 2</title>
		<link>http://unbland.org/blog/2008/05/29/27.html</link>
		<comments>http://unbland.org/blog/2008/05/29/27.html#comments</comments>
		<pubDate>Thu, 29 May 2008 11:27:57 +0000</pubDate>
		<dc:creator>muta244@admin</dc:creator>
				<category><![CDATA[Flash (ActionScript)]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flash Player 10]]></category>
		<category><![CDATA[Pixel Bender]]></category>

		<guid isPermaLink="false">http://unbland.net/blog/archives/2008/05/flash-player-10-7-%e3%82%b7%e3%82%a7%e3%83%bc%e3%83%80%ef%bc%88pixel-bender%ef%bc%89%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%9f%e9%a0%82%e7%82%b9%e6%83%85%e5%a0%b1%e3%81%ae%e8%a8%88%e7%ae%97%e3%81%ae.html</guid>
		<description><![CDATA[前回のエントリーでは複雑なことをしてシェーダにデータを渡そうとしていましたが、Saqoosha さんからコメント欄で教えていただいた boostworthyisryantaylor というサイトの情報（ShaderJob [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.unbland.net/blog/archives/2008/05/flash-player-10-5-pixel-bender.html">前回のエントリー</a>では複雑なことをしてシェーダにデータを渡そうとしていましたが、<a href="http://saqoosha.net/" target="_blank">Saqoosha さん</a>からコメント欄で教えていただいた <a href="http://www.boostworthy.com/blog/?p=243" target="_blank">boostworthyisryantaylor</a> というサイトの情報（ShaderJob クラスなど）を元に、シェーダでの頂点情報の計算に成功しました。</p>
<p><strong>フレームレートが 20 を切る分割数を計測（Z ソートは今回無し）</strong></p>
<p>従来の通りの頂点計算 =&gt; 分割数 75、頂点数 5625<br />
シェーダを使った頂点計算 =&gt; 分割数 80、頂点数 6400</p>
<p>こんな感じで、望んでいたような劇的な変化はありませんでした。自分の環境は普通の MacBook ですので GPU は搭載されていませんが、GPU がある環境では wmode を gpu とかにすれば結果は変わってくるんでしょう。試してないですが。</p>
<p>・<a rel="shadowbox[Mixed];width=320;height=320" href="http://unbland.net/blog/wp-content/uploads/2008/10/demo_internal.swf">従来の通りの頂点計算デモはこちら</a><br />
・<a rel="shadowbox[Mixed];width=320;height=320" href="http://unbland.net/blog/wp-content/uploads/2008/10/demo_shader.swf">シェーダを使った頂点計算デモはこちら</a></p>
<p>※ 要 Flash Player 10<br />
※ 左右キーで分割数、上下キーで視野角を変更できます。</p>
<p><a href="http://www.boostworthy.com/blog/?p=243" target="_blank">boostworthyisryantaylor</a> さんでも書かれているように、現在はバグなのか、ShaderInput に　Vector.&lt;number&gt; を渡すとエラーになるので ByteArray で渡しています（ドキュメントでは渡せると書いてあります）。この問題が直れば幾分は良くなるでしょうが、あまり期待はできないのかも。引き続き、調査は続けていくつもりです。とりあえずは Vector.&lt;number&gt; が渡せるようになるのを待つつもりですが。</p>
<p>http://www.libspark.org/svn/as3/Astro/VertexShader_01/</p>
<p>に今回のコードを上げましたので必要な方はチェックアウトしてください。</p>
]]></content:encoded>
			<wfw:commentRss>http://unbland.org/blog/2008/05/29/27.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>[Flash Player 10 #6]  シェーダ (Pixel Bender) を使った頂点計算の最適化 1</title>
		<link>http://unbland.org/blog/2008/05/28/26.html</link>
		<comments>http://unbland.org/blog/2008/05/28/26.html#comments</comments>
		<pubDate>Wed, 28 May 2008 01:17:59 +0000</pubDate>
		<dc:creator>muta244@admin</dc:creator>
				<category><![CDATA[Flash (ActionScript)]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flash Player 10]]></category>
		<category><![CDATA[Pixel Bender]]></category>

		<guid isPermaLink="false">http://unbland.net/blog/archives/2008/05/flash-player-10-6-%e3%82%b7%e3%82%a7%e3%83%bc%e3%83%80%ef%bc%88pixel-bender%ef%bc%89%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%9f%e9%a0%82%e7%82%b9%e6%83%85%e5%a0%b1%e3%81%ae%e8%a8%88%e7%ae%97%e3%81%ae.html</guid>
		<description><![CDATA[3D でボトルネックになるのは描画と頂点情報の計算などです。描画については drawTriangles という便利なメソッドがあるのでまだ良いとして、頂点情報については for で回して計算するのが常套手段ですが、最近は [...]]]></description>
			<content:encoded><![CDATA[<p>3D でボトルネックになるのは描画と頂点情報の計算などです。描画については drawTriangles という便利なメソッドがあるのでまだ良いとして、頂点情報については for で回して計算するのが常套手段ですが、最近はシェーダ（Pixel Bender）を使っての最適化に挑戦しています。</p>
<p><strong>&#8216;08 5.29 追記：</strong><br />
<a href="http://saqoosha.net/" target="_blank">Saqoosha さん</a>からコメント欄で頂いた情報を元に<a href="http://www.unbland.net/blog/archives/2008/05/flash-player-10-7-pixel-bender.html">新しいエントリー</a>を投稿しました。このエントリーでしているような複雑なことをしなくても、シェーダにデータを渡せますのでそちらを参照ください。<br />
&#8212;&#8211;</p>
<p>そのためにまず必要になるのが、どのようにシェーダ側にデータを渡すかというところ。シーンの行列などはパラメータで渡せるのですが、頂点の情報量は不定のためパラメータとしては渡せません（そもそも、シェーダは Flash 用に書き出す設定では配列に対応していませんし）。ですので、ピクセルに頂点座標を埋め込もうとしたのですが、これも中々うまくいかず、現状はここで止まってます。</p>
<p>流れを追って説明すると以下のような感じ。</p>
<p><strong>1. Flash 側 − ビットマップに頂点情報を埋め込む。</strong></p>
<p>浮動小数点数な頂点情報を、ビットマップに 15.15 形式の固定小数点数な uint（32 bit） として埋め込む。（ビットマップに書き込む際にアルファ値が 0 だと他の色情報まで 0 になってしまうため、32 bit 目は 1 で固定。また、31 bit 目は正負を表すために 15.15 形式）</p>
<p>例えば {x:100, y:0, z:0} の頂点一つのデータを埋め込むコードは以下。</p>
<div style="position:relative;top:18px;margin-top:-18px;"><small><strong>ActionScript</strong></small>
</div>
<pre name="code" class="actionscript" style="margin:18px 0;">
var vector:Vector. = Vector.([
    // 100 &amp;lt;&amp;lt; 15 | 0x80000000 でも良い。
    // ただ、ビット演算は計算によってはオーバーフローを起こすので注意。
    // ちなみに 0x80000000 は 32 bit 目を 1 にするため。
    100 * 0x8000 + 0x80000000, 0, 0
]);
var data:BitmapData = new BitmapData(3, vector.length / 3);
data.setVector(data.rect, vector);
</pre>
<p><strong>2. シェーダ側 − ピクセルから頂点情報を抜き出す。</strong></p>
<p>シェーダ側でピクセルをサンプリングすると float4（a, r, g, b） の形になるので、これをもう一度固定小数点数に戻す。ただし、Pixel Bender の int 型は 16 bit なので float 型で取り扱う。</p>
<p>コードは以下。</p>
<div style="position:relative;top:18px;margin-top:-18px;"><small><strong>ActionScript</strong></small>
</div>
<pre name="code" class="actionscript" style="margin:18px 0;">
// BIT_24　は 16777216.0、BIT_16 は 65536.0、BIT_08 は 256.0 をそれぞれ定数化したもの
pixel4 tmp = sampleNearest(src, outCoord());
float n = floor(tmp.a * 255.0) * BIT_24
        + floor(tmp.r * 255.0) * BIT_16
        + floor(tmp.g * 255.0) * BIT_08
        + floor(tmp.b * 255.0);
</pre>
<p><strong>3. シェーダ側 − 頂点情報を計算。</strong></p>
<p>パラメータで受け取った行列などを元に、頂点情報を計算する。ここは実際には試していないが、大した問題ではないはず。</p>
<p><strong>4. シェーダ側 − ピクセルに埋め込むために各色情報を分解。</strong></p>
<p>Pixel Bender はビット演算が行えないため、乗算・除算を使って分解します。</p>
<p>コードは以下。</p>
<div style="position:relative;top:18px;margin-top:-18px;"><small><strong>ActionScript</strong></small>
</div>
<pre name="code" class="actionscript" style="margin:18px 0;">
float a = floor(n / BIT_24);
float r = floor(n / BIT_16) - (a * BIT_08);
float g = floor(n / BIT_08) - (a * BIT_16 + r * BIT_08);
float b = floor(n         ) - (a * BIT_24 + r * BIT_16 + g * BIT_08);
</pre>
<p>いま、つまづいているのがまさにここ。例えば、n が 4294770688.0（{a:255, r:253, g:0, b:0}）の時は誤差が生じて r 成分が 254 になってしまいます。試しに、ActionScript で同様のコードを実行しても誤差は生じず・・・。</p>
<p>同様のコード。</p>
<div style="position:relative;top:18px;margin-top:-18px;"><small><strong>ActionScript</strong></small>
</div>
<pre name="code" class="actionscript" style="margin:18px 0;">
var BIT_24:Number = 16777216.0;
var BIT_16:Number = 65536.0;
var BIT_08:Number = 256.0;

var BYTE:Number = 255.0;

var dst:Object = {a:255/255, r:253/255, g:0/255, b:0/255};

var n:Number = Math.floor(dst.a * BYTE) * BIT_24
             + Math.floor(dst.r * BYTE) * BIT_16
             + Math.floor(dst.g * BYTE) * BIT_08
             + Math.floor(dst.b * BYTE);

trace(n); // 出力 =&amp;gt; 4294770688

var a:Number = Math.floor(n / BIT_24);
var r:Number = Math.floor(n / BIT_16) - (a * BIT_08);
var g:Number = Math.floor(n / BIT_08) - (a * BIT_16 + r * BIT_08);
var b:Number = Math.floor(n         ) - (a * BIT_24 + r * BIT_16 + g * BIT_08);

trace(dst.a, dst.r, dst.g, dst.b); // 出力 =&amp;gt; 1 0.9921568627450981 0 0
trace(aa / BYTE, rr / BYTE, gg / BYTE, bb / BYTE); // 出力 =&amp;gt; 1 0.9921568627450981 0 0
</pre>
<p>色々とデバッグ（Pixel Bender はデバック面倒過ぎ！）して分かったことは、除算を行うと何故か誤差が生じてしまい、うまく分解できていないということ。内部の計算に使用できる bit 数が異なるために起こる誤差なのか、何なのか・・・。誰か助けていただけませんか。</p>
]]></content:encoded>
			<wfw:commentRss>http://unbland.org/blog/2008/05/28/26.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.439 seconds -->
