通常,point sprites只能通过GS来实现,但是最新的DX11.1后技术,可以直接利用VS实现,并且速度更快:
- 创建一个point buffer作为SRV绑定到VS上;
- 调用Draw或者 DrawIndexed来渲染一个三角形列表;
- 在VS中读取point buffer中的信息扩展为一个四边形;
这个技术可以用particle渲染,Bokeh DOF sprites
PS:小物体不要使用Drawinstanced.
C++ 代码:
pD3dContext->IASetIndexBuffer(g_pParticleIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
pD3dContex->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
pD3dContext->DrawIndexed(g_particleCount*6, 0, 0);
HLSL代码:
VSInstanceParticleDrawOut VSIndexBuffer( uint id:SV_VERTEXID)
{
VSInstancedParticleDrawOut output;
uint particleIndex = id/4;
uint vertexInQuad = id%4;
// calculate the position of the vertex
float3 position;
position.x = (vertexInQuad%2) ? 1.0 : -1.0;
position.y = (vertexInQuad&2) ? -1.0 : 1.0;
position.z = 0.0;
position.xy *= PARTICLE_RADIUS;
position = mul(position, (float3x3)g_mInvView) + g_bufPosColor[particleIndex].pos.xyz;
output.pos = mul(float4(position,1.0), g_mWorldViewProj );
output.color = g_bufPosColor[particleIndex].color;
// texture coordinate
output.tex.x = (vertexInQuad%2) ? 1.0 : 0.0;
output.tex.y = (vertexInQuad&2) ? 1.0 : 0.0;
return output;
}
DrawIndexed() 性能最高; Draw()稍慢点,但是不需要IB。DrawInstanced() 性能极差,不建议使用。