<?xml version="1.0" encoding="UTF-8"?><!-- generator="WordPress/2.6" -->
<rss version="0.92">
<channel>
	<title>39</title>
	<link>http://www4.atword.jp/cathy39</link>
	<description>About 3D graphics programming</description>
	<lastBuildDate>Sat, 11 Dec 2010 16:38:43 +0000</lastBuildDate>
	<docs>http://backend.userland.com/rss092</docs>
	<language>en</language>
	
	<item>
		<title>memo : Gatherがサンプリングする位置</title>
		<description>GatherはDirectX10.1から使える機能の１つで４サンプルを１度にとってこられるものです。
Gatherを使うと4つのピクセルのRGBを３命令でとってくることができます。

今までは
Sample( sampler, uv )
Sample( sampler, uv + offset0 )
Sample( sampler, uv + offset1 )
Sample( sampler, uv + offset2 )
とやっていたのが
GatherRed( sampler, uv );
GatherGreen( sampler, uv );
GatherBlue( sampler, uv );
で取れるということです。

が、いざ使ってみようと思ったら、
Gatherに指定するuvとフェッチされるサンプルの位置についての記述が見当たりません。
どこに書いてあるんですか？？

仕方ないので調べてみる。
まず普通にテクスチャを描画。

テクスチャは16x16です。(ポイントフィルタで描画)

次に、Gatherでサンプリングした結果を復元して描画

Rチャンネル
uvが0.5ずつ左下にずれている

Gチャンネル
uvが0.5ずつ右下にずれている

Bチャンネル
uvが0.5ずつ右上にずれている

Aチャンネル
uvが0.5ずつ左上にずれている


ということで、
- Gatherに指定するuv → 中心
- Gatherでサンプリングする位置 → 中心±0.5テクセルの位置

Gatherに指定するuvをPとすると、
RGBA各チャンネルのサンプリングポイントは以下の図のようになる


まあ予想通りというか普通な結果ですが、
指定したuvはサンプリングされないということです。
それと、Gatherを使う場合はリニアフィルタが利かないです。 </description>
		<link>http://www4.atword.jp/cathy39/2010/05/19/gather_jp/</link>
			</item>
	<item>
		<title>Linked Listを利用したOIT - 4</title>
		<description>[前回のつづき]

今回は２パス目、フラグメントのソートと描画パスの実装についての解説です。


3. ソートと描画パスの実装

このパスではピクセルごとにLinked Listをたどって全てのフラグメントデータを取り出し、深度値でソートして奥のフラグメントから順にブレンディング、結果をフレームバッファに出力します。

3-a. シェーダの実装

新しいhlslファイルを作成します。今回はピクセルシェーダだけでなくフルスクリーンを描画するための頂点シェーダも必要です。
ピクセルシェーダでは全てのフラグメントデータをテンポラリ配列に一度コピーし、それから深度値でソートします。これはメモリアクセスを抑えるためです。



StructuredBuffer&#60;SFragmentLink&#62; FragmentLinkSRV : register(t0);
Buffer StartOffsetSRV : register(t1);

struct QuadVS_Output
{
&#160;&#160;&#160;&#160;float4 pos   : SV_POSITION;
};


float4 SortFragmentsPS( QuadVS_Output _input ) : SV_Target0
{
&#160;&#160;&#160;&#160;uint uIndex = (uint)_input.pos.y * g_nFrameWidth + (uint)_input.pos.x;

&#160;&#160;&#160;&#160;// Read and store linked list data to the tempolary buffer.
&#160;&#160;&#160;&#160;SFragment aData[32];
&#160;&#160;&#160;&#160;int anIndex[32];
&#160;&#160;&#160;&#160;uint uNumFragment = 0;&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;uint uNext = StartOffsetSRV[uIndex];
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;while ( uNext != ...</description>
		<link>http://www4.atword.jp/cathy39/2010/05/08/linked-list-oit-japanese-4/</link>
			</item>
	<item>
		<title>Linked Listを利用したOIT - 3</title>
		<description>[前回のつづき]


今回はLinked List OITの1パスめ、Linked Listの作成パスの実装について解説します。


2.Linked Listの作成パスの実装

OIT11サンプルでは３つのバッファと１つの２Dテクスチャを利用していますが、Linked List OITでは２つのバッファを使用します。

・Fragment Link バッファ
全てのフラグメントデータを格納するためのStructured バッファ。
各フラグメントデータはカラー、深度値に加えて次のフラグメントデータのインデックスを持っています。次のフラグメントデータがない場合、リストの終わりを示す特定の値を格納することになります。今回の実装では0xffffffffを使います。
ピクセルシェーダにおけるフラグメントデータの宣言は以下のようになります。カラーはuintにパックしています。


struct SFragment {
&#160;&#160;&#160;&#160;uint  uColor;
&#160;&#160;&#160;&#160;float fDepth;
};

struct SFragmentLink {
&#160;&#160;&#160;&#160;SFragment fragment;
&#160;&#160;&#160;&#160;uint      uNext;
};



・Start Offset バッファ
各ピクセルにおけるリストの先頭を指すuintバッファ。毎フレーム描画の前に0xffffffffで初期化されます。


Linked Listの作成パスでは、追加するフラグメントデータをリストの先頭として挿入していきます。つまり、追加されるフラグメントデータが指す次のインデックスにはStart Offsetバッファに含まれていた値を入れ、Start Offset バッファには追加されたフラグメントデータのインデックスを入れます。この部分はスライドのアニメーション"Linked List Creation(2a)~(2d)"を見ると非常にわかりやすいと思います。　


2-a. Linked List作成シェーダの実装

Constant Bufferがそのまま使えるので、Linked Listの作成パスはOIT_PS.hlslを改造して実装することにします。Fragment Link バッファとStart Offsetは以下のように宣言します。両方とも書き込みが必要なのでRW…がつきます。


// Fragment And Link Buffer
RWStructuredBuffer FLBuffer&#60;SFragmentLink&#62; : register( u0 );
// Start Offset ...</description>
		<link>http://www4.atword.jp/cathy39/2010/05/07/linked-list-oit-japanese-3/</link>
			</item>
	<item>
		<title>Linked Listを利用したOIT - 2</title>
		<description>[前回の続き]

今回からはOIT11をどのように改造してLinked List OITを実装するのかを説明していきます。
説明が足りないところは前述のスライドやOIT11サンプルを参照していただけるとわかると思います。特にスライドはアニメーションがあったりするので英語が読めなくてもなんとなくわかります。また、スライドにはシェーダコードも記載されています。実装は非常に簡単なのでスライドが読めればできたも同然です。


1.　描画フローの変更

通常の半透明プリミティブの描画フローでは、
半透明プリミティブの描画時にZテストをパスしたらアルファブレンドしてフレームバッファを更新
という流れですが、
OITではプリミティブの描画時にはZテストは行わず、フレームバッファも更新しません。その代わり、全ての半透明のフラグメントデータを別の大きなバッファに格納します。フラグメントデータは、最低でも深度値とカラーを持ち、スクリーン上のどこかのピクセルに属しています。半透明ポリゴンが重なるところでは、１つのピクセルに複数のフラグメントデータが存在する状態になります。
半透明の描画終了後、各ピクセルごとにフラグメントデータを深度値でソートしてブレンディングを行い、結果のカラーをフレームバッファに描きこみます。

この「別の大きなバッファに格納する」方法がDirectXのOIT11サンプルとLinked List版とで異なります。

OIT11サンプルではフラグメントデータを各ピクセルごとに順番につめていきます。
つまり、スクリーンの左上から
０番目のピクセルに描画されるフラグメントデータ1,2,3…
１番目のピクセルに描画されるフラグメントデータ1,2,…
というようにピクセル順に複数のフラグメントデータをバッファに格納します。

このため、フラグメントデータを保存する前に、あらかじめ各ピクセルに描画されるフラグメントデータの数や、各ピクセルの格納先インデックスがわかっていなければなりません。
OIT::Render関数を見てみると全体の流れがわかります。

// Create a count of the number of fragments at each pixel location
// １．各ピクセルに描画されるフラグメントデータの数を数える
CreateFragmentCount( pD3DContext, pScene, mWorldViewProjection, pRTV, pDSV );

// Create a prefix sum of the fragment counts.  Each pixel location will hold
// a count of the total number of fragments of every preceding pixel location.
// ...</description>
		<link>http://www4.atword.jp/cathy39/2010/05/06/linked-list-oit-japanese-2/</link>
			</item>
	<item>
		<title>Linked Listを利用したOIT</title>
		<description>GDC　2010にてLinked List を利用したOrder Independent Transparency の紹介がありました。

スライドはこちら。
GDC 2010: OIT and GI using DX11 linked lists (Nick Thibieroz &#38; Holger Grün)
http://developer.amd.com/documentation/presentations/Pages/default.aspx

Order Independent Transparency (以後OIT)というのは、半透明の描画順ソートを行う技術です。通常のZテストとアルファブレンディングで描画順のソートを完全に正しく行うのには限界があり、実質不可能です。たとえばポリゴンが他のポリゴンに突き抜けている場合などはかなり無理です。しかし、OITを利用すればそのような状態でも正しく半透明ポリゴンを重ねて描画することができます。

DirectX SDKサンプルにもOIT11というサンプルがあり、ポリゴンが突き抜けているような状態でも正しくブレンドすることができています。しかし残念ながら非常に重くて使い物になりません。一方、同じOITを行うATI のRadeon™ HD 5000 シリーズの「Mecha」デモはOIT11に比べてはるかに複雑なシーンなのにわりとさくさく動いています。GDCで紹介されたOITの技術はMechaデモで使用しているものと同じ、とういことで、OIT11サンプルを改造してLinked Listを実装し、速度を比較してみることにしました。


実装結果

オリジナルのOIT11サンプルはRADEON HD5800上で11.3fpsで動いています。



Linked List　OITを実装後、fpsは1800まであがりました。
実に約160倍です。DirectXのサンプルはあまり参考にしないほうがいいですね…



実装方法はおいおい投稿していきます。

[つづく] </description>
		<link>http://www4.atword.jp/cathy39/2010/05/04/linked-list-oit-japanese-1/</link>
			</item>
	<item>
		<title>OIT using Linked Lists - 4</title>
		<description>[Previous post]


3. Implement Sorting and rendering pass

In the second pass, all fragments in the linked list at each pixel are sorted by depth value, then the color is blended in order of depth.

3-a. Implement shaders.

Create new hlsl files for the sorting and rendering pass. In the pixel shader, copy all ...</description>
		<link>http://www4.atword.jp/cathy39/2010/05/04/linked-list-oit-4/</link>
			</item>
	<item>
		<title>OIT using Linked Lists - 3</title>
		<description>[Previous post]


2. Implement Linked List Creation


The OIT11 uses one 2D Texture and three buffers. Linked List OIT requires two buffers, one is a structured buffer which is called "Fragment Link Buffer". The other is a uint buffer which is called "Start Offset Buffer".

- Fragment Link Buffer
contains all fragments. Each fragment ...</description>
		<link>http://www4.atword.jp/cathy39/2010/05/04/linked-list-oit-3/</link>
			</item>
	<item>
		<title>OIT using Linked Lists - 2</title>
		<description>[Previous post]

I show my implementation here. Refer to the slide and OIT11 sample code for details of each technique.　The slide is very useful to understand how linked lists works and it also contains code. You can implement easily after you read the slide.


1. Modify Rendering Flow

In usual rendering, pixels which ...</description>
		<link>http://www4.atword.jp/cathy39/2010/04/29/linked-list-oit-2/</link>
			</item>
	<item>
		<title>OIT using Linked Lists</title>
		<description>There was a presentation about Order Independent Transparency using Linked Lists at GDC2010.

GDC 2010: OIT and GI using DX11 linked lists (Nick Thibieroz &#38; Holger Grün)
You can download the slide here.
http://developer.amd.com/documentation/presentations/Pages/default.aspx


I noticed the DirectX OIT11 sample was too slow but Mecha Demo for ATI Radeon™ HD 5000 Series seemed to ...</description>
		<link>http://www4.atword.jp/cathy39/2010/04/21/linkedlistoit1/</link>
			</item>
</channel>
</rss>

