D3Dshader, the pixel shader implements a variety of shape magnifying glasses (circle, square, triangle, trapezoid, hexagon, heart shape, pentagram)

Tip: After the article is written, the table of contents can be automatically generated. How to generate it can refer to the help document on the right

Article directory

  • foreword
  • 1. Round magnifying glass
  • 3. Rectangular magnifying glass
  • 4. Triangular magnifying glass
  • Five, trapezoidal magnifying glass
  • Six, hexagonal magnifying glass
  • Seven, heart-shaped magnifying glass
  • Eight, five-pointed star magnifying glass
  • Summarize

Foreword

I realized a series of magnifying glasses of different shapes before, and I referred to many articles and materials on the Internet. After I finished it, I posted it to share.

Reminder: The following is the text of this article, the following case is for reference

1. Round magnifying glass

As the most basic magnifying glass style, it is relatively simple to implement. The texture in the specified circular area is multiplied by a magnification factor (less than zero), and the code is directly written and commented in the code.

 //int magnifying_Center_x; //Lens center x coordinate (-100 to 100)
    //int magnifying_Center_y; //The y coordinate of the lens center (-100 to 100)
    //int magnifying_Radius; //(0 to 100) magnifying glass radius
    //int magnifyingl_Times; //(0 to 10) magnification
    //v2TexSize is the window size, for example (1920, 1080)
    float2 center = float2(0.5 + magnifying_Center_x / 200, 0.5-magnifying_Center_y / 200) * v2TexSize;//Calculate the center point of the magnifying glass
    float radius = magnifying_Radius / 100 * v2TexSize.y;//Generally, the window is rectangular, and the short side is selected as the radius expansion factor
    float Times = (1 - magnifyingl_Times / 10);//Calculate the magnification factor, the smaller the Times, the greater the magnification
    tex *= v2TexSize;//Restore the texture of the range (0-1) to the window size
    
    float dist = distance(tex, center);//The distance between the current texture point and the center of the magnifying glass

    // inside the circle
        if (dist < radius)//When the current texture point is in the magnifying glass
        {<!-- -->
            tex -= center;//Move the texture coordinate axis to the texture coordinate space centered on the center of the magnifying glass
        
            tex = tex * Times;//Zoom in, that is, let the current texture display the texture area closer to the center of the circle
                       
            tex + = center;//Restore to the original texture coordinate space
            
          }
    float4 outp = g_Tex.Sample(g_SamLinear, tex / v2TexSize); //Get the texture processed by the current magnifying glass
    return outp;//output

Effect:

3. Rectangular magnifying glass

Delineate a rectangular area according to the center and radius
The code for the key area is as follows:

 //int magnifying_Center_x; //Lens center x coordinate (-100 to 100)
    //int magnifying_Center_y; //The y coordinate of the lens center (-100 to 100)
    //int magnifying_Radius; //(0 to 100) magnifying glass radius
    //int magnifyingl_Times; //(0 to 10) magnification
    //v2TexSize is the window size, for example (1920, 1080)
    float2 center = float2(0.5 + magnifying_Center_x / 200, 0.5-magnifying_Center_y / 200) * v2TexSize;//Calculate the center point of the magnifying glass
    float radius = magnifying_Radius / 100 * v2TexSize.y;//Generally, the window is rectangular, and the short side is selected as the radius expansion factor
    float Times = (1 - magnifyingl_Times / 10);//Calculate the magnification factor, the smaller the Times, the greater the magnification
    tex *= v2TexSize;//Restore the texture of the range (0-1) to the window size
    
        //The current texture is in the rectangular area, and the side length of the rectangle is radius
        if ((tex.x < center.x + radius / 2) & amp; & amp; (tex.x > center.x - radius / 2) & amp; & amp; (tex.y < center.y + radius / 2) & amp; & amp; (tex.y > center.y - radius / 2))
        {<!-- -->
            tex -= center;
            tex = tex * Times;
            tex + = center;
        }
    float4 outp = g_Tex.Sample(g_SamLinear, tex / v2TexSize); //Get the texture processed by the current magnifying glass
    return outp;//output

The effect is as follows:

4. Triangular magnifying glass

The code for the key area is as follows:

 //int magnifying_Center_x; //Lens center x coordinate (-100 to 100)
//int magnifying_Center_y; //The y coordinate of the lens center (-100 to 100)
//int magnifying_Radius; //(0 to 100) magnifying glass radius
//int magnifyingl_Times; //(0 to 10) magnification
//v2TexSize is the window size, for example (1920, 1080)
float2 center = float2(0.5 + magnifying_Center_x / 200, 0.5-magnifying_Center_y / 200) * v2TexSize;//Calculate the center point of the magnifying glass
float radius = magnifying_Radius / 100 * v2TexSize.y;//Generally, the window is rectangular, and the short side is selected as the radius expansion factor
float Times = (1 - magnifyingl_Times / 10);//Calculate the magnification factor, the smaller the Times, the greater the magnification
tex *= v2TexSize;//Restore the texture of the range (0-1) to the window size

        float g = sin(PI/3)*2;
        center.y + = (g / 4) * radius;
        tex -= center;
         //a, b, c are the three vertices of the triangle
        float2 a = float2(-radius / 2, 0);
        float2 b = float2(0, -radius * g/2);
        float2 c = float2(radius / 2, 0);
 
         
        if (inTriangle(a, b, c, tex))//Whether tex is in the triangle formed by abc
        {<!-- -->
            tex = tex * Times;
        }
        tex + = center;
float4 outp = g_Tex.Sample(g_SamLinear, tex / v2TexSize); //Get the texture processed by the current magnifying glass
return outp;//output
        
        
         

The inTriangle function is used to determine whether the current point tex is within the triangle formed by the three points abc, that is to say, the shape of the triangle can be changed by changing the position of the three points abc, and this function is also used in the subsequent five-pointed star magnifying glass. Among them, the concept of pseudo-cross product is used, and the pseudo-cross product will not be expanded. Baidu, the inTriangle function is as follows:
Reference article link: link

bool inTriangle(float2 a, float2 b, float2 c, float2 tex)
{<!-- -->
    float2 AB = float2(b - a);
    float2 BC = float2(c - b);
    float2 CA = float2(a - c);
        
    float2 AP = float2(tex - a);
    float2 BP = float2(tex - b);
    float2 CP = float2(tex - c);
        
        
    bool Out_In1 = AB.x * AP.y - AB.y * AP.x > 0
         & amp; & amp; BC.x * BP.y - BC.y * BP.x > 0
         & amp; & amp; CA.x * CP.y - CA.y * CP.x > 0;
    bool Out_In2 = AB.x * AP.y - AB.y * AP.x < 0
         & amp; & amp; BC.x * BP.y - BC.y * BP.x < 0
         & amp; & amp; CA.x * CP.y - CA.y * CP.x < 0;
    return Out_In1 || Out_In2;
    
}

The triangle mosaic effect is as follows:

5. Keystone magnifying glass

Similar to the previous operation, the trapezoidal area is obtained, and the texture in the area is enlarged.

 //int magnifying_Center_x; //Lens center x coordinate (-100 to 100)
//int magnifying_Center_y; //The y coordinate of the lens center (-100 to 100)
//int magnifying_Radius; //(0 to 100) magnifying glass radius
//int magnifyingl_Times; //(0 to 10) magnification
//v2TexSize is the window size, for example (1920, 1080)
float2 center = float2(0.5 + magnifying_Center_x / 200, 0.5-magnifying_Center_y / 200) * v2TexSize;//Calculate the center point of the magnifying glass
float radius = magnifying_Radius / 100 * v2TexSize.y;//Generally, the window is rectangular, and the short side is selected as the radius expansion factor
float Times = (1 - magnifyingl_Times / 10);//Calculate the magnification factor, the smaller the Times, the greater the magnification
tex *= v2TexSize;//Restore the texture of the range (0-1) to the window size
\t    
        //Using the center of the bottom of the trapezoid as the origin, find the formulas of the other two straight lines
        float a = 1.732; //Square square root formula 1: y=-ax-(a/2)*R 2: y=ax-(a/2)*R
        center.y + = (a / 4) * radius;
        if (tex.y < center.y & amp; & amp; tex.y > center.y - (a / 2) * radius)//limit the range to the upper and lower sides of the trapezoid
        {<!-- -->
            tex -= center;
        // inside the trapezoid
            if ((tex.y > (-1 * a * tex.x - a * radius)) & amp; & amp; (tex.y > ( a * tex.x - a * radius)))
            {<!-- -->
            
                tex = tex * Times;
            }
        }
        tex + = center;
float4 outp = g_Tex.Sample(g_SamLinear, tex / v2TexSize); //Get the texture processed by the current magnifying glass
return outp;//output
 

6. Hexagonal magnifying glass

A hexagonal region can be formed by the upper and lower sides + the remaining four hypotenuses:

 //int magnifying_Center_x; //Lens center x coordinate (-100 to 100)
//int magnifying_Center_y; //The y coordinate of the lens center (-100 to 100)
//int magnifying_Radius; //(0 to 100) magnifying glass radius
//int magnifyingl_Times; //(0 to 10) magnification
//v2TexSize is the window size, for example (1920, 1080)
float2 center = float2(0.5 + magnifying_Center_x / 200, 0.5-magnifying_Center_y / 200) * v2TexSize;//Calculate the center point of the magnifying glass
float radius = magnifying_Radius / 100 * v2TexSize.y;//Generally, the window is rectangular, and the short side is selected as the radius expansion factor
float Times = (1 - magnifyingl_Times / 10);//Calculate the magnification factor, the smaller the Times, the greater the magnification
tex *= v2TexSize;//Restore the texture of the range (0-1) to the window size
\t    
        //Using the midpoint of the hexagon as the origin, find the formulas of the other four straight lines
        //1.732=Formula 1 of the other four sides of root number three: y=-ax-a*R 2: y=ax-2*R 3: y=a*x + a*R ,4:y=-a* x + a*R
        float a = sin(PI/3)*2;
       
        if ((tex.y < center.y + radius / 2) & amp; & amp; (tex.y > center.y - radius / 2))//limit the range up and down
        {<!-- -->
            tex -= center;
            radius *=0.6;
            if ((tex.y > (-1. * a * tex.x - a * radius)) & amp; & amp; (tex.y > (a * tex.x - a * radius)) & amp; & amp; (tex.y < (a * tex.x + a * radius)) & amp; & amp; (tex.y < (-1.*a * tex.x + a * radius)))
            {<!-- -->
            
                tex = tex * Times;
            }
            tex + = center;
        }
float4 outp = g_Tex.Sample(g_SamLinear, tex / v2TexSize); //Get the texture processed by the current magnifying glass
return outp;//output


Of course, it can also be realized according to the previous method of drawing triangles. A hexagon is composed of six triangles.

7. Heart-shaped magnifying glass

The core of Heart Magnifier is to create a heart-shaped area.

 //int magnifying_Center_x; //Lens center x coordinate (-100 to 100)
//int magnifying_Center_y; //The y coordinate of the lens center (-100 to 100)
//int magnifying_Radius; //(0 to 100) magnifying glass radius
//int magnifyingl_Times; //(0 to 10) magnification
//v2TexSize is the window size, for example (1920, 1080)
float2 center = float2(0.5 + magnifying_Center_x / 200, 0.5-magnifying_Center_y / 200) * v2TexSize;//Calculate the center point of the magnifying glass
float radius = magnifying_Radius / 100 * v2TexSize.y;//Generally, the window is rectangular, and the short side is selected as the radius expansion factor
float Times = (1 - magnifyingl_Times / 10);//Calculate the magnification factor, the smaller the Times, the greater the magnification
tex *= v2TexSize;//Restore the texture of the range (0-1) to the window size
\t    
        //Love formula ((x*x + y*y-1)^3)=x^2*y^3
        tex -= center; //Take the center as the origin
        if (inHeart(tex, radius) != 0)
        {<!-- -->
            tex *= Times;
        }
        tex + = center;
        float4 outp = g_Tex.Sample(g_SamLinear, tex / v2TexSize);
float inHeart(float2 tex, float size)//Used to judge whether the current point is inside Heart Heart
{<!-- -->
    if (size == 0.)
    {<!-- -->
        return 0;
    }
    tex /= size;
    
    
    float s = tex.x * tex.x - tex.y * -tex.y - 1;
    //Love formula ((x*x + y*y-1)^3)=x^2*y^3
    float f1 = s * s * s;
    float f2 = tex.x * tex.x * tex.y * tex.y * tex.y * -1;
    return step(f1, f2);

}

Effect:

8. Pentagram magnifying glass

The five-pointed star is composed of ten triangles. First, find the coordinates of each point of the ten triangles, and then judge whether the current point is within the ten triangles.
Referenced article: link
code:

 //int magnifying_Center_x; //Lens center x coordinate (-100 to 100)
//int magnifying_Center_y; //The y coordinate of the lens center (-100 to 100)
//int magnifying_Radius; //(0 to 100) magnifying glass radius
//int magnifyingl_Times; //(0 to 10) magnification
//v2TexSize is the window size, for example (1920, 1080)
float2 center = float2(0.5 + magnifying_Center_x / 200, 0.5-magnifying_Center_y / 200) * v2TexSize;//Calculate the center point of the magnifying glass
float radius = magnifying_Radius / 100 * v2TexSize.y;//Generally, the window is rectangular, and the short side is selected as the radius expansion factor
float Times = (1 - magnifyingl_Times / 10);//Calculate the magnification factor, the smaller the Times, the greater the magnification
tex *= v2TexSize;//Restore the texture of the range (0-1) to the window size
   \t\t
float R = radius;//outer pentagon radius
        float r = radius * sin(PI/10.) / cos(PI/5.);//Inner pentagon radius
        float2 PointO[5];//outer pentagon
        float2 PointI[5];//inner pentagon
        
        tex -= center;
   
        for (int i = 0; i < 5; i ++ )
        {<!-- -->
            PointO[i] = float2(R * cos(0.5 * PI + i * 0.4 * PI), -R * sin(0.5 * PI + i * 0.4 * PI));
 PointI[i] = float2(r * cos(0.7 * PI + i * 0.4 * PI), -r * sin(0.7 * PI + i * 0.4 * PI));
            if (inTriangle(float2(0, 0), PointO[i], PointI[i], tex))
            {<!-- -->
                tex *= Times;
            }
            
        }
        if (inTriangle(float2(0, 0), PointO[0], PointI[4], tex))
        {<!-- -->
            tex *= Times;
        }
        
        for (int j = 1; j < 5; j ++ )
        {<!-- -->
            if (inTriangle(float2(0, 0), PointO[j], PointI[j-1], tex))
            {<!-- -->
                tex *= Times;
            }
        }
       tex + = center;
float4 outp = g_Tex.Sample(g_SamLinear, tex / v2TexSize); //Get the texture processed by the current magnifying glass
return outp;//output
        

Effect:

Summary

Shared the implementation methods of seven different shapes of magnifying glasses using HLSL, some of which must have shortcomings, welcome to point out, thank you.