A-Buffer Pass finished!


After days of debugging and testing i finally finished implementing the A-Buffer pass!
Here’s an image of the coverage computing done in the A-Buffer pass:


I just have to implement the storing of the coverage data as “per-pixel” linked list, like it’s done in AMD’s sample.
After that i can finally start implementing the last pass of the rendering shader which computes the Kajiya-Kay lighting and the order independent transparency (A-Buffer sorting).

I will keep this blog updated about any news from tressfx in unity ūüôā

TressFX’s A-Buffer Pass


I’ve started experimenting with unity’s rendering abilities.
In the TressFX sample the DirectX 11 function DrawIndexedInstanced and DrawIndexed will get used to draw the hair geometry.
There is no support for this functions in Unity, or atleast i didn’t found them in the API reference.

This is the rendering function in the TressFX sample to render the hair geometry.
It can render line or triangle primitives and also with / without anti-aliasing:

void CTressFXRender::RenderHairGeometry( ID3D11DeviceContext* pd3dContext,
                                ID3D11VertexShader* pVS, 
                                ID3D11PixelShader* pPS,
                                float density,
                                bool useLinePrimitives /*= true*/,
								int	iStrandCopies /*= 1*/) 

	pd3dContext->VSSetShader( pVS, NULL, 0 );
    pd3dContext->PSSetShader( pPS, NULL, 0 );

    pd3dContext->PSSetShaderResources(IDSRV_NOISEMAP, 1, &m_pNoiseSRV);
	pd3dContext->VSSetShaderResources(IDSRV_NOISEMAP, 1, &m_pNoiseSRV);
	pd3dContext->VSSetShaderResources( IDSRV_HAIR_VERTEX_POSITIONS, 1, &m_pTressFXMesh->m_HairVertexPositionsSRV );
    pd3dContext->VSSetShaderResources( IDSRV_HAIR_TANGENTS, 1, &m_pTressFXMesh->m_HairVertexTangentsSRV );

    if (useLinePrimitives)
		// render line primitives for the shadow map
        pd3dContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_LINELIST );

        UINT strides = sizeof( StrandVertex );
        UINT offsets = 0;
        pd3dContext->IASetInputLayout( m_pLayoutHair_2 );
        pd3dContext->IASetVertexBuffers( 0, 1, &m_pTressFXMesh->m_pVertexBuffer, &strides, &offsets );
        pd3dContext->IASetIndexBuffer( m_pTressFXMesh->m_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );

        pd3dContext->DrawIndexed(UINT( density * m_pTressFXMesh->m_TotalIndexCount), 0, 0 );
		// triangle rendering
        pd3dContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

        UINT stride = 0;
        UINT offset = 0;
        pd3dContext->IASetInputLayout( 0 );
        ID3D11Buffer* buf[]={0};
        pd3dContext->IASetVertexBuffers( 0, 1, buf, &stride, &offset );
        pd3dContext->IASetIndexBuffer( m_pTressFXMesh->m_pTriangleIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );

    	pd3dContext->VSSetShaderResources( IDSRV_HAIR_THICKNESSES, 1, &m_pTressFXMesh->m_pThicknessCoeffsSRV);

        pd3dContext->DrawIndexedInstanced(UINT( density * m_pTressFXMesh->m_TotalTriangleIndexCount), iStrandCopies, 0, 0, 0);  // If iStrandCopies>1 a different VS is set

    ID3D11ShaderResourceView* nullViews[] = { NULL };
    pd3dContext->VSSetShaderResources( IDSRV_HAIR_VERTEX_POSITIONS, 1, nullViews );
    pd3dContext->VSSetShaderResources( IDSRV_HAIR_TANGENTS, 1, nullViews );

While the current unity tressfx render uses the Graphics.DrawProcedural() function combined with a geometry shader that will cut the linestrips at the end of each strand.
That’s not the best method to do it because the geometry shader will get executed for every draw call, while the DrawIndexedInstanced won’t execute any geometry shader.

The A-Buffer pass will render the hair geometry to the backbuffer and sort the hair strands in back-to-front order for correct alpha blending.
It will store data for every pixel, as mentioned in the porting guide:

abufferThe next step on my list is to implement triangle rendering and port this shader pass to unity’s cg shading system and implement alpha-blended rendering.
After that i will start with the K-Buffer and rendering pass. I will write a post here when i got any progress on this.

AMD’s TressFX for Unity


In the first post on my new blog, i want to show AMD’s TressFX effect and my current progress on porting it to unity.
TressFX was developed in 2013, the newest version of it got released in november 2013 and is available in the radeon sdk: http://developer.amd.com/tools-and-sdks/graphics-development/amd-radeon-sdk/

It uses a DirectCompute shader to simulate single hair strands physically accurate on the gpu. This way it can handle thousands of strands in realtime.
The compute shader consists of multiple functions/kernels, which will get executed one after another.

For rendering it uses the Kajiya-Kay lighting model for simulating realistic lighting for the single hair strands. The rendering is done in two passes. The first pass is the “A-Buffer Pass” which will fill a buffer that holds the pixel-coverage of the current vertex in the hair stand and some other values needed for rendering.

The next pass is the “K-Buffer Sort and Rendering” pass.
It sorts the pixels stored in the A-Buffer pass in back-to-front order for blending the correclty. After sorting these pixels, alpha blending is done and the hair gets rendered.

Further information on how TressFX works can get obtained in the radeon sdk. The TressFX sample includes a manual and a porting guide.

My first attempt to port TressFX to unity was to use the native plugin interface and reuse the TressFX sample code, which failed after 3 days full of debugging issues and no really process. Then i started porting the TressFX C++ code to C# and reuse the HLSL DirectCompute shader. I just needed to do minor changes in order to make it work with unity.

Currently my TressFX implementation just supports LineStrip topology rendering which will get changed to triangle rendering. There are also some strange bugs on some graphics cards (mostly seen on mobile graphics cards, i will have a look into it after the rendering is finished).

The full code of the unity TressFX implementation is available on Github: https://github.com/kennux/TressFXUnity
There’s also a webplayer demo:¬†http://kennux.net/unity/SimulationDemo/
And a demo video: http://kennux.net/unity/TressFX/Simulation1.mp4