本篇主要用于记录自己的实战操作,以及一些碎碎念(观后感),如果有什么好想法或者本篇出现什么错误,请多指教~
本篇的内容参考视频:庄懂的技术美术入门课(美术向) 使用软件:Unity 2019 3.6f1 ,ShaderForge
本篇内容主要包括:钟表小人的制作;
1.准备工作
- 模型
- SD处理贴图
为什么不用PS用SD,一个是批量处理,一个是PS的涂抹可能会导致某些效果出错;
NoFace节点创建:
- 首先为了了解效果先用单张贴图做处理,通过Transform节点放大贴图额头局部,再做tilling,然后底下通过SVG去绘制遮罩(记得将颜色设置为GrayScale)然后与Bevel节点相连做柔和处理;
- 为了批量处理,再将贴图和输出结果都替换成可选择的;
- 最后在总节点里,分别处理各贴图;
clock节点创建:
- 首先利用Text节点制作数字,然后在Patterns里找到一个圆形分布的节点,并分别连接六个数字(自定义最大六个),然后用blendMax方式混合取亮度区域;
- 接下来用bevel对数字柔化,并添加一个图形作为中间的装饰,将两者混合输出;
- 最后在总节点里,导入并调整大小使其与表盘相当,并根据调整后的图,制作法线贴图,AO贴图,增强对比度的操作,根据法线贴图制作曲率图;
总节点操作:
- 利用上面的遮罩,在相应位置取色并混合
乱成麻花了…; - 法线贴图的处理仅需将表盘与原法线贴图的结合在一起;
表针的SD处理:
- 首先先导入模型并烘焙得到物体的世界空间下的法线贴图;
- 用烘焙出的贴图求得曲率图和AO图
- 利用Shape节点结合放缩节点制作三个指针的大致遮罩,以便后面进行加工处理;
- 划痕取自SD中内置的噪波图,并取反,获得遮罩图,然后再引入一个边缘破损的图对指针进行混合处理,再与之前的指针遮罩混合得到划痕效果;
- 我们从颜色贴图里引出一个HSL节点用于调色相饱和度亮度,再与其本身使用Blend混合,遮罩取自时针的遮罩图,同样的操作处理分针秒针进行基础色上色;
- 再跟据之前处理表盘的掉漆处理,处理针的掉漆,法线贴图则取自于掉漆遮罩的节点,最后将处理好的图该合并的合并然后输出;
2.代码
- 我们以之前的oldschoolpro为基础,添加时分秒针的相关参数以及偏移量用于校正旋转中心,然后和上一篇里说的旋转一样,声明函数;
- 接下来我们要使小人时间和系统时间一致,编写C#脚本,就先声明几个变量,Material一个,然后三个针的ID各一个,Unity中对于材质的寻找并不像是场景中 的物体以名字找,而是在游戏开始之初根据ID寻找,再声明一个valid布尔类型变量以判断是否有效,当无效时省的让其脚本继续运行徒增负荷;
- 然后就是在update函数里进行获取当前时间和给材质中参数赋值的操作;
最终效果:
c#代码如下:
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine;
public class clock : MonoBehaviour
{
// Start is called before the first frame update
public Material clockmat;
private bool valid;
private int hourAnglePropID;
private int minuteAnglePropID;
private int secondAnglePropID;
void Start()
{
if (clockmat != null)
{
hourAnglePropID = Shader.PropertyToID("_HourHandAngle");//获取属性名的ID值
minuteAnglePropID = Shader.PropertyToID("_MinuteHandAngle");
secondAnglePropID = Shader.PropertyToID("_SecondHandAngle");
if (clockmat.HasProperty(hourAnglePropID) && clockmat.HasProperty(minuteAnglePropID) && clockmat.HasProperty(secondAnglePropID))
valid = true;
}
}
// Update is called once per frame
void Update()
{
if (!valid) return;
int second = DateTime.Now.Second;//获取本电脑上的时间;
float secondAngle = second / 60.0f * 360.0f;//获取转动值
int minute = DateTime.Now.Minute;
float minuteAngle = minute / 60.0f * 360.0f;
int hour = DateTime.Now.Hour;
float hourAngle = (hour % 12) / 12.0f * 360.0f + minuteAngle / 360.0f * 30.0f;//映射下,一分钟跳一小小格
clockmat.SetFloat(secondAnglePropID, secondAngle);//设定Material中的转动值
clockmat.SetFloat(minuteAnglePropID, minuteAngle);
clockmat.SetFloat(hourAnglePropID, hourAngle);
}
}
Shader关键代码如下:
void clockrotate(inout float3 vertex,float angle,float offset,float mask){
vertex.y -=offset*mask;
float radZ=radians(angle*mask);
float sinz,cosz=0.0;
sincos(radZ,sinz,cosz);
vertex.xy=float2(
vertex.x*cosz-vertex.y*sinz,
vertex.x*sinz+vertex.y*cosz
);
vertex.y+=offset*mask;
}
void ClockAnime(float3 color,inout float3 vertex){
clockrotate(vertex,_HourHandAngle,_RotateOffset,color.r);
clockrotate(vertex,_MinuteHandAngle,_RotateOffset,color.g);
clockrotate(vertex,_SecondHandAngle,_RotateOffset,color.b);
}