赞
踩
Hello . 大家好
今天给大家带来Fur Shader的简单实现
我是王掌柜
一、毛发物理性质归纳材质间的区别是由其材质特性决定的,所以在引擎中利用shader实现一个具体的材质效果之前,需要归纳其核心物理特征构建一个概念模型作为指导,寻找核心方法利用代码、贴图加以最终实现。
图1.1 毛发参考图人造纤维(图片来源:百度)
图1.2 毛发参考图动物皮毛(图片来源:百度)
基于PBR的材质共性(光滑度|金属度|固有色):也就是说欲创建的Fur Shader要有Metallic,Smoothness(or Roughness)的参数槽。
基于毛发材质的几点特性:
1 毛发长度:Fur Length,此外还有毛发长短不一的特征。
2 毛发根部到尖端由粗到细的变化:需要两个变量来分别控制根部和尖端
3 毛茸茸的感觉:这个需要利用核心方法ShellPass以及模拟毛发边缘衰减来进一步辅助表现
4 毛发受重力影响:这里要注意重力是一个矢量(Vector),有大小和方向,故这里也需要两个参量来模拟
5 毛发颜色:一般采用贴图控制
二、制作流程1. 美术素材制作。这里面你可以在网上搜索相关毛发图或是自己绘制的颜色图,唯一要注意的是需要开个Alpha通道,并制作一张噪点图放入该通道之中。这张噪点图很重要,它控制着毛发的最终长度、分布以及显示。制作了两张噪点图,一张是WhiteNoise、一张PerlinNoise。在PS里我将两张噪声图不透明度降低并合并,形成放在颜色图A通道里的最终效果图(这里由于懒没做四方联续)
图2.1 WhiteNoise And Perlin Noise
图2.2合成效果
图2.3置于Alpha通道之中
2.这里应用的unity引擎版本是2018.3。首先,在Project面板中,创建一个Material和Standard SurfaceShader。并在Scene视图中创建一个Sphere并赋予该材质(这里为了方便直接使用unity内置Sphere)
图2.4shader和Material创建
3.将新建的Standard SurfaceShader重命名为Fur,双击Fur,利用本地电脑的IDE打开(这里用的是VS2017),根据之前分析的模拟的毛发属性开始为Fur材质添加属性,代码如下
Shader "WegShaders/Test/Fur" //shader索引编辑,就可以在目录中检索到并添加,如下图:
图2.5shader索引
{
Properties
{
_Color ("Color", Color) = (1,1,1,1) //色相槽
_MainTex ("Albedo (RGB)", 2D) = "white" {} //贴图槽
_Glossiness ("Smoothness", Range(0,1)) = 0.0 //光滑度
_Metallic ("Metallic", Range(0,1)) = 0.0 //金属度
_FurLength ("Fur Length", Range (.0002, 1)) = 0.25 //毛发长度这里利用Pass次数来模拟该处设计为可在定区间内自由调节
_Cutoff ("Alpha Cutoff", Range(0,1)) = 0.5 // 毛发的粗细程度
_CutoffEnd ("Alpha Cutoff end", Range(0,1)) = 0.5 //毛发末尾的粗细程度(锥子型)
_EdgeFade ("Edge Fade", Range(0,1)) = 0.5 //边缘衰减,毛发边缘由于光照产生类似散射的毛茸茸效果的模拟
_Gravity ("Gravity Direction", Vector) = (0,0,0,0) //重力方向
_GravityStrength ("Gravity Strength", Range(0,1)) = 0.5 //重力大小
}
4.该shader需要重复同一Pass若干次,主要是为了实现即时调整毛发长度(FurLength),这里需要利用CgIncludes来创建一个外部文件,来实现这个功能。创建过程是在Unity工程文件根目录创建一个.txt记事本文件,创建之后修改文件后缀为.cginc。创建完成之后用Windows里的软件无法打开,不过没关系,在启动unity之后,在Project目录中找到该文件可以用本地IDE打开并进行编程。
图2.6cginc文件创建
5.这里我将该文件命名为FurPass,并打开IDE输入以下代码
fixed4 _Color;
sampler2D _MainTex;
half _Glossiness;
half _Metallic;
uniformfloat _FurLength;
uniformfloat _Cutoff;
uniformfloat _CutoffEnd;
uniformfloat _EdgeFade;
uniform fixed3 _Gravity;
uniform fixed _GravityStrength;
void vert (inout appdata_full v)
{
fixed3direction = lerp(v.normal, _Gravity * _GravityStrength + v.normal *(1-_GravityStrength), FUR_MULTIPLIER);
v.vertex.xyz+= direction * _FurLength * FUR_MULTIPLIER * v.color.a;
}
struct Input {
float2 uv_MainTex;
float3 viewDir;
};
void surf (Input IN, inout SurfaceOutputStandard o) {
fixed4c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo= c.rgb;
o.Metallic= _Metallic;
o.Smoothness= _Glossiness;
o.Alpha= step(lerp(_Cutoff,_CutoffEnd,FUR_MULTIPLIER), c.a);
float alpha = 1 - (FUR_MULTIPLIER *FUR_MULTIPLIER);
alpha+= dot(IN.viewDir, o.Normal) - _EdgeFade;
o.Alpha *= alpha;
6.回到Fur.shader,在ENDCG后添加FurPass这个外部Pass
void surf (Input IN, inout SurfaceOutputStandard o) {
fixed4c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo= c.rgb;
o.Metallic= _Metallic;
o.Smoothness= _Glossiness;
o.Alpha= c.a;
}
ENDCG
CGPROGRAM
#pragma surface surf Standard fullforwardshadowsalpha:blend
vertex:vert
#define FUR_MULTIPLIER 0.05
#include "FurPass.cginc"
ENDCG
7.之后将这个shader文件挂载到材质球上,并将材质球赋予给Sphere,观察此时材质球的属性面板,会出现下列我们已经设置好的属性模块。
图2.7 FurShader 主要属性
8.调整相关参数,就可以得到不同效果,如下示例
图2.8 调试效果图
三、一些制作思路这个方法全称是Lengyel'sconcentric fur-shell technique,其实就是以原本几何体为中心复制并扩大出一个个副本用以渲染,这个副本就被命名为“Shell”。这种方法不计较容易实现毛发效果。而另一种思路如果要生成真实的几何体毛发的话,不仅要从原有的模型挤出几何形体而且相应的顶点也会发生变化,这种方法的话可以利用TessellationShader实现。ShellFur Shader的理论毛发模型如下
图3.1 FurShader理论模型
FurShader每一次Pass主要靠 FurPass.cginc控制,根据法线方向挤出一个个比原来的球稍稍大那么一点点的副本做shell。重力效果主要靠离中心的距离来控制其强度:
voidvert (inout appdata_full v)
{
fixed3 direction =lerp(v.normal, _Gravity * _GravityStrength + v.normal * (1-_GravityStrength),FUR_MULTIPLIER);
v.vertex.xyz +=direction * _FurLength * FUR_MULTIPLIER * v.color.a;
}
当然,这个Fur Shader还可以继续优化比如加一些阴影效果:例如越接近根本的像素点越暗或者利用插值去实现。今天就到这里啦!下次我们继续。
- End -
ABOUT US 关于我们微信群
公众号
QQ群
喜欢Thepoly的可以通过三种方式与我们建立联系。分别是公众号、微信群以及QQ群。公众号是我们最为官方的窗口,更多内容都必须关注公众号后才能获取。另外现以开通微博:手机版http://weibo.cn/thepoly网页版http://weibo.com/thepoly
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。