Directx11 tutorial (49) Application of stenpencil-mirror reflection

Source: Internet
Author: User

In this tutorial, we use stencel to implement a mirror reflection effect.

1. First, we need to add several member variables and functions in d3dclass.

Id3d11depthstencilstate * m_depthstencilstatemirror;
Id3d11depthstencilstate * m_depthstencilstatereflect;

M_depthstencilstatemirror is the depth stencer State used when rendering the mirror. We set the stencer function to d3d11_comparison_always. In this way, stencer can always pass, and then the pass operation is fail, the Set ref value is used to fill the stencel buffer.

Depthstencildesc. depthenable = true;
Depthstencildesc. depthwritemask = d3d11_depth_write_mask_all

Depthstencildesc. depthfunc = d3d11_comparison_less;

Depthstencildesc. stencilenable = true;
Depthstencildesc. stencilreadmask = 0xff;
Depthstencildesc. stencilwritemask = 0xff;

// Template operations for front face pixels.
Depthstencildesc. frontface. stencilfailop = d3d11_stencil_op_keep;
Depthstencildesc. frontface. stencildepthfailop = d3d11_stencil_op_keep;
Depthstencildesc. frontface. stencilpassop = d3d11_stencil_op_replace;
Depthstencildesc. frontface. stencilfunc = d3d11_comparison_always;

// Template operation mode for back face pixels.
Depthstencildesc. backface. stencilfailop = d3d11_stencil_op_keep;
Depthstencildesc. backface. stencildepthfailop = d3d11_stencil_op_decr;
Depthstencildesc. backface. stencilpassop = d3d11_stencil_op_replace;
Depthstencildesc. backface. stencilfunc = d3d11_comparison_always;

// Create a deep template to make it take effect
Result = m_device-> createdepthstencilstate (& depthstencildesc, & m_depthstencilstatemirror );
If (failed (result ))
{
HR (result );
Return false;

}

M_depthstencilstatereflect is used to render the reflected objects in the mirror. Depth test is forbidden at this time, so that depth test is always passed. The stenpencil function is used to compare the current stenpencil ref value with the value in stenpencil buffer, if the value is equal to the value of pass stencel test.

// Set the reflect object depth template status description.
Depthstencildesc. depthenable = true;
Depthstencildesc. depthwritemask = d3d11_depth_write_mask_zero; // d3d11_depth_write_mask_zero disable deep write buffer
Depthstencildesc. depthfunc = d3d11_comparison_always;

// Template operations for front face pixels.
Depthstencildesc. frontface. stencilpassop = d3d11_stencil_op_keep;
Depthstencildesc. frontface. stencilfunc = d3d11_comparison_equal;

// Create a deep template to make it take effect
Result = m_device-> createdepthstencilstate (& depthstencildesc, & m_depthstencilstatereflect );
If (failed (result ))
{
HR (result );
Return false;

}

M_alphaenableblendingstate state variable creates an Alpha blend state, which is mainly used when rendering objects in the mirror, because our mirror is represented by a texture, alpha blend combines the mirror texture with the rendered object.

// Create an Alpha blend status.
Blendstatedescription. rendertarget [0]. blendenable = true;
// Blendstatedescription. rendertarget [0]. srcblend = d3d11_blend_one;
Blendstatedescription. rendertarget [0]. srcblend = d3d11_blend_blend_factor;
Blendstatedescription. rendertarget [0]. destblend = d3d11_blend_inv_blend_factor;
Blendstatedescription. rendertarget [0]. blendop = d3d11_blend_op_add;
Blendstatedescription. rendertarget [0]. srcblendalpha = d3d11_blend_one;
Blendstatedescription. rendertarget [0]. destblendalpha = d3d11_blend_zero;
Blendstatedescription. rendertarget [0]. blendopalpha = d3d11_blend_op_add;
Blendstatedescription. rendertarget [0]. rendertargetwritemask = d3d11_color_write_enable_all; // 0x0f;

// Create an Alpha blend state with the descriptor
Result = m_device-> createblendstate (& blendstatedescription, & m_alphaenableblendingstate );
If (failed (result ))
{
Return false;
}

Another function is changebackcullmode (bool B), which is used to change the rendering state and set the front face to clockwise rendering. Because when rendering an object in a mirror, the front of the object in the mirror actually corresponds to the opposite of the object, which requires changing the rendering order.

The following functions are used to change the new States.

Void turnonalphablending ();
Void turnoffalphablending ();
Void changebackcullmode (bool B );

Void enabledefaultdepthstencel ();
Void enableincludepthstenpencil ();
Void enablereflectdepthstenpencil ();

2. The beginsence function in d3dclass is slightly changed. The stencer value is cleared before each frame is rendered to 0.

Void d3dclass: beginscene (float red, float green, float blue, float alpha)
{
...

// Clear the buffer depth.
M_devicecontext-> cleardepthstencilview (m_depthstencilview, d3d11_clear_depth | d3d11_clear_stencer, 1.0f, 0 );

Return;
}

3. added a built-in modelclass class to indicate the mirror mesh.

4. Rendering objects in sequence in the graphicsclass class

First render the ground, wall, and box

M_d3d-> enableincludepthstencel ();

Render mirror

M_d3d-> enabledefaultdepthstencel ();

Define the mirror reflection plane and calculate the reflection matrix. Note that when d3dxmatrixreflect calculates the reflection matrix, the plane is normalized, so I added a translation operation.

D3dxplane serial plane (0.0, 0.0, 10.99, 0.0 );
D3dxmatrix R;
// Obtain the reflection matrix based on the plane.
D3dxmatrixreflect (& R, & mirrorplane );
// The box is at the origin and remains unchanged. Its world coordinate matrix is worldmatrix.
D3dxmatrix W = worldmatrix * R;
D3dxmatrixtranslation (& worldmatrix1, 0.0, 0.0,-18.0 );
W = worldmatrix1 * W;

Next, set the status

M_d3d-> enablereflectdepthstenpencil ();
M_d3d-> turnonalphablending ();
M_d3d-> changebackcullmode (true );

Rendering box in mirror

M_d3d-> enabledefaultdepthstencel ();
M_d3d-> turnoffalphablending ();
M_d3d-> changebackcullmode (false );

The final effect of the program is as follows:

Complete code can be found:

Project File mytutoriald3d11_43

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.