Unity&Shader基礎篇-常用函式的使用與案例
阿新 • • 發佈:2019-01-30
程式碼中使用到了“_Time”變數,這個是Unity內建的四維向量,(t/20,t,t*2,t*3)因此“_Time.y=t”即獲得系統的渲染的單位時間。Shader "Unlit/Chapter6-Animations" { Properties { _SpeedY("第一部分的速度",Range(0,3)) = 1 _Amplitude("第二部分的振幅",Range(0,1)) = 0.8 _RSpeedX("圓周運動X方向的速度",Range(0,10)) = 5 _RSpeedY("圓周運動Y方向的速度",Range(0,10)) = 5 _RAmplitudeY("圓周運動Y方向的幅度",Range(0,1)) = 0.1 _RAmplitudeX("圓周運動X方向的幅度",Range(0,1)) = 0.1 _ChainAnimSpeed("鏈條運動的速度",Range(0,10)) = 5 _ChainAnimRotaSpeed("鏈條運動的旋轉速度",Range(0,10)) = 3 _JumpSpeed("跳躍運動的速度",Range(0,10))=2 } SubShader { // No culling or depth Cull Off ZWrite Off ZTest Always CGINCLUDE #define PI 3.1415926 // 通過函式來畫網格 float coordinateGrid(float2 r) { float3 axisCol = float3(0.0, 0.0, 1.0); float3 gridCol = float3(0.5, 0.5, 0.5); float ret = 0.0; // 畫網線 const float tickWidth = 0.1; for (float i = -2.0; i<2.0; i += tickWidth) { ret += 1.0 - smoothstep(0.0, 0.008, abs(r.x - i)); ret += 1.0 - smoothstep(0.0, 0.008, abs(r.y - i)); } // 畫座標軸 ret += 1.0 - smoothstep(0.001, 0.015, abs(r.x)); ret += 1.0 - smoothstep(0.001, 0.015, abs(r.y)); return ret; } // 圓內的返回1 float disk(float2 r, float2 center, float radius) { return 1.0 - smoothstep(radius - 0.005, radius + 0.005, length(r - center)); } // 在長方形內返回1 float rectangle(float2 r, float2 bottomLeft, float2 topRight) { float ret; float d = 0.005; ret = smoothstep(bottomLeft.x - d, bottomLeft.x + d, r.x); ret *= smoothstep(bottomLeft.y - d, bottomLeft.y + d, r.y); ret *= 1.0 - smoothstep(topRight.y - d, topRight.y + d, r.y); ret *= 1.0 - smoothstep(topRight.x - d, topRight.x + d, r.x); return ret; } float mod(float a, float b) { return a - b*floor(a / b); } ENDCG Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" uniform float _Amplitude; uniform float _SpeedY; uniform float _RSpeedX; uniform float _RSpeedY; uniform float _RAmplitudeY; uniform float _RAmplitudeX; uniform float _ChainAnimSpeed; uniform float _ChainAnimRotaSpeed; uniform float _JumpSpeed; struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; v2f vert(appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = v.uv; o.uv.y = 1 - o.uv.y; return o; } //動畫,使用到了Unity內建的變數_Time 四維向量(t/20, t, t*2, t*3),_Time.y=t; fixed4 frag(v2f i) : SV_Target { float2 r = 2.0 * (i.uv - 0.5); float aspectRatio = _ScreenParams.x / _ScreenParams.y; r.x *= aspectRatio; fixed3 bgCol = float3(1.0, 1.0, 1.0); // white fixed3 col1 = float3(0.216, 0.471, 0.698); // blue fixed3 col2 = float3(1.00, 0.329, 0.298); // red fixed3 col3 = float3(0.867, 0.910, 0.247); // yellow fixed3 ret; ret = bgCol; //第一部分,迴圈向上運動 if (i.uv.x < 1.0 / 5.0) { float2 q = r + float2(aspectRatio*4.0 / 5.0, 0); ret = fixed3(0.3, 0.3, 0.3); //unity內建的時間向量 float y = _SpeedY*_Time.y; //使得y在-1到1之間 y = mod(y,2.0) - 1.0; ret = lerp(ret, col1, disk(q, float2(0.0, y), 0.1)); } //第二部分,迴圈來回並縮放運動 else if (i.uv.x < 2.0 / 5.0) { float2 q = r + float2(aspectRatio*2.0 / 5.0, 0); ret = fixed3(0.4, 0.4, 0.4); //新增振幅 float y = _Amplitude * sin(0.5*_Time.y* 2.0 * PI); float radius = 0.15 + 0.05 * sin(_Time.y * 8.0); ret = lerp(ret, col1, disk(q, float2(0.0, y), radius)); } //第三部分,圓周運動並變換顏色 else if (i.uv.x < 3.0 / 5.0) { float2 q = r + float2(aspectRatio * 0 / 5.0, 0); ret = float3(0.5, 0.5, 0.5); float x = _RAmplitudeX*cos(_Time.y*_RSpeedX); float y = _RAmplitudeY*sin(_Time.y*_RSpeedY); float radius = 0.2 + 0.1*sin(_Time.y*2.0); fixed3 color = lerp(col1, col2, sin(_Time.y)*0.5 + 0.5); ret = lerp(ret, color, rectangle(q, float2(x - 0.1, y - 0.1), float2(x + 0.1, y + 0.1))); } //第四部分,鏈條運動 else if (i.uv.x < 4.0 / 5.0) { float2 q = r + float2(-aspectRatio*2.0 / 5.0, 0); ret = float3(0.4, 0.4, 0.4); for (float i = -1.0; i<1.0; i += 0.2) { float x = 0.2 * cos(_Time.y*_ChainAnimSpeed + i*PI); float y = i; float2 s = q - float2(x, y); float angle = _Time.y * _ChainAnimRotaSpeed + i; float2x2 rot = float2x2(cos(angle), -sin(angle), sin(angle), cos(angle)); s = mul(rot, s); ret = lerp(ret, col1, rectangle(s, float2(-0.06, -0.06), float2(0.06, 0.06))); } } //第五部分,跳躍運動 else if (i.uv.x < 5.0 / 5.0) { float2 q = r + float2(-aspectRatio*4.0 / 5.0, 0); ret = float3(0.3, 0.3, 0.3); float speed = _JumpSpeed; float t = _Time.y * speed; float stopEveryAngle = PI / 2.0; float stopRatio = 0.5; //floor(x):返回小於等於t的最大整數 frac(x):返回x的小數部分 float t1 = (floor(t) + smoothstep(0.0, 1.0 - stopRatio, frac(t)))*stopEveryAngle; float x = -0.2*cos(t1); float y = 0.3 * sin(t1); float dx = 0.1 + 0.03 * sin(t*10.0); float dy = 0.1 + 0.03 * sin(t*10.0 + PI); ret = lerp(ret, col1, rectangle(q, float2(x - dx, y - dy), float2(x + dx, y + dy))); } fixed3 pixel = ret; return fixed4(pixel, 1.0); } ENDCG } } }
2、等離子流動效果,效果圖如圖所示: