OIT using Linked Lists - 2

 カテゴリー: OIT — Kaori @ 4 月 29th, 2010

[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 pass depth test are drawn to a frame buffer directly. In OIT, transparent primitives are not rendered to the frame buffer directly. Instead, all fragments are stored to a large buffer. Each fragment has a color and depth value and belongs to a pixel in the screen. There are multiple fragments per pixel where multiple transparent polygons overlaps. After rendering all transparent primitives, all fragments at a pixel are sorted by its depth and then the blended color is drawn to the frame buffer.


The OIT11 sample stores the fragments to a large buffer in order of pixel address.
For instance, the fragments are stored as follows.
Fragment 1, 2, 3, .... of the pixel[0]
Fragment 1, 2, ... of the pixel[1]

To store fragments like this, before storing fragments, it is necessary to know how many fragments each pixel has and where the fragment should be stored in the large buffer.
The OIT11 sample has 4 phases. You can see the entire phases in 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.
CreatePrefixSum( pD3DContext );

// Fill in the deep frame buffer with depth and color values. Use the prefix
// sum to determine where in the deep buffer to place the current fragment.
FillDeepBuffer( pD3DContext, pRTV, pDSV, pScene, mWorldViewProjection );

// Sort and render the fragments. Use the prefix sum to determine where the
// fragments for each pixel reside.
SortAndRenderFragments( pD3DContext, pDevice, pRTV );

The first and third phases are implemented by pixel shaders and the others by compute shaders.

On the other hand, Linked List OIT stores fragments in order of being drawn. So it requires only 2 passes. Instead of count the number of fragments, it stores fragments as linked lists. All fragments which belong to a certain pixel are in a linked list.
OIT::Render can be rewritten as follows:

// Linked List creation.
CreateFragmentLink( pD3DContext, pRTV, pDSV, pScene, mWorldViewProjection );

// Sort and render the fragments.
SortAndRenderFragments( pD3DContext, pDevice, pRTV );

Both passes are implemented by a pixel shader. The primitives are drawn in the first pass and the second pass is performed by rendering a screen quad.
Linked List OIT does not use Compute shader.


[To be continued...]


 OIT using Linked Lists

 カテゴリー: OIT — Kaori @ 4 月 21st, 2010

There was a presentation about Order Independent Transparency using Linked Lists at GDC2010.

GDC 2010: OIT and GI using DX11 linked lists (Nick Thibieroz & 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 be fast.
So I tried to modify the DirectX sample and implement linked lists instead.


Result

The original OIT11 runs at 11.3 fps on RADEON HD 5800.


After modification, it increase to around 1800 fps.
Linked list OIT is 160x faster!




I will post my implementation soon.




[To be continued...]

ホットワード カテゴリー After quad コメント Pages
割引クーポンまとめ情報 - クー割