Graphics Reference
In-Depth Information
To generate these two triangles, each line segment results in six vertices. The full
extent of the geometry expansion occurs in the vertex shader. Here are the two
steps involved in the hair geometry expansion:
World-space hair fiber radius expansion: The rasterized hair fibers end up
being a sequence of view plane aligned billboards for each hair fiber segment.
The individual hair fiber segments are expanded by the hair fiber radius in
world space when these billboards are generated.
Screen-space pixel expansion: After projecting the expanded hair fiber ver-
tices, an additional expansion occurs to ensure that a single hair fiber covers
at least one pixel width by adding 2 / 2
0 . 71 to the projected hair fiber
radius.
See Listing 5.1 to see how both of these described steps are performed in the
vertex shader that performs the hair geometry expansion.
static const uint HairVertexSelection [] = { 0, 1, 0, 1, 1, 0 } ;
static const float OffsetDir [] =
{− 1. f , 1. f ,1. f , 1. f ,1. f ,1. f } ;
static const uint OffsetDirIndex [] = { 0, 0, 1, 0, 1, 1 } ;
HairPSInput HairVS ( uint vertexId : SV_VertexID )
{ HairPSInput Output =( HairPSInput )0;
float thicknessFactor [] = ... // normalized thickness scaler
// two tangents and vertices of the hair fiber segment
float3 t [2] , v [2];
// calculate right vector for billboarding the hair fiber quad
float3 right [] = {
cross ( t [0] , normalize ( v [0]
g_vEye )),
cross ( t [1] , normalize ( v [1]
g_vEye ))
}
;
float2 proj_right [] =
{
normalize ( mul ( float4 ( right [0] , 0), g_mViewProj ). xy ),
normalize ( mul ( float4 ( right [1] , 0), g_mViewProj ). xy )
}
// Setting up the indexing for calculating one of the
// 6 verts of the 2 triangles making a quad
// indexing vert 0 to 5
uint localVertId = vertexId % GENERATED_VERTEX_COUNT ;
// choosing vertex in the fiber segment
uint idx
= HairVertexSelection [ localVertId ];
// choosing which direction to offset from the fiber segment
uint offDirIndex = OffsetDirIndex [ localVertId ];
float4 hairEdgePositions [2]; // 0 is negative , 1 is positive
// World space expansion
hairEdgePositions [0] = float4 ( v [ idx ]+
1. f ￿ right [ idx ] ￿ thicknessFactor [ idx ] ￿ fiberRadius ,1. f );
hairEdgePositions [1] = float4 ( v [ idx ]+
1. f ￿ right [ idx ] ￿ thicknessFactor [ idx ] ￿ fiberRadius ,1. f );
hairEdgePositions [0] = mul ( hairEdgePositions [0] , g_mViewProj );
Search WWH ::




Custom Search