当前位置:   article > 正文

2d shader unity 阴影_Shader | 基于unity2018的Fur Shader(毛发着色器)的简单实现

shader fur

4a5d21136367bc134ad5c94978a7b3ed.png

Hello . 大家好

今天给大家带来Fur Shader的简单实现

我是王掌柜

460e573d09f21071fb04f28eec850951.png

一、毛发物理性质归纳

材质间的区别是由其材质特性决定的,所以在引擎中利用shader实现一个具体的材质效果之前,需要归纳其核心物理特征构建一个概念模型作为指导,寻找核心方法利用代码、贴图加以最终实现。

757d1b884374a74042fdbccc27dcd1c9.png

图1.1 毛发参考图人造纤维(图片来源:百度)

5c40128feb559e8a150f8b4988ae3895.png 图1.2 毛发参考图动物皮毛(图片来源:百度)

基于PBR的材质共性(光滑度|金属度|固有色):也就是说欲创建的Fur Shader要有Metallic,Smoothness(or Roughness)的参数槽。

22c3cc5df8c6b9c5a7fd433a71689581.png

基于毛发材质的几点特性:

1 毛发长度:Fur Length,此外还有毛发长短不一的特征。

2 毛发根部到尖端由粗到细的变化:需要两个变量来分别控制根部和尖端

3 毛茸茸的感觉:这个需要利用核心方法ShellPass以及模拟毛发边缘衰减来进一步辅助表现

4 毛发受重力影响:这里要注意重力是一个矢量(Vector),有大小和方向,故这里也需要两个参量来模拟

5 毛发颜色:一般采用贴图控制

二、制作流程

1.    美术素材制作。这里面你可以在网上搜索相关毛发图或是自己绘制的颜色图,唯一要注意的是需要开个Alpha通道,并制作一张噪点图放入该通道之中。这张噪点图很重要,它控制着毛发的最终长度、分布以及显示。制作了两张噪点图,一张是WhiteNoise、一张PerlinNoise。在PS里我将两张噪声图不透明度降低并合并,形成放在颜色图A通道里的最终效果图(这里由于懒没做四方联续)

398e1a0ce3b8d8ae230714e8aec4ec1a.png

4a18a266a4d930ac7f8786d690e4f741.png

 图2.1 WhiteNoise And Perlin Noise

319f0d9e3f320403c3a291dd9adf7600.png

图2.2合成效果

998891cb063e51a08ec3636b088045ba.png

图2.3置于Alpha通道之中

2.这里应用的unity引擎版本是2018.3。首先,在Project面板中,创建一个Material和Standard SurfaceShader。并在Scene视图中创建一个Sphere并赋予该材质(这里为了方便直接使用unity内置Sphere)

dff204aeec78350ad4669a1b25e6cee8.png

图2.4shader和Material创建

3.将新建的Standard SurfaceShader重命名为Fur,双击Fur,利用本地电脑的IDE打开(这里用的是VS2017),根据之前分析的模拟的毛发属性开始为Fur材质添加属性,代码如下

Shader "WegShaders/Test/Fur" //shader索引编辑,就可以在目录中检索到并添加,如下图:

ad2ca09014443bdde9190d0b70c7bbfd.png

图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打开并进行编程。

154e7a020a1a8b2a3bab66ac72e19266.png

图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,观察此时材质球的属性面板,会出现下列我们已经设置好的属性模块。

40d5ebd5d08b657bc13ec7ca5cb670ca.png

图2.7 FurShader 主要属性

8.调整相关参数,就可以得到不同效果,如下示例

f39cc82b61cdfba0d07874645d704c79.png

图2.8 调试效果图

一些制作思路

这个方法全称是Lengyel'sconcentric fur-shell technique,其实就是以原本几何体为中心复制并扩大出一个个副本用以渲染,这个副本就被命名为“Shell”。这种方法不计较容易实现毛发效果。而另一种思路如果要生成真实的几何体毛发的话,不仅要从原有的模型挤出几何形体而且相应的顶点也会发生变化,这种方法的话可以利用TessellationShader实现。ShellFur Shader的理论毛发模型如下

672d94960879658d553bf8074d1e6dab.png

图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 关于我们 163e1fabdbe26fc4a0e66457f53adcb2.png

微信群

b349cd999f78b3a69ec9ff2cec07e509.png

公众号

a7a219492670bf353427a75fc52cac9a.png

QQ群

喜欢Thepoly的可以通过三种方式与我们建立联系。分别是公众号、微信群以及QQ群。公众号是我们最为官方的窗口,更多内容都必须关注公众号后才能获取。另外现以开通微博:手机版http://weibo.cn/thepoly网页版http://weibo.com/thepoly

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/108549
推荐阅读
相关标签
  

闽ICP备14008679号