Just an Update

Hey there,

Yes, i am still alive ūüôā

I recently spent some hours going on with the debugging of the Unity TressFX portation and it doesn’t seem i’ll figure out how to integrate¬†it nicely into unity, so at this point i’ll stop working on it. The simulation is very well integrated but for the rendering i don’t know if unity is even capable of rendering such DX 11 effects (For example DrawProcedural() doesn’t seem to integrate well into the Graphics pipeline as it does not render shadows and anything else, there’s also not much documentation about DX 11).

However, i may go on with it later (maybe if Unity 5 is released). Also anyone is free to work on my code, which is available on github (https://github.com/kennux/TressFXUnity).

For now, i’ll work on some other projects and / or games, which i’ll post here if there is something to post ūüėõ

 

Unity TressFX progress

Hey there,

It’s been a time since i wrote a post here. I’ve been working on other projects or was playing Diablo 3 and Payday 2 (Really nice games :D).

So, for Unity TressFX some days ago i uploaded a fix for the coverage computing issue, which was a very stupid mistake by me.
I’ve seen that the coverage computing was working “well” (Well, it wasn’t ^^) if i “eliminate” the pixel offsets i get in the shader.
That was wrong, i did calculations in 2 different coordinate system (was mixing DirectX calculations with Unity’s OpenGL style calculations).

Now the calculations are fixed and the coverage computing is fully working.
However, i’m still facing a serious bug in the fragment shader. Fragments at 0|0 get passed with screen coordinates like 38|4 which is currently really annoying me.

I’m still working on TressFX and i’ll try to get some hours to patch or atleast try to patch the pixel offsetbug.
After that i’m going to implement the order independent transparency, Kajiya-Kay lighting and the shadows.

The shadows will also be my next bigger problem because it seems like Unity’s Graphics.DrawProcedural() function does not integrate well in the graphics pipeline (“Normal” shadow rendering like in unity surface shaders or with the unity makros for fragment and vertex shaders seems to be impossible to use with procedurally drawn geometry).

So, that’s all for the moment.

A-Buffer Pass finished!

Heyho,

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:

coverage_computing

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

Heyho,

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 );
    }
    else
	{
		// 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

Hello,

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