Directx11 tutorial (64) tessellation (6)-PN triangles

Source: Internet
Author: User
Tags mul

Previously, we used tessellation to subdivide a triangle or a quadrilateral. The generated subdivision points are within a triangle or a quadrilateral plane. In this tutorial, we will take a look at the PN triangles (point normal triangles) method and subdivide a triangle into a curved surface. For details about PN triangles, see: 2001 paper by vlachos et al. Next we will briefly introduce PN triangles:

As we all know, we usually use the besell function to represent a smooth surface. The besell function is a polynomial function. The surface it represents is also called the besell surface. For details about the besell surface, go to the Wiki.Bezr Surface.

Pn triangle is a special besell surface, which is expressed:

U, V, W are the center of gravity coordinates, bxyz is the control point, where u + V + W = 1, the position of the control point is as follows, it can be seen that b003, b030, b300 is the three vertex control points of a triangle. Based on the positions and directions of these three control points, we can calculate the positions of other control points.

The Pn triangles method is calculated using the following method:

Next we will add PN triangle support based on mytutoriald3d_54 and generate a surface using a triangle. First, modify the meshclass class to add the normal attribute to the vertex structure of the triangle patch, because it is required to calculate the control point.

Struct vertextype
{
D3dxvector3 position;
D3dxvector3 normal;
D3dxvector4 color;
};

...

// Create a clockwise triangle and a left-hand rule
// Set vertex data
Vertices [0]. Position = d3dxvector3 (4.0f, 0.0f,-2.0f); // bottom left
Vertices [0]. Normal = d3dxvector3 (-1.0f, 1.0f, 0.0f );
Vertices [0]. Color = d3dxvector4 (1.0f, 1.0f, 0.0f, 1.0f );

Vertices [1]. Position = d3dxvector3 (6.0f, 0.0f, 4.0f); // medium to high.
Vertices [1]. Normal = d3dxvector3 (0.0f, 1.0f, 1.0f );
Vertices [1]. Color = d3dxvector4 (0.0f, 1.0f, 0.0f, 1.0f );

Vertices [2]. Position = d3dxvector3 (8.0f, 0.0f,-2.0f); // bottom right
Vertices [2]. Normal = d3dxvector3 (1.0f, 1.0f, 0.0f );
Vertices [2]. Color = d3dxvector4 (0.0f, 1.0f, 1.0f, 1.0f );

Next, modify the tessshaderclass class, modify the vertex layout, and add normal support:

Polygonlayout [1]. semanticname = "normal ";
Polygonlayout [1]. semanticindex = 0;
Polygonlayout [1]. format = dxgi_format_r32g32b32_float;
Polygonlayout [1]. inputslot = 0;
Polygonlayout [1]. alignedbyteoffset = 12;
Polygonlayout [1]. inputslotclass = d3d11_input_per_vertex_data;
Polygonlayout [1]. instancedatasteprate = 0;

The next step is the modification of the shader file, which is also the most critical part. Let's take a look at each shader file. In vs, it is basically pass through, and pass the vertex attribute to HS, compared with the previous one, HS adds the code for generating new control points:

Constantoutputtype colorpatchconstantfunction (inputpatch {
Constantoutputtype output;

// Set the subdivision factor of the three edges.
Output. Edges [0] = tessellationamount;
Output. Edges [1] = tessellationamount;
Output. Edges [2] = tessellationamount;

// Set the subdivision factor in the Triangle
Output. Inside = tessellationamount;

// The Position of the three control vertices in PN triangle, which is the same as the original control point of the triangle patch.
Float3 f3b003 = inputpatch [0]. position;
Float3 f3b030 = inputpatch [1]. position;
Float3 f3b300 = inputpatch [2]. position;


// Normal
Float3 f3n002 = inputpatch [0]. normal;
Float3 f3n020 = inputpatch [1]. normal;
Float3 f3n200 = inputpatch [2]. normal;


// Calculate edge control points and central control points based on the formula
Output. f3b210 = (2.0f * f3b003) + f3b030-(dot (f3b030-f3b003), f3n002) * f3n002)/3.0f;
Output. f3b120 = (2.0f * f3b030) + f3b003-(dot (f3b003-f3b030), f3n020) * f3n020)/3.0f;
Output. f3b021 = (2.0f * f3b030) + f3b300-(dot (f3b300-f3b030), f3n020) * f3n020)/3.0f;
Output. f3b012 = (2.0f * f3b300) + f3b030-(dot (f3b030-f3b300), f3n200) * f3n200)/3.0f;
Output. f3b102 = (2.0f * f3b300) + f3b003-(dot (f3b003-f3b300), f3n200) * f3n200)/3.0f;
Output. f3b201 = (2.0f * f3b003) + f3b300-(dot (f3b300-f3b003), f3n002) * f3n002)/3.0f;

Float3 f3e = (output. f3b210 + output. f3b120 + output. f3b021 + output. f3b012 + output. f3b102 + output. f3b201)/6.0f;
Float3 f3v = (f3b003 + f3b030 + f3b300)/3.0f;
Output. f3b111 = f3e + (f3e-f3v)/2.0f );

// Calculate the normal control point
Float fv12 = 2.0f * dot (f3b030-f3b003, f3n002 + f3n020)/DOT (f3b030-f3b003, f3b030-f3b003 );
Output. f3n110 = normalize (f3n002 + f3n020-fv12 * (f3b030-f3b003 ));
Float fv23 = 2.0f * dot (f3b300-f3b030, f3n020 + f3n200)/DOT (f3b300-f3b030, f3b300-f3b030 );
Output. f3n011 = normalize (f3n020 + f3n200-fv23 * (f3b300-f3b030 ));
Float fv31 = 2.0f * dot (f3b003-f3b300, f3n200 + f3n002)/DOT (f3b003-f3b300, f3b003-f3b300 );
Output. f3n101 = normalize (f3n200 + f3n002-fv31 * (f3b003-f3b300 ));

Return output;
}

In ds, a new control point is generated based on the PN triangle formula:

// Center of gravity Coordinate
Float Fu = uvwcoord. X;
Float FV = uvwcoord. Y;
Float fw = uvwcoord. Z;

// Pre-calculate required values
Float fuu = fu * Fu;
Float fvv = FV * FV;
Float fww = fw * Fw;
Float fuu3 = fuu * 3.0f;
Float fvv3 = fvv * 3.0f;
Float fww3 = fww * 3.0f;
// Calculate the vertex position after subdivision based on the formula and the center of gravity Coordinate
Float3 f3position = Patch [0]. Position * fww * Fw +
Patch [1]. Position * fuu * Fu +
Patch [2]. Position * fvv * FV +
Input. f3b210 * fww3 * Fu +
Input. f3b120 * Fw * fuu3 +
Input. f3b201 * fww3 * FV +
Input. f3b021 * fuu3 * FV +
Input. f3b102 * Fw * fvv3 +
Input. f3b012 * Fu * fvv3 +
Input. f3b111 * 6.0f * Fw * Fu * FV;


// Calculate the position of the new vertex in the world coordinate system
Output. Position = MUL (float4 (f3position, 1.0f), worldmatrix );
Output. Position = MUL (output. Position, viewmatrix );
Output. Position = MUL (output. Position, projectionmatrix );

// Calculate the normal direction
Float3 f3normal = Patch [0]. Normal * fww +
Patch [1]. Normal * fuu +
Patch [2]. Normal * fvv +
Input. f3n110 * Fw * Fu +
Input. f3n011 * Fu * FV +
Input. f3n101 * Fw * FV;

// Normalization
F3normal = normalize (f3normal );

Output. Normal = f3normal;

// The new vertex color is also the color combination of each Control Point
Output. Color = uvwcoord. x * Patch [0]. color + uvwcoord. y * Patch [1]. color + uvwcoord. z * Patch [2]. color;

After the program is executed, the interface is shown as follows. Tess factor ranges from 1 to 6. As the subdivision factor increases, the closer the triangle is to the surface.

Complete code can be found:

Project File mytutoriald3d11_59

Download Code:

Provided later

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.