您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 Thepoly 于 2022-3-26 14:51 编辑
Hello . 大家好
今天给大家带来Fur Shader的简单实现 我是王掌柜
一、毛发物理性质归纳
材质间的区别是由其材质特性决定的,所以在引擎中利用shader实现一个具体的材质效果之前,需要归纳其核心物理特征构建一个概念模型作为指导,寻找核心方法利用代码、贴图加以最终实现。
图1.1 毛发参考图人造纤维(图片来源:百度)
基于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理论模型
- End -
喜欢Thepoly的可以通过三种方式与我们建立联系。分别是公众号、微信群以及QQ群。公众号是我们最为官方的窗口,更多内容都必须关注公众号后才能获取。另外现以开通微博: |