3.Shaping Functions Part.1

3. Shaping Functions Part.1

10. Drawing a circle

10.1 The Cg methons you  really need to know

  • step(edge,n)
  • smoothstep(edge0,edge1,n)
  • clamp(n,min,max)
  • lerp(x,y,a)

We want inCircle to be 1.0 when length(i.position.xy) < 0.25 and 0.0 when is longer.Quad is from (-0.5,0.5,0) to (0.5,0.5,0)

Now caculate the color through specific point :

Black Point:

i.position.xy = float2(-0.5,0)_Point on the middle left

length(i.position.xy) = 0.5_length

step(0.25,0.5) = 1.0_return 1,but we need not yellow here

1.0-step(0.25,0.5)=0 _now black

Yellow Point:

i.position.xy = float2(0,0.1)_Point in circle

length(i.position.xy) = 0.1_length

step(0.25,0.1) = 0_return 0,but we need not black here

1.0-step(0.25,0.1)=1 _now yellow

so shader :

fixed4 frag (v2f i) : SV_Target
{
	float inCircle = 1 - step(0.25, length( i.position.xy ));
  //if just using inCircle will be white because of blue channel
	fixed3 color = fixed3(1,1,0) * inCircle;
	return fixed4(color, 1.0);
}

11. Drawing a square

We will create our own custom function.

Yellow inside Black outside:

float InRect(float2 center,float2 pt,float2 size)
            {
  //pt is pixel point
//center2pt vector
  //return 1 when pos is inside a rectangle defined by size ande center
  //ie. (pt - center) > - halfsize and (pt - center) < halfsize
                float2 p = pt - center;
                float2 halfSize = size/2;
  
                // range : if inside return 1 else 0
                float hor = step(-halfSize,p.x) - step(halfSize,p.x);
                float ver = step(-halfSize,p.y) - step(halfSize,p.y);
                return hor*ver;
  					
  
            }
            fixed4 frag (v2f i) : SV_Target
            {
                float2 center = float2(0,0);
                float2 pt = i.position.xy;
                float2 size = 0.5;
                float inRect = InRect(center,pt,size);
                
                fixed3 color = fixed3(1,1,0) * inRect;
                return fixed4(color, 1.0);
            }
            ENDCG

the most important part:

float2 p = pos - center;Relative position…

float hor = step(-halfSize.x,p.x) - step(halfSize.x,p.x);Inside (-halfSize,halfSize) pixel will be yellow,return 1

And x y code also can simplify our InRect function replacing the hor and ver with a single float2 vector:

// range : if inside return 1 else 0
                // float hor = step(-halfSize.x,p.x) - step(halfSize.x,p.x);
                // float ver = step(-halfSize.y,p.y) - step(halfSize.y,p.y);
                float2 test = step(-halfSize,p) - step(halfSize,p);
                //return hor*ver;
                return test.x * test.y;
  1. You can use the step function more than once in a calculation
  2. If you are testing for the value being less than an edge value, then substract the return value from 1.0.
  3. You can create custom functions that return a value.

12.Moving our shap

12.1 Chanllenge

Make shape:

  • Left of center
  • 0.5 wide
  • 0.25 high
     				fixed4 frag (v2f i) : SV_Target
            {
              //here is changed
                float2 center = float2(-0.25,0);
                float2 pos = i.position.xy;
                float2 size = float2(0.5,0.25);
                float inRect = InRect(center,pos,size);
                
                fixed3 color = fixed3(1,1,0) * inRect;
                return fixed4(color, 1.0);
            }
            ENDCG
        }
    }
}

12.2 Challenge2

Two squares:

  1. Yellow,size 0.3,left of center
  2. Green,size 0.4,right of center
fixed4 frag (v2f i) : SV_Target
            {
                
                float inRectYellow = InRect(float2(-0.25,0),0.3,i.position.xy);
                float inRectGreen = InRect(float2(0.25,0),0.4,i.position.xy);
  //1 + 0 = 1;so use plus
                fixed3 color = fixed3(1,1,0) * inRectYellow + fixed3(0,1,0) * inRectGreen;
                return fixed4(color,1.0);
            }
            ENDCG

13. Moving the square with mouse??

Texture coordinates for the Quad is from (0,0) to (1,1).

这里很奇怪,好像是说uv是从0到1,但是顶点的位置是-0.5到+0.5还蛮奇怪的,后面的课程应该会讲吧

How to move:

Just square center follow let mouseposition.

public class TrackMouse : MonoBehaviour
{
    Material material;
    Vector4 mouse;
    //Camera camera;

    // Start is called before the first frame update
    void Start()
    {
        Renderer rend = GetComponent<Renderer>();
        material = rend.material;
        
        mouse = new Vector4();
        mouse.z = Screen.height;
        mouse.w = Screen.width;
        
        //camera = Camera.main;
    }

    // Update is called once per frame
    void Update()
    {
        RaycastHit hit;
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray,out hit))
        {
          //textureCoord命中的纹理坐标
            mouse.x = hit.textureCoord.x;
            mouse.y = hit.textureCoord.y;
        }
        material.SetVector("_Mouse", mouse);
    }
}

Use material.SetVector("_Mouse",mouse);Change value _Mouse of Shader

//shader: change center place
fixed4 frag (v2f_img i) : SV_Target
            {
                float2 pos = i.uv;
                float2 size = 0.2;
                //_Mouse.xy = 0.1;
                float inrect = InRect(_Mouse.xy,pos,size);
                fixed3 color = fixed3(1,1,0) * inrect;
                return fixed4(color,1.0);
            }
            ENDCG

14. Moving the shape over time

  • Use the uniform -_Time
  • Plus the trig functions : sin and cos

Use the charecter sin^2+cos^2 = 1 to make a circle moving

float2 center = float2(cos(_Time.y),sin(_Time.y)) * _Radius;

and use time.w

15. Rotating the square

Now we will make square rotate itself around center:

float2x2(c,-s,s,c)

15.1 Using the mul function

If you multiply in a matrix by a vector then the matrix is the first parameter and the vector is the second.

15.2 if pixel is in the rotated square(解决)

float2 pt = mul(mat,pos)

float2x2 getRotationMatrix(float theta)
            {
                float s = sin(theta);
                float c = cos(theta);
                return float2x2(c,s,-s,c);
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float2 center = float2(0, 0);
                float2 pos = i.position * 2.0;
                float2 size = _Size;
                float2x2 mat = getRotationMatrix(_Time.y);
              
                float2 pt = mul(mat,pos);//new texture pos
                  
                float3 color = _Color * rect(pt, size, center);
                
                return fixed4(color, 1.0);
            }
            ENDCG
        }

如果要换中心旋转,那么就要先将pos减去center,做一个相对旋转,然后再加上center。

How to rotate(self) about a point :

float2 pt = mul(mat,pos-center) + center;

这里如果不懂的话,就得想到Games101了。

因为旋转和缩放是线性变换,我们构造旋转矩阵和缩放矩阵的时候都是针对原点来构造的,所以需要先把该点平移到原点,然后旋转,缩放,再平移回去。

15.3 Summary

  • Trig functions, sin and cos take radian parameters.
  • There are 2pie(6.28) radians in a full revolution
  • You can create a matrix using float2x2,float3x3,float4x4
  • In this course all matrices are square
  • You can multiply a float2x2 by a float2,float3x3 by a float3,float4x4 by a float4

16. Changing the rotation centre and scaling

Now we want the rectangle to rotate around one of its corners.

如果正方形长宽都是0.3,那么就是(-0.15,-0.15)to (0.15,015)

计算的时候,也就是通过相对锚点的halfsize来限制。

16.1 Anchor

Add anchor variable:

拆解锚点,旋转之前将锚点移到原点,所以每一帧绘制的时候都要将锚点移到原点,这样才能确定该点的颜色。

float rect(float2 pt, float2 size, float2 center,float2 anchor){
                //return 0 if not in rect and 1 if it is
                //step(edge, x) 0.0 is returned if x < edge, and 1.0 is returned otherwise.
                float2 p = pt - center;
                float2 halfsize = size/2.0;
                //也是一个相对关系,添加了都减去anchor
                float horz = step(-halfsize.x - anchor.x, p.x) - step(halfsize.x-anchor.x, p.x);
                float vert = step(-halfsize.y - anchor.y, p.y) - step(halfsize.y - anchor.y, p.y);
                return horz*vert;
            }

16.2 Scale

when scale =  1

[ 1 0 0 1 ] \begin{bmatrix} 1&0\\ 0&1\\ \end{bmatrix} [1001]

when scale  = 2

[ 2 0 0 2 ] \begin {bmatrix} 2&0\\ 0&2\\ \end{bmatrix} [2002]

How to change the scale :

float2x2 getScaleMatrix(float scale)
            {
                
                return float2x2(scale,0,0,scale);
            }
fixed4 frag (v2f i) : SV_Target
            {
                float2 center = float2(0.5, 0);
                float2 pos = i.position * 2.0;
                float2 size = _Size;
                float2 anchor = _Anchor.xy;
                
                float2x2 matr = getRotationMatrix(_Time.y);
                float2x2 mats = getScaleMatrix(sin(_Time.y)/2 + 1);
                
                float2x2 mat = mul(matr,mats);
                float2 pt = mul(mat,pos-center) + center;
                
                  
                float3 color = _Color * rect(pt, size, center,anchor);
                
                return fixed4(color, 1.0);
            }
            ENDCG

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值