DIRECT2D 1.1 Development Notes effect article (v) radial blur

Source: Internet
Author: User
Tags assert
(reprint please indicate the source)

For a long time did not update the blog, a little busy, recently a little tired, write new things are also good, this time to say direct2d special effects article. This part has not been updated for more than a year. found that the level of code is much higher than a year ago:

Since the use of vs2015, the waist is not sour, the leg does not hurt, a breath code hundreds of lines also do not bother. So the engineering code may need WIN10 SDK + VS2015 to compile successfully. Theory Win8 can, a little change to Win7 also OK, but Win10 can guarantee no problem:) This time we're going to talk about radial blur:

The built-in effects provided by Microsoft have Gaussian blur and directional blur. For basic applications, the radial blur is still a difference.

So let's do it now, make a "game version" of the radial blur, a little bit simpler:
We all know the fuzzy algorithm: After processing the pixel is the original "nearby" several sampling points of the weighted average value. Gaussian Blur is the weight of Gauss function, ordinary on the arithmetic mean, simple.

So in theory we just follow a central point and sample it.

For example, 8 sampling points, the intensity is roughly 60%, (of course, this is the sample I provided, the actual 64 sampling points can not be so delicate),
This output pixel color is: This special case of the algorithm

Point =?,?
Center =?,?
Step = (center-point)/8 * 0.6
color = 0 for
(i:0...8) color + = Get_color (point + step*i)
color/= 8

How, simple, if the strength reaches 100%, basically each point is a central point of the "gene" (Forget what word).

So this is still a pixel shader, but with a constant buffer (Cbuffer):

//2D texture The first input is stored in t0 texture2d inputtexture:register (t0);//sampler State first stored in S0 samplerstate Inputsa

Mpler:register (S0);
    Constant Cache (B0) cbuffer Radialblurproperties:register (b0) {float2 center:packoffset (C0);
    Float Magnitude:packoffset (C0.Z);
Float Samples:packoffset (C0.W);

}; Shader entrance FLOAT4 Main (float4 clipspaceoutput:sv_position, Float4 scenespaceoutput:scene_position, Floa
    T4 texelspaceinput0:texcoord0): sv_target {//initialize FLOAT4 color = 0;
    Float2 step = (CENTER-TEXELSPACEINPUT0.XY)/samples * magnitude; Iterate through each sampling point for (float i = 0; i < samples; ++i) {//Compute sampling location FLOAT2 pos = texelspaceinput0.xy + step
        I
    Add Sample Data color + + inputtexture.sample (Inputsampler, POS);
///average return color/samples; }

The main function has nothing to say, with the previous special case basic one truth. It is worth explaining: Pixel shader inside of the image Unit is 1.0, so the image center point is 0.5,0.5. So here the radial Fuzzy Center point unit is also so strength unit with 1.0, convenient, general range [-1.0, 1.0] sampling rate with dynamic, can also be written dead to facilitate compiler optimization.

Constant caching (B0)
cbuffer radialblurproperties:register (b0) {
    float2  center      : Packoffset (C0);
    Float   magnitude   : Packoffset (c0.z);
    Float   Samples     : Packoffset (C0.W);

Center, the central point of fuzzy control.
Magnitude, fuzzy strength.
samples, sample quantity. can use integral type, but think of the graphics card's floating-point operation ability is stronger, so use float.
Cbuffer is a keyword that represents the constant cache, which is 256-byte aligned from the D3D12, so use a multiple of 256 bytes as much as possible.
B0 represents the first constant cache register.
Packoffset is the default 128-bit alignment, so use this. C + + objects

C + + End is simple, this time two in one:

Radial blur effects class Radialblureffect final:public Id2d1effectimpl, public id2d1drawtransform {public://Property list enum
        : UINT32 {//d2d1_point_2f Properties_centerpoint = 0,//float properties_magnitude,
   Float Properties_samples};
    ... public://Set Center point Auto SetCenter (const d2d1_point_2f& PT) noexcept {m_cbuffer.center = pt;}
    Get Center Point Auto Getcenter () const noexcept {return m_cbuffer.center;}
    Set degree auto Setmagnitude (float m) noexcept {m_cbuffer.magnitude = m;}
    Gain degree Auto Getmagnitude () const noexcept {return m_cbuffer.magnitude;}
    Set the sampling quantity auto Setsamples (float s) noexcept {m_cbuffer.samples = s;}
    Get the sample Quantity Auto Getsamples () const noexcept {return m_cbuffer.samples} private: ...//constant cache.//
        struct {//center point d2d1_point_2f Center = d2d1_point_2f (); degree float magnitude = 0.1f;
        Sampling point Quantity float samples = 16.F;
Constant cache} M_cbuffer; };

at the same time inherit from Id2d1effectimpl, Id2d1drawtransform, easy to write. Update Cbuffer:

Modifies the control variable, and modifies the cbuffer synchronously, which is the positive solution. But the modification of a synchronized modification, performance must be low, after all, limited by the video card bandwidth. So we just need to check before rendering: If you modify it, sync the graphics data. Microsoft provides us with the Id2d1effectimpl::P Repareforrender interface for easy inspection:

Preparing to render
ifacemethodimp radialblureffect::P repareforrender (d2d1_change_type changetype) noexcept {
    if ( changetype = = D2d1_change_type_none) return S_OK;
    Sets the pixel shader
    m_pdrawinfo->setpixelshader (guid_dustpg_radialblurshader);
    Modified Property
    if (changetype = = d2d1_change_type_properties) {
        //update constant cache return
        m_pdrawinfo-> Setpixelshaderconstantbuffer (
            reinterpret_cast<byte*> (&m_cbuffer), sizeof (M_cbuffer)
            );
    return S_OK;
}
Variable Binding

Requires two parts: XML information

D2d1_property_binding data

XML is relatively simple to add a property node on the line:

xml (<?xml Version = "1.0"?> <Effect> <property name = "DisplayName" type = "s Tring "value =" Radiablureffect "/> <property name =" Author "type =" string "value =" Dustpg "/> <pro Perty name = "Category" type = "string" value = "Transform"/> <property name = "Description" type = "string" va Lue = "radial blur"/> <Inputs> <input name = "Source"/> </Inputs> <property name= ' C Enter ' type= ' Vector2 ' > <property name= ' DisplayName ' type= ' string ' value= ' radial blur center '/> </p roperty> <property name= ' magnitude ' type= ' float ' > <property name= ' DisplayName ' type= ' string ' value = ' radial blur cagnitude '/> </Property> <property name= ' Samples ' type= ' float ' > <property Name= ' DisplayName ' type= ' string ' value= ' radial blur samples count '/> </Property> </effect> 

There are a list of previous references, and the type attribute needs to be filled in.

D2d1_property_binding use Microsoft to provide the macro d2d1_value_type_binding on the line
, but my failure, do not know is not a lot of inheritance of the pot, so I wrote a, anonymous expression is good:

 #define My_d2d1_value_type_binding (class, TYPE, NAME) \ {\ L#name, [] (iunknown* obj, c
            Onst byte* data, UINT32 len) noexcept {\ assert (obj && data && len = = sizeof (TYPE)); \
            Auto Impl = static_cast<id2d1effectimpl*> (obj); \ auto ths = static_cast<class*> (impl); \ ths->set# #NAME (*reinterpret_cast<const type*> (data)); \ return s_ok;\}, [] (const IUNKN own* obj, byte* OPTIONAL-data, UINT32 len, uint32* OPTIONAL outeln) noexcept {\ assert (obj); \ if ( data) {\ auto Impl = Static_cast<const id2d1effectimpl*> (obj); \ auto ths = Static_ca
            St<const radialblureffect*> (impl); \ *reinterpret_cast<type*> (data) = ths->get# #NAME (); \ }\ if (outeln) {\ *outeln = sizeof (TYPE); \} \ Return S_ok;\} \
    }

It's a bit of a hassle, but that's it. But I find that, in this case, it is not to limit the CPU and GPU size segment consistent? ( ̄▽ ̄) ╭ but that's not what we care about.

Register, initialize, do not say. The update control variable is roughly the same:

//set radial blur parameter void Imagerenderer::config_blur_properties () noexcept {//Set attribute const int NAM
    Eless = 400;
    const int nameless_2 = NAMELESS/2;
        {//Computing center Point pt;:: GetCursorPos (&PT);
        :: ScreenToClient (M_hwnd, &pt);
        Auto size = M_ptestbitmap->getsize ();
        Size.width = float (pt.x)/size.width;
        Size.Height = float (pt.y)/size.height; Calculated strength Auto magnitude = static_cast<float> (int (m_cframecount)% nameless-nameless_2)/Stati
        C_cast<float> (nameless_2);
        magnitude = std::abs (magnitude) * 2.F-1.F;
        Calculate the sample amount of float Sam = 64.f;
        Set Data M_pradialblureffect->setvalue (radialblureffect::P roperties_centerpoint, size);
        M_pradialblureffect->setvalue (radialblureffect::P roperties_magnitude, magnitude);
    M_pradialblureffect->setvalue (radialblureffect::P roperties_samples, Sam); }
}


Engineering code for the convenience of everyone, I put it on the GitHub,
because it can be browsed online, the address of this section is here. Right, do not forget the shader of the compiler, in order to save run-time time, here still use a precompiled way, forget to look at the front.

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.