Shader - Fabric & Microfiber

材质效果(Unity)

材质参考(Marmoset Toolbag)

主要参考八猴渲染器的官方材质Velvet,解析了它的实现思路,它使用了两套光照着色并叠加:Sheen BRDF + GGX BRDF


材质对齐(Marmoset Toolbag)

逐步分解着色计算的过程并使用同一套贴图,横向对比Marmoset Toolbag和Unity的效果。单独对比仅在直接光作用下的Sheen BRDF效果。
从结果中可以看到,直接光的效果基本是一致的,但是间接光的差异就比较大。八猴渲染器的间接环境光源是带有方向信息的,在光照计算时能得到和直接光一样真实的漫反射和镜面反射,这就明显区别于Unity使用的Light Probes和Reflection Probes。


Microfacet Sheen BRDF

基于理论基础:"Production Friendly Microfacet Sheen BRDF"(Alejandro Conty Estevez, Christopher Kulla)

Specular BRDF

struct MicrofiberGCurve
{
    float a, b, c, d, e;
};
MicrofiberGCurve G_MicrofiberInterpolate( float roughness )
{
float r  = 1.0 - roughness;
float r2 = r * r;
MicrofiberGCurve g;
g.a = mix(  21.5473,  25.3245, r2 );
g.b = mix(  3.82987,  3.32435, r2 );
g.c = mix(  0.19823,  0.16801, r2 );
g.d = mix( -1.97760, -1.27393, r2 );
g.e = mix( -4.32054, -4.85967, r2 );
return g;
}
float G_MicrofiberL( MicrofiberGCurve g, float x )
{
return g.a * rcp(1.0 + g.b*pow(x, g.c)) + g.d*x + g.e;
}
float G1_Microfiber( MicrofiberGCurve g, float cosTheta )
{
return cosTheta < 0.5
? exp( G_MicrofiberL(g, cosTheta) )
: exp( 2.0*G_MicrofiberL(g, 0.5) - G_MicrofiberL(g, saturate(1.0 - cosTheta)) );
}
float G2_Microfiber( float NdotL, float NdotV, float roughness )
{
MicrofiberGCurve g = G_MicrofiberInterpolate( roughness );
float dL = G1_Microfiber( g, NdotL );
float dV = G1_Microfiber( g, NdotV );
//soften shadow terminator
{
float f = saturate( 1.0 - NdotL );
f *= f; f *= f; f *= f; // f^8
dL = pow( dL, 1.0 + 2.0*f );
}
return rcp( 1.0 + dL + dV );
}
float NDF_Microfiber( float NdotH, float roughness )
{
float invr = rcp( roughness );
float sinTheta2 = saturate( 1.0 - NdotH*NdotH );
return ( 2.0 + invr ) * pow( sinTheta2, invr * 0.5 ) * INVTWOPI;
}

float D = NDF_Microfiber( NdotH, roughness );
float G = G2_Microfiber( NdotL, NdotV, roughness );
float3 F = sheen;//sheen map color
float denom = 4.0 * NdotV; //non cancelled-out microfacet BRDF normalization terms
outSpecTerm = F * D * G * ( denom > 0.0 ? rcp(denom) : 0.0 );

Diffuse BRDF

//energy conservation terms, sample sheen albedo map
float specAlbedoL = SAMPLE_TEX_SHEENALBEDOLUT( float2(NdotL, roughness) ).x;
float specAlbedoV = SAMPLE_TEX_SHEENALBEDOLUT( float2(NdotV, roughness) ).x;
float3  specAlbedo  = min( OneminusClamped(sheen * specAlbedoL), OneminusClamped(sheen * specAlbedoV) );
outDiffTerm = specAlbedo * brdfData.albedo * INVPI;

上面的漫反射项计算中,需要用到一张预制作的贴图,模拟材质表面反射率的衰减变化过程,能量的转换和守恒。

sheen albedo map



评论

此博客中的热门博文

Shader - Hair & Fur

Shader - Skin & SSS

一个Mesh的半透明类型