人体皮肤学习1

参考网址:
https://www.cnblogs.com/timlly/p/11098212.html
https://zhuanlan.zhihu.com/p/72161323
http://www.iryoku.com/translucency/

1、首先效果图:
在这里插入图片描述
1、surf函数的解析
输入的参数:

struct Input 
{
	float2 uv_MainTex;
};

在_MainTex前加了一个前缀:uv,获取uv坐标:

_MainTex ("Diffuse Map(RGB)", 2D) = "white" {}

输出的参数:

struct MySurfaceOutput 
{
    half3 Albedo;
    half3 Normal;
    #ifdef ENABLE_SEPARATE_DIFFUSE_NORMALS
    half3 NormalBlue;
    half3 NormalGreen;
    half3 NormalRed;
    #endif
    half3 Emission;
    half Specular;
    half Gloss;
    half Alpha;
    half Scattering;
    #ifdef ENABLE_TRANSLUCENCY
    half3 Translucency;
    #endif
    #ifdef ENABLE_RIMS
    half BackRimWidth;
    half FrontRimWidth;
    #endif
}; 

surf函数的主体部分:

float2 uv = IN.uv_MainTex; //得到uv坐标
	
#ifdef ENABLE_SEPARATE_DIFFUSE_NORMALS
	float3 normalHigh = UnpackNormal(tex2D(_BumpMap, uv));
	float3 normalLow = UnpackNormal(tex2Dbias(_BumpMap, float4(uv, 0, 3)));
	o.Normal = normalize(lerp(normalLow, normalHigh, _Bumpiness));
	o.NormalRed = normalize(lerp(normalLow, normalHigh, _BumpinessDR));
	o.NormalGreen = normalize(lerp(normalLow, normalHigh, _BumpinessDG));
	o.NormalBlue = normalize(lerp(normalLow, normalHigh, _BumpinessDB));
#else
	#ifndef NOGLSL
		o.Normal = UnpackNormal(tex2Dbias(_BumpMap, float4(uv, 0, (1-_Bumpiness)*3)));
	#else
	// no GLSL support (most likely Intel igp)
	// fallback to smoothing to fully perpendicular normal instead of low res mipmap
	// this could result in differences if normal contains larger features, not just
	// small bumpy ones.
	// TODO could geet rid of normalize op by pecifying packed normal for various platforms (or is there a define i didn't find?)
	//	o.Normal = normalize(lerp(half3(0,0,1),UnpackNormal(tex2D(_BumpMap, uv)), _Bumpiness));
	// FIXME should normalize it, but there are no more instructions left!
		o.Normal = (lerp(half3(0,0,1),UnpackNormal(tex2D(_BumpMap, uv)), _Bumpiness));
	#endif
#endif

这段只是为了计算法线。
_BumpMap 为凹凸图/法线图。
在这里插入图片描述

half3 specGlosDepth = tex2D(_SpecGlosDepthMap, uv).rgb;
half depth = specGlosDepth.b;
o.Scattering = saturate((depth + _ScatteringOffset) * _ScatteringPower);

其中_SpecGlosDepthMap的定义为:三个维度存放了三个不同的信息。分别是镜面反射系数、光滑度、深度。
_SpecGlosDepthMap (“Specular ® Glosiness(G) Depth (B)”, 2D) = “white” {}
在这里插入图片描述
在unity中也可以很方便的查看各个通道的信息:
在这里插入图片描述
上面的三句代码是,采样纹理,得到b通道的数值,即深度信息,对深度进行偏移,并进行缩放。这个最终表达的是次表面散射的强度。

half3 c = tex2D(_MainTex, uv).rgb;
o.Albedo = c.rgb * _Color.rgb;
o.Alpha = 1; // no transparency
o.Specular = specGlosDepth.g * _SpecRoughness;
o.Gloss = specGlosDepth.r * _SpecIntensity;

采样纹理,对颜色进行缩放,alpha设置为1,对光滑度进行缩放,为啥存放在specular中呢???,对镜面反射强度进行缩放。

#ifdef ENABLE_RIMS
	half rimSpread = 1 - depth*0.8;
    o.BackRimWidth = _BackRimWidth * rimSpread;
    o.FrontRimWidth = _FrontRimWidth * rimSpread;
#endif

如果开启了边缘效果。那么1 - depth*0.8;表示,越薄则边缘光越强,与厚度成反比。

#ifdef ENABLE_TRANSLUCENCY
    // Calculate the scale of the translucency effect.
	depth = 1-depth;
	depth = saturate((depth + _TranslucencyOffset) * 1);
	
    float scale = 8.25 * depth / _TranslucencyRadius;
    float d = scale * depth;
    half translucencyStrength = (1-depth) * _TranslucencyPower;
    
       
    // Could use a lookup map for this, but it's actually faster to compute on my GTX460
    // half3 translucencyProfile = tex2D(_LookupTranslucency, half2(d, 0)).rgb;
    
    float dd = -d * d;
    half3 translucencyProfile =
    				 float3(0.233, 0.455, 0.649) * exp(dd / 0.0064) +
                     float3(0.1,   0.336, 0.344) * exp(dd / 0.0484) +
                     float3(0.118, 0.198, 0.0)   * exp(dd / 0.187)  +
                     float3(0.113, 0.007, 0.007) * exp(dd / 0.567)  +
                     float3(0.358, 0.004, 0.0)   * exp(dd / 1.99)   +
                     float3(0.078, 0.0,   0.0)   * exp(dd / 7.41);
                     
    o.Translucency = translucencyStrength * translucencyProfile;
	#endif

这个暂时不懂。。

下面是光照函数:

摘取片段:

half4 c = _LightColor0.rgba;
c.rgb *= s.Albedo * ( diff //漫反射
	#ifdef ENABLE_TRANSLUCENCY //半透明效果
		+ translucency * atten
	#endif
    #ifdef ENABLE_RIMS
		+ (frim * atten).xxx //正面边缘光
	#endif
)
+ (specLevel * atten).xxx //这部分是镜面反射
   #ifdef ENABLE_RIMS
	+ brim.xxx //这是背面边缘光
	#endif
;
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值