Directx11 tutorial (52) simple application of instancing

Source: Internet
Author: User

Sometimes, we need to render a large number of repeated objects in the scene, such as the audience in the stadium, the trees in the forest, and so on. These objects have similar shapes, such as many trees, but with different positions, or the textures are different. If we use the billboard technology to repeatedly render these trees and use N trees, we need to input N * 4 vertices. When there are many trees, this is not a small overhead, because data is transmitted between system memory and GPU every time.

In d3d11, this overhead can be effectively reduced by using the instance technology.

The main implementation method of instance technology: defines a vertex buffer, and then defines the second buffer, called instance buffer, which only records the information of the object changes, such as the information of location changes. In this way, a large number of objects can be effectively rendered by passing in a small number of vertices.

Next, we will draw 4 trees based on mytutoriald3d11_45 using the instance technology.

1. First, modify the vertex modelclass. Because our tree is implemented through the billboard, this class is used to define vertex and instance buffer information (because our code is modified, so I didn't change the class name. In principle, using treemodelclass may be more intuitive)

Define the instance class structure. We only change the object location, so the structure is very simple. Then we define the instance buffer and instance count (excluding the index buffer ).

Struct instancetype {d3dxvector3 position ;};

...

Id3d11buffer * m_instancebuffer; // instance Buffer
Int m_instancecount;

The instance buffer definition code is as follows:

Instances [0]. Position = d3dxvector3 (-5.5f, 0.0f, 5.0f );
Instances [1]. Position = d3dxvector3 (-1.5f, 0.0f, 5.0f );
Instances [2]. Position = d3dxvector3 (5.5f, 0.0f, 15.0f );
Instances [3]. Position = d3dxvector3 (1.5f, 0.0f, 9.0f );

...
// Create an instance buffer.
Instancebufferdesc. Usage = d3d11_usage_default;
Instancebufferdesc. bytewidth = sizeof (instancetype) * m_instancecount;
Instancebufferdesc. bindflags = d3d11_bind_vertex_buffer;
Instancebufferdesc. cpuaccessflags = 0;
Instancebufferdesc. miscflags = 0;
Instancebufferdesc. structurebytestride = 0;

// Point to the temporary instance buffer.
Instancedata. psysmem = instances;
Instancedata. sysmempitch = 0;
Instancedata. sysmemslicepitch = 0;

Result = device-> createbuffer (& instancebufferdesc, & instancedata, & m_instancebuffer );
If (failed (result ))
{
Return false;
}

The next step is the change of the rendering buffer function. Here we have removed the index buffer, and we also note that we use the entity semantics of the triangle band (strip. In the vertex buffer, we define four points. Through the triangle band, we can draw a rectangle to make the billboard.

Void initialize modelclass: renderbuffers (id3d11devicecontext * devicecontext)
{
Unsigned int strides [2];
Unsigned int offsets [2];
Id3d11buffer * bufferpointers [2];

// Set the vertex buffer span and offset.
Strides [0] = sizeof (vertextype );
Strides [1] = sizeof (instancetype );

Offsets [0] = 0;
Offsets [1] = 0;

// Point to vertex buffer and instance buffer.
Bufferpointers [0] = m_vertexbuffer;
Bufferpointers [1] = m_instancebuffer;

// Bind the vertex buffer and index buffer in the input assemberl phase for rendering.
Devicecontext-> iasetvertexbuffers (0, 2, bufferpointers, strides, offsets );

// Set the body meta semantics to render the triangle band
Devicecontext-> iasetprimitivetopology (d3d11_primitive_topology_trianglestrip );

Return;
}

Next, we will define a new lighttexinstanceshader class, which is the shader class for rendering instance objects. Its code is similar to the lighttexshader class. I mainly point out that different parts are in the input layout, we added the instance buffer, which will be passed into.

// Instance data
Polygonlayout [5]. semanticname = "texcoord ";
Polygonlayout [5]. semanticindex = 1;
Polygonlayout [5]. format = dxgi_format_r32g32b32_float;
Polygonlayout [5]. inputslot = 1;
Polygonlayout [5]. alignedbyteoffset = 0;
Polygonlayout [5]. inputslotclass = d3d11_input_per_instance_data;
Polygonlayout [5]. instancedatasteprate = 1;

// Obtain the number of elements in layout.
Numelements = sizeof (polygonlayout)/sizeof (polygonlayout [0]);

// Create a vertex input layout.
Result = device-> createinputlayout (polygonlayout, numelements, vertexshaderbuffer-> getbufferpointer (), vertexshaderbuffer-> getbuffersize (),
& M_layout );

Then, use drawinstance to replace the drawindex function.

// Rendering triangle instance
Devicecontext-> drawinstanced (indexcount, instancecount, 0, 0 );

Finally, the rendering tree instance is called in the graphicsclass class:

Result = m_lighttexinstanceshader-> render (m_d3d-> getdevicecontext (), m_0000model-> getvertexcount (), m_0000model-> getinstancecount (), worldmatrix4, viewmatrix, projectionmatrix,
Light, material, camera, m_texmanager-> createtex (m_d3d-> getdevice (), string ("tree1.dds ")));
If (! Result)
{
Return false;
}

In vs, we will read the location offset in the instance buffer and use it to offset each vertex to draw different instances:

Struct vertexinputtype
{
Float4 position: position;
Float3 normal: normal;
Float2 TEX: texcoord0; // texture coordinate
Float4 KD: diffuse;
Float4 KS: specular;
Float3 instanceposition: texcoord1;
};

...

// Update the vertex position with instance data.
Input. position. x + = input. instanceposition. X;
Input. position. Y + = input. instanceposition. Y;
Input. position. Z + = input. instanceposition. Z;

NOTE: For the examples in this chapter, we get different instances through the offset location to draw different trees, but we only use a world matrix for these different instance billboards, we should use different world matrices, that is, we should consider the location offset of each instance so that every billboard tree can face the camera direction. However, in this way, computing the world matrix on the CPU end may not be very suitable for the instance billboard.

After the program is executed, the interface is as follows:

Complete code can be found:

Project File mytutoriald3d11_46

Download Code:

Http://files.cnblogs.com/mikewolf2002/d3d1139-49.zip

Http://files.cnblogs.com/mikewolf2002/pictures.zip

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.