Shader | 基于unity2018的Fur Shader(毛发着色器)的简单实现
Shader虚幻引擎技术渲染代码Thepoly 20229 3
实名

通过了实名认证的内容创造者

发布于 2022-3-26 14:47:11

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 Thepoly 于 2022-3-26 14:51 编辑

            src=http___img-blog.csdnimg.cn_img_convert_bb16c68e8b798b1ea8771e1b08482ac3.pngrefer=http___img-blog.csdnimg.webp.jpg
174551k9r66ex7z719e99h.jpg



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输入以下代码
  1. fixed4 _Color;
  2. sampler2D _MainTex;
  3. half _Glossiness;
  4. half _Metallic;
  5. uniformfloat _FurLength;
  6. uniformfloat _Cutoff;
  7. uniformfloat _CutoffEnd;
  8. uniformfloat _EdgeFade;
  9. uniform fixed3 _Gravity;
  10. uniform fixed _GravityStrength;

  11. void vert (inout appdata_full v)
  12. {
  13.          fixed3direction = lerp(v.normal, _Gravity * _GravityStrength + v.normal *(1-_GravityStrength), FUR_MULTIPLIER);
  14.          v.vertex.xyz+= direction * _FurLength * FUR_MULTIPLIER * v.color.a;
  15. }

  16. struct Input {
  17.          float2 uv_MainTex;
  18.          float3 viewDir;
  19. };

  20. void surf (Input IN, inout SurfaceOutputStandard o) {
  21.          fixed4c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
  22.          o.Albedo= c.rgb;
  23.          o.Metallic= _Metallic;
  24.          o.Smoothness= _Glossiness;
  25.          o.Alpha= step(lerp(_Cutoff,_CutoffEnd,FUR_MULTIPLIER), c.a);

  26.          float alpha = 1 - (FUR_MULTIPLIER *FUR_MULTIPLIER);
  27.          alpha+= dot(IN.viewDir, o.Normal) - _EdgeFade;
  28.          o.Alpha *= alpha;
点击此处复制文本


6.回到Fur.shader,在ENDCG后添加FurPass这个外部Pass
  1. void surf (Input IN, inout SurfaceOutputStandard o) {

  2.                            fixed4c = tex2D (_MainTex, IN.uv_MainTex) * _Color;

  3.                            o.Albedo= c.rgb;

  4.                            o.Metallic= _Metallic;

  5.                            o.Smoothness= _Glossiness;

  6.                            o.Alpha= c.a;

  7.          }

  8. ENDCG

  9. CGPROGRAM

  10. #pragma surface surf Standard fullforwardshadowsalpha:blend

  11. vertex:vert

  12. #define FUR_MULTIPLIER 0.05

  13. #include "FurPass.cginc"

  14. 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群。公众号是我们最为官方的窗口,更多内容都必须关注公众号后才能获取。另外现以开通微博:         

本帖被以下画板推荐:

还没有设置签名!您可以在此展示你的链接,或者个人主页!
使用道具 <
Teny  发表于 2022-3-26 18:43:30  
3#
谢谢楼主分享!!!
回复 收起回复
使用道具
塔叶苔  发表于 2022-7-11 14:53:57  
4#
学习了,收藏一下
回复 收起回复
使用道具
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表