unity时钟着色器(附代码)

先看效果:

大致思路:先绘制矩形,旋转UV达到转动效果,极坐标转换绘制刻度。

graph节点:

着色器代码:

Shader "CustomURP/TimeText"
{
	Properties
	{
		_Secondsdeg("Secondsdeg",float) = 0
		_Minutesg("Minutesg",float) = 0
		_Hourdeg("Hourdeg",float) = 0
	}
	SubShader
	{
		tags{"RenderType"="Opaque" "RenderPipeline"="UniversalPipeline"}
		
		Pass
		{
			HLSLPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
			
			struct Attributes
			{
				float3 positionOS:POSITION;
				half2 uv:TEXCOORD0;
			};
			
			struct Varyings
			{
				float4 positionHCS:SV_POSITION;
				half2 uv:TEXCOORD0;
			};			
			
			CBUFFER_START(UnityPerMaterial)		
				float _Secondsdeg;
				float _Minutesg;
				float _Hourdeg;
			CBUFFER_END

			void Unity_Rotate_Radians_float(float2 UV, float Rotation, out float2 Out) //旋转
			{
				float2 Center = float2(.5, .5);
				UV -= Center;
				float s = sin(Rotation);
				float c = cos(Rotation);
				float2x2 rMatrix = float2x2(c, -s, s, c);
				rMatrix *= 0.5;
				rMatrix += 0.5;
				rMatrix = rMatrix * 2 - 1;
				UV.xy = mul(UV.xy, rMatrix);
				UV += Center;
				Out = UV;
			}

			void Unity_RoundedRectangle_float(float2 UV, float Width, float Height, out float Out) //矩形绘制
			{
				float Radius = max(min(min(2, abs(Width)), abs(Height)), 1e-5);
				float2 uv = abs(UV * 2 - 1) - float2(Width, Height) + Radius;
				float d = length(max(0, uv)) / Radius;
				Out = saturate((1 - d) / fwidth(d));
			}

			void Unity_PolarCoordinates_float(float2 UV, float2 Center, float RadialScale, out float2 Out) //极坐标转换
			{
				float2 delta = UV - Center;
				float radius = length(delta) * 2 * RadialScale;
				float angle = atan2(delta.x, delta.y) * 1.0/6.28;
				Out = float2(radius, angle);
			}

			void Unity_DrawPointer_float(float2 UV, float Rotate,float Width, float Height, float Step, out float Out) //指针绘制
			{
				float mask;
				float rot = -2 * frac(Rotate) * 3.14;
				Unity_Rotate_Radians_float(UV,rot,UV);
				Unity_RoundedRectangle_float(UV,Width,Height,mask);
				Out = mask * step(Step, UV.y);
			}

			void Unity_DrawTimeScale_float(float2 UV, float RadialScale, float Partition, float2 Scale, out float Out) //刻度绘制
			{
				float mask,mask1,mask2;
				Unity_PolarCoordinates_float(UV,float2(0.5,0.5),RadialScale,UV);
				Unity_RoundedRectangle_float(UV,Scale.y,3,mask);
				mask1 = frac(UV.y * Partition);
				mask2 = step(mask1,Scale.x);
				mask1 = step((1-mask1),Scale.x);
				mask *= mask1 + mask2;
				Out = mask;
			}


			Varyings vert(Attributes IN)
			{
				Varyings o;				
				o.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
				o.uv = IN.uv;				
				return o;
			}
			
			half4 frag(Varyings IN):SV_Target
			{
			//指针绘制
				float secondsdeg,minutesg,hourdeg;
				//秒针
				Unity_DrawPointer_float(IN.uv,_Secondsdeg,0.01,0.8,0.41,secondsdeg);
				//分针
				Unity_DrawPointer_float(IN.uv,_Minutesg,0.02,0.65,0.46,minutesg);
				//时针
				Unity_DrawPointer_float(IN.uv,_Hourdeg,0.031,0.3,0.46,hourdeg);
			//刻度绘制
			float longpartition,minipartition;
				//大刻度
				Unity_DrawTimeScale_float(IN.uv,0.56,12,float2(0.05,0.05),longpartition);
				//小刻度
				Unity_DrawTimeScale_float(IN.uv,0.56,60,float2(0.05,0.05),minipartition);

				return saturate(secondsdeg + minutesg + hourdeg + longpartition + minipartition * 0.5);
			}
			ENDHLSL
		}
	}
}

时间传递代码:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Clockcode : MonoBehaviour
{
    [SerializeField]
    bool SecondRun;
    TimeSpan time;
    float hourdeg, minutesg, secondsdeg;
    Material material;

    void Awake()
    {
        time = DateTime.Now.TimeOfDay;
        hourdeg = (float)time.TotalHours / 12f;
        minutesg = (float)time.TotalMinutes / 60f;
        if (SecondRun)
        {
            secondsdeg = (float)time.TotalSeconds / 60f;
        }
        else
        {
            secondsdeg = DateTime.Now.Second / 60f;
        }
        material.SetFloat("_Secondsdeg", secondsdeg);
        material.SetFloat("_Minutesg", minutesg);
        material.SetFloat("_Hourdeg", hourdeg);
    }
    // Start is called before the first frame update
    void Start()
    {
        material = GetComponent<Renderer>().material;
    }

    // Update is called once per frame
    void Update()
    {
        Debug.Log(DateTime.Now.Hour + ":" + DateTime.Now.Minute + ":" + DateTime.Now.Second);
        Awake();
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值