unity shader - 毛发渲染,飘逸的毛发

unity shader - 毛发渲染,飘逸的毛发_第1张图片
渲染原理:
第一步:
分层layer,渲染不同长度的毛发。 层越多,绘制的越细节。
因为毛发有长短,所以,在上层,没有毛发的部分alpha设置为0,不显示
多个layer,可以使用shader等多个pass进行绘制
每一个 Pass 即表示一层。 当渲染每一层时, 使用法线将顶点位置挤出模型表面
第二步:
根据噪音贴图, 在随机毛发的长度。控制alpha的值
层次不同,毛发的uv位置偏移应该也有所不同,这样制作的才能更自然,否则uv一直不变,那么毛发的方向不变就变成了刺猬
毛发不同层次的偏移,也可能收到外力的影响,比如,风等,所以外边可以设置一个偏移量
第三步
处理环境光,反射和漫反射光等影响,设置颜色

实现:

1 多pass渲染。 对于皮毛来说,每一层的渲染方式是一样的,所以采用 在每个pass中引用, 避免重复代码。
不同的层次需要传参数控制表示. 用 【 1/总的层数 】 就是每一层毛所对应的长度
//表面皮肤渲染
Pass
{
    CGPROGRAM
               
    #pragma vertex vert_surface//点着色器 , 对应引用cginc中的方法
    #pragma fragment frag_surface// 片段着色器 , 对应引用cginc中的方法
    #define FURSTEP 0.0 
    #include "FurHelper.cginc" // 引用的shader
               
    ENDCG
               
}
// 毛的渲染
Pass
{
    CGPROGRAM
               
    #pragma vertex vert_base //点着色器 , 对应引用cginc中的方法
    #pragma fragment frag_base // 片段着色器 , 对应引用cginc中的方法
    #define FURSTEP 0.05 // 皮毛的长度
    #include "FurHelper.cginc" // 引用的shader
               
    ENDCG
               
}

2 顶点外扩, 实现多层次偏移
思路:在顶点的法线方向,向外扩展一定的距离。 所以在顶点着色器中处理
            v2f vert(a2v v)
            {
                v2f o;
                float3 OffetVertex = v.vertex.xyz + v.normal * _LayerOffset *_FurLength;//顶点外扩
                OffetVertex += mul(unity_WorldToObject, _FurOffset);//顶点受力偏移【加一个方向上的偏移,看起来更自然,例如向下垂】
            }

3 使用噪音贴图,进行透明度处理
思路: 利用uv2 存储噪音贴图, 然后根据噪音贴图随机性,处理显示毛发的透明度 。 
fixed3 noise = tex2D(_FurTex, i.uv.zw ).rgb; 
fixed alpha = saturate(noise - (_LayerOffset * _LayerOffset + _LayerOffset * _FurDensity));

4 优化处理。提炼参数
    · 毛发长度参数。限制最外层的扩展长度
    · 毛发层数
    · 颜色参数
    · 毛发密集参数(噪音贴图中使用,控制uv的tilling)
    · 添加偏移参数 (例如, 长毛宠物的毛会下垂)
5 *优化处理, 添加毛发移动
使用c#代码控制毛发,缓慢飘逸移动 【lerp】
思路:
shader只渲染一层毛发
c#代码控制,克隆多个游戏对象, 都赋值该毛发的shader,通过改变偏移量,生成多个【需要多少层就是生成多少层】
c#代码中,update中lerp控制每一层毛发缓慢移动。 从而实现飘逸的移动
// 生成, material赋值, shader赋值
void CreateShell()
{
    CheckParent();
    layers = new GameObject[LayerCount];
    float furOffset = 1.0f/ LayerCount;
    for (int i = 0; i< LayerCount; i++)
    {
        //复制渲染的原模型一遍
        GameObject layer = Instantiate(Target.gameObject, Target.transform.position, Target.transform.rotation);
        layer.transform.parent = _parent;
        layer.GetComponent().sharedMaterials = new Material[1];
        layer.GetComponent().sharedMaterial = ResetSharedMaterials(i, furOffset);
        layers[i] = layer;
    }
}

// shader 赋值
Material ResetSharedMaterials(int index, float furOffset)
{
    Material special = new Material(ShellShader);
    if (special != null)
    {
        special.SetTexture("_MainTex", Target.sharedMaterial.GetTexture("_MainTex"));
        special.SetColor("_Color", FurColor);
        special.SetColor("_RootColor", FurRootColor);
        special.SetColor("_RimColor", FurRimColor);
        special.SetColor("_Specular", FurSpecularColor);
        special.SetFloat("_Shininess", Shininess);
        special.SetFloat("_RimPower", RimPower);
        special.SetFloat("_FurShadow", FurShadow);
        special.SetTexture("_FurTex",FurPattern);
        special.SetFloat("_FurLength", FurLength);
        special.SetFloat("_FurDensity", FurDensity);
        special.SetFloat("_FurThinness", FurThinness);
        special.SetFloat("_LayerOffset", index * furOffset);            //不同Shell的偏移参数不一样
        special.SetVector("_FurOffset", FurForce* Mathf.Pow(  index*furOffset,FurTenacity));//计算受力、层数和硬度共同影响的Shell偏移
        special.renderQueue = 3000 + index;//由于在单通道渲染半透明材质,进行了深度写入,为了防止被深度剔除,所以要手动更改渲染队列
    }
    return special;
}


// 移动
void UpdateShellTrans()
{
    if (layers == null || layers.Length == 0)
    {
        return;
    }
    for (int i = 0; i < layers.Length; i++)
    {
        //位置和旋转Lerp到目标模型
        layers[i].gameObject.transform.position = Vector3.Lerp(layers[i].gameObject.transform.position, Target.transform.position, lerpSpeed * Time.deltaTime *20);
        layers[i].gameObject.transform.rotation = Quaternion.Lerp(layers[i].gameObject.transform.rotation, Target.transform.rotation, lerpSpeed * Time.deltaTime *10);
    }
}

参考:

真香预警!新版“峡谷第一美”妲己尾巴毛发制作分享

https://github.com/Sorumi/UnityFurShader

Fur Tool Unity Asset for 3D Character Modelling Artists | Coldface Interactive

https://github.com/Acshy/FurShaderUnity

 

你可能感兴趣的:(shader,lua,unity,shader)