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