Unity3D ShaderLab布料着色器

布料着色器是我们在虚拟现实中经常使用的着色器。本篇就来完成一个较为简单的布料着色器。

新建Shader,Material,InteractiveCloth【布料】。完成的代码如下

Shader "91YGame/ClothShader" {
Properties {
//参数;
_MainTint("Base Color",Color)=(,,,)
_BumpMap ("Normal Map", 2D) = "bump" {}
_DetailBump("Detail Normal",2D)=""{}
_DetailTex("Fabric Weave",2D)=""{}
_FresnelColor("Fresnel Color",Color)=(,,,)
_FresnelPower("Fresnel Power",Range(0.01,))=
_RimPower("Rim Falloff",Range(0.01,))=
_SpecIntesity("Specular Intensity",Range(0.01,))=0.3
_SpecWidth("Specular Width",Range(0.01,))=0.2 }
SubShader {
Tags { "RenderType"="Opaque" }
LOD CGPROGRAM
#pragma surface surf VelvetCloth
#pragma target 3.0
//变量;
sampler2D _BumpMap;
sampler2D _DetailBump;
sampler2D _DetailTex;
float4 _MainTint;
float4 _FresnelColor;
float _FresnelPower;
float _RimPower;
float _SpecIntesity;
float _SpecWidth;
//输入结构体;
struct Input {
float2 uv_BumpMap;
float2 uv_DetailBump;
float2 uv_DetailTex;
}; inline fixed4 LightingVelvetCloth(SurfaceOutput s,fixed3 lightDir, fixed3 viewDir, fixed atten){
//光照向量;
viewDir =normalize(viewDir);
lightDir = normalize(lightDir);
half3 halfVec = normalize(lightDir+viewDir);
fixed NdotL = max(0.01,dot(s.Normal,lightDir));
//计算高光;
float NdotH = max(0.01,dot(s.Normal,halfVec));
float spec = pow(NdotH,s.Specular*)*s.Gloss;
//视线越贴近布料表面,纤维吸收的背面光就越多,高光也就越强;
float HdotV = pow(-max(,dot(halfVec,viewDir)),_FresnelPower);
float NdotE = pow(-max(,dot(s.Normal,viewDir)),_RimPower);
float finalSpecMask = NdotE*HdotV;
//最终颜色;
fixed4 c;
c.rgb = (s.Albedo*NdotL*_LightColor0.rgb)+(spec*(finalSpecMask*_FresnelColor))*(atten*);
c.a =;
return c;
} void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_DetailTex, IN.uv_DetailTex);
//提取法线;
fixed3 normals = UnpackNormal(tex2D(_BumpMap,IN.uv_BumpMap)).rgb;
fixed3 detailNormals = UnpackNormal(tex2D(_DetailBump,IN.uv_DetailBump)).rgb;
fixed3 finalNormals = float3(normals.x+detailNormals.x,normals.y+detailNormals.y,normals.z+detailNormals.z);
o.Normal = normalize(finalNormals);
o.Specular = _SpecWidth;
o.Gloss = _SpecIntesity;
o.Albedo = c.rgb*_MainTint;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}

返回Unity,设置变量。最终效果如下:

Unity3D ShaderLab 布料着色器-LMLPHP

Unity3D ShaderLab 布料着色器-LMLPHP

在上面的实现过程中,我们将两张不同平铺率的法线贴图结合到一起。计算出新的法线向量。

所以使用UnpackNormal从变化法线贴图中提取出法线向量在产生新的法线贴图。然后使用normalize对最后的向量进行归一化,这样可以避免法线贴图看起来杂乱。

最后 将菲涅尔计算和高光计算的结果进行合并,创建出布料的纤维效果。

05-06 05:09