Directx11 tutorial (54) Simple GS-based billboard implementation

Source: Internet
Author: User

In this chapter, we use a billboard implementation to learn Gs in d3d11.

In vs shader, we input vertex and vertex parameters, and the output is also vertex and parameter. In GS shader, we input the body element (primitive, which can be a vertex, line, triangles, and so on. All the body elements allowed in d3d11 can be used. The vertex, Body element information, and related parameters are output.

For example, in the following two figures, if you perform vs operations on a triangle on the left, vertex operations will be performed on three vertices V1, V2, and V3 respectively, and GS operations will be performed on the triangle on the right, then an entire triangle is used as the input, and the output is a triangle (three triangles are added ).

Now we start to implement a GS billboard. The principle is very simple. We use a vertex to represent the center point of the billboard and two parameters to represent the width and height of the billboard. In the GS input, we use vertices as the primitive input, width and height as the parameter input, and finally generate two complete triangles to represent the billboard. At the same time, texture coordinates will be generated in Gs to paste the tree texture.

Let's take a look at the complete shader code. In fact, as long as you understand the shader execution process, you can basically complete programming. Other code in the program is just to call some functions:

Gstree. vs and vs code are very simple. The input vertex and output vertex are similar to a bypass process without any other operations. However, in d3d11, Vs and PS are two necessary shader processes.

...

Geometryinputtype treevertexshader (vertexinputtype input)
{
Geometryinputtype output;

// Directly transfer data to the GS stage.
Output. centerw = input. centerw;
Output. sizew = input. sizew;

Return output;
}

In gstree. Gs, We will generate four points and their texture coordinates based on the input coordinate of the Point body, and finally generate two triangles. At the same time, we will find the change matrix that keeps the billboard facing the camera. Note: we will pass the primitive ID of the vertex element to PS as a parameter, so that different textures can be selected based on different IDs when pasting the texture.

...

[Maxvertexcount (4)]
Void treegeometryshader (point geometryinputtype Gin [1], uint primid: sv_primitiveid, inout trianglestream <pixelinputtype> tristream)
{

// Convert the center point to the world coordinate system
Gin [0]. centerw = MUL (Gin [0]. centerw, (float3x3) worldmatrix );

// Obtain the four vertices of the billboard.
Float halfwidth = 0.5f * Gin [0]. sizew. X;
Float halfheight = 0.5f * Gin [0]. sizew. Y;

Float4 V [4];
V [0] = float4 (-halfwidth,-halfheight, 0.0f, 1.0f );
V [1] = float4 (+ halfwidth,-halfheight, 0.0f, 1.0f );
V [2] = float4 (-halfwidth, + halfheight, 0.0f, 1.0f );
V [3] = float4 (+ halfwidth, + halfheight, 0.0f, 1.0f );
//
// Calculate the texture coordinates of the four vertices.
//
Float2 texc [4];
Texc [0] = float2 (0.0f, 1.0f );
Texc [1] = float2 (1.0f, 1.0f );
Texc [2] = float2 (0.0f, 0.0f );
Texc [3] = float2 (1.0f, 0.0f );
//
// Calculate the world matrix that makes billboad face cameras
//
Float3 up = float3 (0.0f, 1.0f, 0.0f );
Float3 look = cameraposition. XYZ-Gin [0]. centerw;
Look. Y = 0.0f;
Look = normalize (look );
Float3 right = cross (up, look );

Matrix W;
Matrix gviewproj;
Gviewproj = MUL (viewmatrix, projectionmatrix );

W [0] = float4 (right, 0.0f );
W [1] = float4 (up, 0.0f );
W [2] = float4 (Look, 0.0f );
W [3] = float4 (Gin [0]. centerw, 1.0f );
// Float4x4
Matrix WVP = MUL (W, gviewproj );

//
// Convert the vertex to the world coordinate system and output the triangle band
//
Pixelinputtype gout;
[Unroll]
For (INT I = 0; I <4; ++ I)
{
Gout. Posh = MUL (V [I], WVP );
Gout. posw = MUL (V [I], W );
Gout. normalw = look;
Gout. texc = texc [I];
Gout. primid = primid; // Body element ID

Tristream. append (gout );
}
}

Gstree. PS code:

Float4 treepixelshader (pixelinputtype pin): sv_target
{
Float4 diffuse = shadertexture. Sample (sampletype, pin. texc );

// If the Alpha value is less than 0.25, discard the pixel.
Clip (diffuse. A-0.25f );

// Output texture color

Return diffuse;
}

The other code is to add a treemeshclass, indicating the Tree Mesh class, and then gsshaderclass. In this class, we will load gstree. vs, gstree. GS, gstree. PS, and transmit the const buffer and related settings. Finally, the gsshaderclass rendering tree is called in graphicsclass.

Note that in other shaderclass, we need to add the following code to the rendershader function:

Devicecontext-> gssetshader (null, null, 0 );

Otherwise, the GS specified by gsshaderclass will be used for the objects rendered by the shader class to cause rendering errors.

The execution result of the program is as follows:

Complete code can be found:

Project File mytutoriald3d11_48

Download Code:

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

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

In mytutoriald3d11_49, we add many trees and use the texture array as the PS input to call different texture textures Based on the ID of the object metadata.

The gtree. PS code is slightly different:

Texture2d shadertexture [4];
Samplerstate sampletype;

Struct pixelinputtype
{
Float4 posh: sv_position;
Float3 posw: position;
Float3 normalw: normal;
Float2 texc: texcoord;
Uint primid: sv_primitiveid;
};

Float4 treepixelshader (pixelinputtype pin): sv_target
{
// Obtain from the texture Determinant
// Float3 uvw = float3 (pin. texc, pin. primid % 4 );
// Float4 diffuse = gdiffusemaparray. Sample (sampletype, uvw );
Int I = pin. primid % 4;
Float4 diffuse;
If (I = 0)
Diffuse = shadertexture [0]. Sample (sampletype, pin. texc );
Else if (I = 1)
Diffuse = shadertexture [1]. Sample (sampletype, pin. texc );
Else if (I = 2)
Diffuse = shadertexture [2]. Sample (sampletype, pin. texc );
Else
Diffuse = shadertexture [3]. Sample (sampletype, pin. texc );

// If the Alpha value is less than 0.25, discard the pixel.
Clip (diffuse. A-0.25f );

// Output texture color

Return diffuse;
}

The program execution is as follows:

Complete code can be found:

Project File mytutoriald3d11_49

Download Code:

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

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

In mytutoriald3d11_47, we modified the previous code based on fog, water, and mountains, and added trees to the mountains. The final interface after the program is executed is as follows:

Complete code can be found:

Project File mytutoriald3d11_47

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.