3. Shaping Functions Part.2

3. Shaping Functions Part.2

17. Tiling

17.1 From pos to uv

Before we continue, we are going to switch our code to use the UV value for the Quad rather than the position value.

From the lower left and the top right:

Recall that uv is

( 0 , 0 ) − > ( 1 , 1 ) (0,0) ->(1,1) (0,0)>(1,1)

Whereas position is

( − 0.5 , − 0.5 ) − > ( 0.5 , 0.5 ) (-0.5,-0.5)->(0.5,0.5) (0.5,0.5)>(0.5,0.5)

Ajudsting position values

float2 pos = i.position.xy + 0.5

所以i.uv 可以完全将pos替换,float2 pos = i.position *2

完全可以变成float2 pos = i.uv

如何用UV表示pos呢?让中心变成(0.5,0.5)

17.2 The frac function

float frac(float v)
{
//floor 会向下取值
//结果返回小数部分
	return v - floor(v);
}

when we use i.uv*6 then we have 6 box(0,0) to (1,1) in x,6 in y

shader 的frag改成:

float2 pos = frac(i.uv*_TileCount);

17.3 Summary

  • Quad model coordinates are in the range -0.5 to 0.5
  • Texture coordinates are in the range 0 to 1
  • Tiling needs the coordinate space 0 to 1 to work best

18. Drawing circles

First we want to draw a circle,which we can choose shapen edge or not:

//paint circle
            float circle(float2 pos,float2 center,float radius,float smoothvalue,bool isShapen)
            {
                float2 pt = pos - center;
                //shapen
                float2 shapen = 1 - step(radius,length(pt));
              	//blur
                float2 blur = 1 - smoothstep(radius - smoothvalue,radius + smoothvalue,length(pt));
                return isShapen? shapen :  blur;
            }

fixed4 frag (v2f i) : SV_Target
            {
                float2 pos = i.position * 2;
                float2 center = float2(0,0);
                float radius  = _Radius;
                float smoothValue = _SmoothStep;
  //here is choice
                fixed3 color = _Color * circle(pos,center,radius,smoothValue,false);

                return fixed4(color, 1.0);
            }

Now we want to draw a circle ring:

Same as we made in square shader.

//circle ring
            float circle(float2 pos,float2 center,float radius,float line_width)
            {
                float2 pt = pos - center;
                float2 len = length(pt);
                float2 half_line_width = line_width/2;
                //ring
                float in_ring = step(radius-half_line_width,len) - step(radius+half_line_width,len);
                return in_ring;
            }

fixed4 frag (v2f i) : SV_Target
            {
                float2 pos = i.position * 2;
                float2 center = float2(0,0);
                float radius  = _Radius;
                float smoothValue = _SmoothStep;
  //here is ring paint
                fixed3 color = _Color*circle(pos,center,radius,_LineWidth);
                return fixed4(color, 1.0);
            }

19.Drawing lines

19.1 How to paint a line

What we are going to do:

  • To draw a line on screen we will create a function.
    float online(float a,float b,float line_width,float edge_thickness)
  • Return 1 if pixel is on the line else 0.
  • It is on the line when b is between a+ and -half the line width.
  • Use smoothStep in this test.
  • We will add + and - edge_thickness to the test.

So shader :

 struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv: TEXCOORD0;
                float4 position: TEXCOORD1;
                float4 screenPos: TEXCOORD2;
            };
            
            v2f vert (appdata_base v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.position = v.vertex;
                o.uv = v.texcoord;
                //use for screen
                o.screenPos = ComputeScreenPos(o.vertex);
                return o;
            }
           
            fixed4 _Color;
            float _LineWidth;
            
            float getDelta( float x ){
            	return (sin(x) + 1.0)/2.0;
            }
            //a and line_width for limite
            // b is value 把b包围在a的范围内
            //edge_thickness control edge blur
            float online(float a,float b,float line_width,float edge_thickness)
            {
                float half_line_width = line_width * 0.5;
                 return smoothstep(a - half_line_width -edge_thickness,a - half_line_width,b)
                        - smoothstep(a + half_line_width,a + half_line_width + edge_thickness,b);
            }
            fixed4 frag (v2f i) : SV_Target
            {
            	// //以屏幕UV为原点
             //    float2 uv = i.screenPos.xy / i.screenPos.w;//?这是屏幕uv为原点
            	// //把y限定在x的某个范围内
             //    fixed3 color = lerp(fixed3(0,0,0),_Color.rgb,online(uv.x,uv.y,_LineWidth,_LineWidth*0.1));

                // //以纹理UV为原点
                // float2 uv1 = i.uv;
                // fixed3 color = lerp(fixed3(0,0,0),_Color.rgb,online(uv1.x,uv1.y,_LineWidth,_LineWidth*0.1));
                
                 //以pos中心为原点
                float2 pos = i.position.xy * 2;
                fixed3 color = lerp(fixed3(0,0,0),_Color.rgb,online(sin(pos.x*UNITY_PI*2)/2,pos.y,_LineWidth,_LineWidth*0.1));
                return fixed4(color, 1.0);
            }
            ENDCG

19.2 three different methon

原点相对位置:

  1. 以屏幕UV为原点,这时候需要坐标变换
 fixed4 frag (v2f i) : SV_Target
            {
            	//以屏幕UV为原点
              float2 uv = i.screenPos.xy / i.screenPos.w;//这是Screen uv为原点
            	//把y限定在x的某个范围内
                fixed3 color = lerp(fixed3(0,0,0),_Color.rgb,online(uv.x,uv.y,_LineWidth,_LineWidth*0.1));

                
                return fixed4(color, 1.0);
            }
  1. 以纹理UV为原点
 fixed4 frag (v2f i) : SV_Target
            {
                 //以纹理UV为原点
                 float2 uv1 = i.uv;//uv
                 fixed3 color = lerp(fixed3(0,0,0),_Color.rgb,online(uv1.x,uv1.y,_LineWidth,_LineWidth*0.1));
                return fixed4(color, 1.0);
            }
  1. 以pos中心为原点
 fixed4 frag (v2f i) : SV_Target
            {
                 //以pos中心为原点
                float2 pos = i.position.xy * 2;//pos
                fixed3 color = lerp(fixed3(0,0,0),_Color.rgb,online(sin(pos.x*UNITY_PI*2)/2,pos.y,_LineWidth,_LineWidth*0.1));
                return fixed4(color, 1.0);
            }

19.3 Lerp func

Same as  lerp(color1,color2,delta)

float lerp(a,b,n)
{
	if(n < 0)
    return a;
  else if (n > 1)
    return b;
  else 
    return1 - n)*a + n*b;
}

20.Combining lines

20.1 How to add line:

In last course, we know how to draw a line.Now we use the function,just notice b is limited in a.

20.2 Dot

dot(a,b)把a投影到b。

20.3 clamp

clamp(v,min,max) 钳制函数。

20.4 a trailing edge

扫描函数目的:shader18

  1. 画一个扫描线——通过测试点到sweep线的距离和半径来判断
  2. 扫描线后有拖尾——通过半径和测试点到线的角度来判断

所有的画图都是通过像素来进行的,找到真正需要画的地方,然后对比目前的测试点是不是要画的点,是的就涂色,不是就不涂。

  • 为什么p是(cos,-sin)而不是(cos,sin)?
  • 投影系数是用来限制测试长度内部的点,
  • 拖尾定义了最大颜色角度,拖尾角度,怎么画出拖尾?
float sweep(float2 pt, float2 center, float radius, float line_width, float edge_thickness)
{
                float2 d = pt - center;//目前测试点得到的向量
                float theta = _Time.z;
                
                //从-sin增加就是顺时针,从x轴正方形开始顺时针,sin函数默认增大是逆时针旋转
                float2 p = float2(cos(theta), -sin(theta))*radius;//根据时间得到的方向和长度,此时真正需要画出来的sweepline
                float h = clamp( dot(d,p)/dot(p,p), 0.0, 1.0 );//投影系数  
                //float h = dot(d,p)/dot(p,p);
                float l = length(d - p*h);//目的是找到距离sweepline最近的那些测试点,画出来

                //trail func
                float gradient = 0.0;
                const float gradient_angle = UNITY_PI * 0.5;//最大拖尾角度
  
                if(length(d) < radius)//在半径范围内的点才进入测试
                { 
                    float angle = fmod(theta + atan2(d.y,d.x),UNITY_TWO_PI);//拖尾角度
                    //按角度大小颜色衰减,角度越大衰减越大。这里加到颜色上面不影响,因为除了线上其他地方都是0
                    gradient = clamp(gradient_angle - angle,0.0,gradient_angle)/gradient_angle * 1;
                }
                return gradient + 1.0 - smoothstep(line_width, line_width+edge_thickness, l);//距离越小越要画出来
            }

20.5 Atan2

Atan2(y,x) return angle(其实是弧度制)

20.6 Summary

  • fmod  returns the remainder after division返回余数
  • Clamp restricts a value to a range
  • Create a table of values if the results are not as expected

21.Showing a polygon

21.1 Is the test point insdie the polygon?

Consider a triangle with the hypotenuse being the line from the center to the polygon corner.

21.2 Which corner for our test?

Deciding which corner to use for our test depending on the test point.

Shader22:

float polygon(float2 pt, float2 center, float radius, int sides, float rotate, float edge_thickness)
{
                pt -= center;

                // Angle and radius from the current pixel
                float theta = atan2(pt.y, pt.x) + rotate;
                float rad = UNITY_TWO_PI/float(sides);

                // Shaping function that modulate the distance
                float d = cos(floor(0.5 + theta/rad)*rad-theta)*length(pt);//the most important formula in this func

                return 1.0 - smoothstep(radius, radius + edge_thickness, d);
            }

22.Creating a brick pattern

22.1 Draw a brick:砖块

float brick(float2 pt, float mortar_height, float edge_thickness)
{
                if (pt.y>0.5) pt.x = frac(pt.x + 0.5);//将两个边缘的竖边拉到中间
                
                float half_mortar_height = mortar_height/2.0;
                //可以当成一块的图片来分析
                //Draw bottom line
                float result = 1 - smoothstep(half_mortar_height, half_mortar_height + edge_thickness, pt.y);
                //Draw top line —— 将1当成是上限
                result += smoothstep(1.0 - half_mortar_height - edge_thickness, 1.0 - half_mortar_height, pt.y);
                //Draw middle line —— 将0.5当成是上边
                result += smoothstep(0.5 - half_mortar_height - edge_thickness, 0.5 - half_mortar_height, pt.y) - smoothstep(0.5 + half_mortar_height, 0.5 + half_mortar_height + edge_thickness, pt.y);
                //Draw vertical lines —— 左右的竖线
                result += smoothstep(-half_mortar_height - edge_thickness, -half_mortar_height, pt.x) - smoothstep(half_mortar_height, half_mortar_height + edge_thickness, pt.x) + smoothstep(1.0-half_mortar_height-edge_thickness, 1.0-half_mortar_height, pt.x);
                
                return result;
                
}

22.2 SmoothStep Func more

Now we create smoothstep(a,a+edge_thickness,v)

When v < a return 0, v > a+edge_thickness return 1.

Take care edge_thickness,which is actually a extremly small number.

So we can regard range from a to a+edge_thickness as just one boundary with thickness,like step with no thickness,one side is 0 the other side is 1.

In the range of a and a+edge_thickness, the number is blendered.

22.3 Test record

A property value that is a Vector type can be defined as which Cg type?

——float4

Which option would result in a 6x6 grid?

——frac(i.uv * 6)

——frac(i.position*6) 可能因为position这里是指vertex值是唯一的,但是uv是可以变化的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值