Interpretation of the shader Series 4 Written by CG in unity -- the shader with rounded corners in Unity

Source: Internet
Author: User

In the previous article, we learned the surface removal and cropping modes.

This article will use this knowledge to implement a simple, but not frequently used example: make an image into a rounded rectangle


Example 3: shader with rounded corners

Well, I admit that I had taken a lot of detours in this example, because I have completely mastered the matrix and returned it to the teacher, so I started to use some stupid methods to calculate the rounded rectangle area.

We know that textcoord0 is an object-based coordinate system, and its range is in the first quadrant of the coordinate system. The value ranges from (0, 0))

Then we will regard each image as a rectangle of 1x1 size.

We need to erase four corners in a rectangle of the size of 1x1, which should be like this:


Take the upper left corner as an example. If we make an auxiliary circle to cut into this angle and the radius is 0.1, We will erase this circle by 3/4, the remaining area formed by the yellow arc and the angle is the area to be erased:


This principle is very easy, so we can erase the four corners to get a rounded rectangle with a radius of 10%.


The first detour I took was to calculate the region. Do I use a four-circle equation or a distance to calculate it?


Because the equation for giving four circles is too complicated, I will directly give the algorithm for calculating the outer distance:



First, an inner rectangle is made based on four centers in the inside of the large rectangle. The side length of the heart is 0.8.

Second, ignore the points inside the rectangle. In this red rectangle, given a random outer point P of the blue rectangle, we only need to get the distance between P and the blue rectangle, with a distance greater than 0.1 (RADIUS ), in this case, the image is erased directly outside the rounded rectangle ,:


We can see that the distance between P1, P2, P3 and the blue rectangle is respectively the <radius, 2 times radius of the root number> P2 distance> radius, and the P3 distance is equal to the radius.

So P2 is outside the rounded rectangle, P1 and P3 are inside or at the edge of the rounded rectangle, So we erase P2.

The distance between P3 is exactly the minimum distance from P3 to four straight lines.

Similarly, p1

The P2 distance cannot be calculated in this way, but it should be the minimum value of the distance from p2 to four vertices.



Based on this algorithm, we only need to calculate the distance from all the external points to the area of the blue rectangle, and then infer the size from the radius. If it is greater than the radius, we can get the rounded rectangle.


At first, I came up with an extremely brainless method based on this idea:


Given a random point of P, calculate the distance between P and four straight lines and four vertices, and then calculate the minimum value among the eight distances as the final distance to compare it with the half-width ratio.


I was excited to write the code and I knew I was wrong. After checking it for a long time, it was clear that the minimum distance between the eight points such as P3 is not the distance from the vertex, but the distance to the extended line of the two sides.


So the algorithm for finding the minimum value at the distance of 8 finally ended in failure.


Still have to be honest

So there are several situations.

In fact, there is only one type, but there are two types based on the normal logic:


Let's take a look at the external points of the green and purple regions.

1. When the external point is in the purple area, the distance should be the minimum distance from the point to the 4 Vertex

2. When the external point is in the green area, the distance should be the minimum distance from the point to the four straight lines

Based on this idea, we can infer arbitrary points (x, y) in the whole coordinate system:

1. If you want to calculate the wool distance in the white or green area, it is definitely not discard ~~~~ (I did it before)


2. Calculate the distance from vertex 4 in the purple area, take the minimum value, and remove the part greater than 0.1.


Finally, we need to extract the 0.1 as a variable, so that it cannot be written to death. This can be easily adjusted in inspector or set in script, that is, to define a float or rang attribute for our shader.


The final code is:


Shader "Custom/roundrect" {properties {// two content modes: image mode _ maintex ("base (RGB)", 2d) = "white" {} // solid color mode // _ maincolor ("color", color) = (,) // the radius of the rounded corner, which is 0.20.roundradius ("radius ", float) = 0.1} subshader {pass {cgprogram # pragma fragment frag # include "unitycg. cginc "// obtain the three attributes and pass the values to the CG code snippet sampler2d _ maintex; float _ roundradius; float4 _ maincolor; // The input struct of the fragment shader (omitted) struct fraginput {float2 texcoord: texcoord0 ;}; // fragment iterator Function float4 frag (fraginput input): Color {float4 c = tex2d (_ maintex, input. texcoord); // convert the image information into colors by coordinate conversion. // float4 c = _ maincolor; // solid color // X and Y, the interval is [0, 1] float x = input. texcoord. x; float y = input. texcoord. y; // float XT = 1-_ roundradius; float XB = _ roundradius; float yl = _ roundradius; float yr = 1-_ roundradius; // assume that (X, Y) is not in the white area of the rectangle composed of four straight lines. If (! (X <XT & x> XB & Y> yl & Y <yr) {// assume that (x. y) is not in the green region if (! (X <XT & x> xb) | (Y> yl & Y <yr) // it seems that the inference is complicated due to poor mathematics, assuming that you can directly write the purple region // inequality group, then you can simply {// calculate the coordinates of the four vertices float2 PLB = float2 (_ roundradius, _ roundradius ); float2 PLT = float2 (_ roundradius, 1-_ roundradius); float2 PRT = float2 (1-_ roundradius, 1-_ roundradius); float2 PRB = float2 (1-_ response, _ roundradius); // calculate the distance from X, Y to four vertices respectively float distlb = SQRT (POW (x-plb.x), 2) + POW (y-plb.y ), 2); float distlt = SQRT (POW (x-plt.x), 2) + POW (y-plt.y), 2); float distrt = SQRT (POW (x-prt.x ), 2) + POW (y-prt.y), 2); float distrb = SQRT (POW (x-prb.x), 2) + POW (y-prb.y), 2 )); // take the minimum float Dist = min (distlb, distlt) for the four distances; Dist = min (Dist, distrt); Dist = min (Dist, distrb ); // remove the IF (Dist> _ roundradius) discard;} return C;} endcg} fallback "diffuse "}


The final result is to remove the rounded rectangle of images of different radius sizes.


When the radius is set to 0.25, we can get a circle, so our roundradius attribute can be set to 0.01 ~ Rang of 0.25


Because I am a Windows system, there seems to be a problem in Mac OS. I don't know if the problem of vertex coloring is omitted. I will fix it again after finding the cause.



If my blog is helpful to you or you have any questions, you are welcome to add the Chongqing U3D communication QQ group. I will give you a question: 68994667. You can also join the group to discuss the technology with us.

Interpretation of the shader Series 4 Written by CG in unity -- the shader with rounded corners in Unity

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.