主要材质为 约90%聚酰胺纤维(锦纶/尼龙)+ 约10%聚氨酯纤维(氨纶)
基本上可以推测这种材质的金属性(Metallic)为0,而光滑度(Smoothness)则根据种类不同会有较大区别。
各种丝袜的厚薄也有区别,“D”或“Denier”是指纤维的纤度单位。5D、10D几乎透明,100D以上则几乎不透,很好理解,请看下图:
在Shader里我们采用Denier值来表示丝袜的厚薄程度。
我们可以发现一种现象——靠近腿部中央的位置丝袜颜色较淡,并且如果丝袜够薄甚至会显出底下皮肤的颜色,而越靠近腿两侧丝袜颜色则会越深。丝袜由无数细小交错的纤维组成,所以正对视线的纤维是最稀疏的,而越靠近腿部轮廓的纤维则对于观察者来说越显得密集。
基于PBR,对丝袜纤维的密集程度定义一个属性 疏密度(Density) ,取值范围0(几乎没有纤维)到 1(完全被纤维覆盖)。依据疏密度提供颜色给Albedo通道,疏密度越高显现更多丝袜颜色,越低则显现皮肤颜色。
计算疏密度需要三部步骤:
1.丹尼尔值对整体疏密度的影响。
2.受丝袜良好弹性影响,需要一张灰度贴图来控制不同区域的拉伸程度,拉伸越大疏密度越低。
3.受观察者视线的影响,丝袜平面与观察者视线角度越小时,疏密度越大。称其为边缘度影响。
Properties{
_Denier("Denier", Range(5,120)) = 25.0
_DenierTex("Density Texture", 2D) = "black"{}
_Smoothness("Smoothness", Range(0,1)) = 0.1
_Metallic("Metallic",Range(0,1)) = 0.1
[Enum(Strong,6,Normal,12,Weak,20)] _RimPower("Rim Power", float) = 12
_FresnelScale("Fresnel Scale",Range(0, 6)) = 1
_SkinTint("Skin Color Tint", Color) = (1,0.9,0.8,1)
_SkinTex("Skin Color", 2D) = "white" {}
_StockingTint("Stocking Color Tint", Color) = (1,1,1,1)
_StockingTex("Stocking Color", 2D) = "white"{}
_NormalTex("Normal", 2D) = "bump"{}
}
float denier = (_Denier - 5) / 115;
float density = denier * (1 - tex2D(_DenierTex, IN.uv_DenierTex));
float rim = pow(1 - dot(normalize(IN.viewDir), o.Normal), _RimPower / 10); //边缘光
float fresnel = pow(1.0 - max(0,dot(normalize(IN.viewDir), o.Normal)),_FresnelScale); //菲涅尔
Shader "Kirk/Stocking" {
Properties{
_Denier("Denier", Range(5,120)) = 25.0
_DenierTex("Density Texture", 2D) = "black"{}
_Smoothness("Smoothness", Range(0,1)) = 0.1
_Metallic("Metallic",Range(0,1)) = 0.1
[Enum(Strong,6,Normal,12,Weak,20)] _RimPower("Rim Power", float) = 12
_FresnelScale("Fresnel Scale",Range(0, 6)) = 1
_SkinTint("Skin Color Tint", Color) = (1,0.9,0.8,1)
_SkinTex("Skin Color", 2D) = "white" {}
_StockingTint("Stocking Color Tint", Color) = (1,1,1,1)
_StockingTex("Stocking Color", 2D) = "white"{}
_NormalTex("Normal", 2D) = "bump"{}
}
SubShader{
Tags{ "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Standard fullforwardshadows
#pragma target 3.0
struct Input {
float2 uv_SkinTex;
float2 uv_StockingTex;
float2 uv_DenierTex;
float2 uv_NormalTex;
float3 viewDir;
};
float _RimPower;
float _Denier;
float _Smoothness;
float _Metallic;
float _FresnelScale;
float4 _SkinTint;
float4 _StockingTint;
sampler2D _DenierTex;
sampler2D _SkinTex;
sampler2D _StockingTex;
sampler2D _NormalTex;
void surf(Input IN, inout SurfaceOutputStandard o) {
o.Normal = UnpackNormal(tex2D(_NormalTex, IN.uv_NormalTex)); //得到法线
float4 skinColor = tex2D(_SkinTex, IN.uv_SkinTex) * _SkinTint; //内颜色
float4 stockingColor = tex2D(_StockingTex, IN.uv_StockingTex) * _StockingTint; //外颜色
float rim = pow(1 - dot(normalize(IN.viewDir), o.Normal), _RimPower / 10); //边缘光
float fresnel = pow(1.0 - max(0,dot(normalize(IN.viewDir), o.Normal)),_FresnelScale); //菲涅尔
float denier = (_Denier - 5) / 115; //丹尼尔参数
float density = max(rim, (denier * (1 - tex2D(_DenierTex, IN.uv_DenierTex)))); //lerp参数
o.Albedo = lerp(skinColor, stockingColor, density);
o.Albedo = o.Albedo * (1 - fresnel);
o.Metallic = _Metallic;
o.Smoothness = _Smoothness;
}
ENDCG
}
FallBack "Diffuse"
}