unity shader 绘制钟表

2020-09-22 10:52发布

1:效果图如下

2:shader代码如下:

Shader "Unlit/clock"

{

Properties

{

_MainTex ("Texture", 2D) = "white" {}

hors("hors",int) = 13

mins("mins",int) = 30

secs("secs",int) = 30

mils("mils",int) = 30

}

SubShader

{

Tags { "RenderType"="Opaque" }

LOD 100

Pass

{

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

struct appdata

{

float4 vertex : POSITION;

float2 uv : TEXCOORD0;

};

struct v2f

{

float2 uv : TEXCOORD0;

float4 vertex : SV_POSITION;

};

sampler2D _MainTex;

float4 _MainTex_ST;

int hors;

int mins;

int secs;

int mils;

float lerpLine(float2 _LP1,float2 _LP2,float2 pos,float width) {

if(dot(pos - _LP1, _LP2- _LP1)>=0)

{

float d = 1;

d = abs((_LP2.y - _LP1.y)*pos.x + (_LP1.x - _LP2.x)*pos.y + _LP2.x*_LP1.y - _LP2.y*_LP1.x) / sqrt(pow(_LP2.y - _LP1.y, 2) + pow(_LP1.x - _LP2.x, 2));

if (d < width)

{

return min(1, abs(width - d) / width*2);

}

else {

return 0;

}

}

else {

return 0;

}

}

fixed3 backColor(float2 uv)

{

fixed3 nightColor = fixed3(0.2, 0.2, 0.2) + 0.1*uv.y;

fixed3 dayColor = fixed3(0.5, 0.6, 0.7) + 0.2*uv.y;

fixed3 col = lerp(nightColor, dayColor, smoothstep(5.0, 7.0, hors) -

smoothstep(19.0, 21.0, hors));

return col;

}

fixed3 drawCircle(float2 uv,float2 pos,float radio, float radio1,float width, float width1) {

float dis = distance(uv, pos);

//时针 分针 秒针

if (dis >= radio1 + width1)

{

float3 col = lerp(fixed3(0, 0, 0), fixed3(1, 1, 1), min(1, (radio - dis) * 200));

int hor = hors % 12;

float hor_angle = (90.0 - 30.0 * hor - mins / 600.0) / 57.29578;

float min_angle = (90.0 - mins*6 - secs/60.0) / 57.29578;

float sec_angle = (90.0 - secs * 6) / 57.29578;

if (dis < 0.15)

{

//时针

float lerpV = lerpLine(pos, float2(0.15*cos(hor_angle) + pos.x, 0.15*sin(hor_angle) + pos.y), uv, 0.005);

if(lerpV>0)

return lerp(col, float3(0, 0, 0), lerpV);

}

if (dis < 0.25)

{

//分针

float lerpV = lerpLine(pos, float2(0.25*cos(min_angle) + pos.x, 0.25*sin(min_angle) + pos.y), uv, 0.005);

if (lerpV > 0)

return lerp(col, float3(0, 0, 0), lerpV);

}

if (dis < 0.35)

{

//秒针

float lerpV = lerpLine(pos, float2(0.35*cos(sec_angle) + pos.x, 0.35*sin(sec_angle) + pos.y), uv, 0.002);

if (lerpV > 0)

return lerp(col, float3(1, 0, 0), lerpV);

}

}

if (dis < radio1) {

//内圈里

return lerp(fixed3(0, 0, 0),fixed3(0.75, 0.75, 0.75),(radio1 - dis)*500);

}

else if(dis< radio1 + width1){

//内圈边

return lerp(fixed3(0, 0, 0),fixed3(1, 1, 1),max(0,1/(radio1 + width1 - dis)*0.0008));

}

else {

float3 col = lerp(fixed3(0, 0, 0), fixed3(1, 1, 1), min(1, (radio - dis) * 200));

if (dis <= radio)

{

//外圈里

if (dis >= radio - 0.08)

{

//刻度

float2 direction = uv - pos;

float angle = acos(dot(normalize(direction), float2(1, 0)));

float angle_d = angle * 57.29577 % 30;

if (angle_d < 0.6 || angle_d>29.4)

{

//刻度长针

if (dis >= radio - 0.06)

{

if (angle_d <1)

{

return lerp(col, fixed3(0, 0, 0), min(1, (0.6 - (abs(angle_d))) / 0.5));

}

else {

return lerp(col, fixed3(0, 0, 0), min(1, ((abs(angle_d) - 29.4)) / 0.5));

}

}

}

else {

//刻度短针

if (dis >= radio - 0.04)

{

float angle_d1 = angle * 57.29577 % 6;

if (angle_d1<0.4 || angle_d1>5.6)

{

if (angle_d1 < 0.4)

{

return lerp(col,fixed3(0, 0, 0), min(1, (0.4- angle_d1) / 0.5));

}

else {

return lerp(col,fixed3(0, 0, 0), min(1, (angle_d1 - 5.6) / 0.5));

}

}

}

}

}

return col;

}

else if (dis >= radio && dis < radio + width)

{

//外圈边

return fixed3(0, 0, 0);

}

else {

//外圈外

return lerp(fixed3(0, 0, 0), backColor(uv), min(1, (dis - radio - width) * 200));

}

}

}

v2f vert (appdata v)

{

v2f o;

o.vertex = UnityObjectToClipPos(v.vertex);

o.uv = TRANSFORM_TEX(v.uv, _MainTex);

return o;

}

fixed4 frag (v2f i) : SV_Target

{

// sample the texture

fixed3 col = drawCircle(i.uv,float2(0.5,0.5),0.4,0.02,0.013,0.01);

return fixed4(col,0);

}

ENDCG

}

}

}

3:unity代码如下:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class clock : MonoBehaviour

{

public Material mat;

public int Hour = 0;

public int Minute = 0;

public int Second = 0;

// Start is called before the first frame update

void Start()

{

mat.SetInt("hors", Hour);

mat.SetInt("mins", Minute);

mat.SetInt("secs", Second);

}

// Update is called once per frame

void Update()

{

if(System.DateTime.Now.Hour!= Hour)

{

Hour = System.DateTime.Now.Hour;

mat.SetInt("hors", Hour);

}

if (System.DateTime.Now.Minute != Minute)

{

Minute = System.DateTime.Now.Minute;

mat.SetInt("mins", Minute);

}

if (System.DateTime.Now.Second != Second)

{

Second = System.DateTime.Now.Second;

mat.SetInt("secs", Second);

}

}

}

本人qq:344810449,欢迎探讨研究。

有unity,shader,小程序等需求也可以联系本人,非常乐于助人。

如果觉得还不错给博主来个小惊喜,纯属自愿,不强求:



作者:unity游侠

链接:https://blog.csdn.net/y90o08u28/article/details/107099946

来源:CSDN
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。