前端路上的小学生

UE毛发系统底层剖析

本文未经允许禁止转载
作者:Heskey0
B站:https://space.bilibili.com/455965619
邮箱:3495759699@qq.com


Unreal Engine - Hair Shading Model

Heskey0的个人空间

Papers

unreal-engine-hair-and-fur-whitepaper

SIGGRAPH 2016 Course: Physically Based Shading in Theory and Practice

unreal-engine-hair

dualscattering

NVIDIAsiggraph2008

EGSR2011

Marschner-Siggraph2003

一. Fur Structure

outer --> inner

  • cuticle

  • cortex : absorbs light

  • medulla : scatters light

paths:

  • R
  • TT
  • TRT

notation p represent R, TT or TRT

二. Radiance

curve irradiance : power per unit length

curve intensity : intensity per unit length

bidirectional scattering function :

S(ωi,ωr)=dL¯r(ωr)dEi(ωi)

the most prominent feature in the scattering function is the specular highlight that occurs approximately when θr=θi

BCSDF : bidirectional curve scattering distribution function

三. Basic concept

normal plane : 垂直于虚拟法线的平面

incidence plane : 由入射光线与入射点处的法线所构成的平面被称为入射面

θi,θr : inclinations with respect to the normal plane

θd=θi+θr2 : the difference angle

θh=θi+θr

ϕi,ϕr : azimuth

ϕ=ϕrϕi

四. Theory

because of the symmetry of a cylinder, the 4D scattering function can be factored into a product of two 2D terms.

One term, capture the θ dependence, called M : longitudinal scattering function , 纵向的散射方向

One term, capture the ϕ dependence, called N : azimuthal scattering function , 头发横截面的散射方向

S(ϕi,θi;ϕr,θr)=MR(θi,θr)NR(η(θd);ϕi,ϕr)/cos2θd+MTT(θi,θr)NTT(η(θd);ϕi,ϕr)/cos2θd+MTRT(θi,θr)NTRT(η(θd);ϕi,ϕr)/cos2θd

for M, 符合高斯函数 :

[EGSR2011 An Energy-Conserving Hair Reflectance Model] 4.1

MR=g(βR,θhαR)MTT=g(βTT,θhαTT)MTRT=g(βTRT,θhαTRT)

where g is a normalized Gaussian of longitudinal inclination θ, β is a roughness term

g(β,θ)=eθ2/(2β2)2πβ

for N, 可做一些简化 :

1. R

[EGSR2011 An Energy-Conserving Hair Reflectance Model] 4.1

NR=|cos(ϕ/2)|4A(0,h)

where A : Attenuation term

A(0,h)=F(η,12+12(ωiωr))

where F : Schlick Fresnel

F(η,x)=F0+(1F0)(1x)5F0=(1η)2(1+η)2

other paths too complex and minor impact

2. TT

[A Data-Driven Light Scattering Model for Hair] 3.2

Np(θi,θr,ϕ)=1211A(p,h)Dp(ϕΦ(p,h))dh

where A : Attenuation term

A(p,h)=(1f)2fp1T(μa,h)p

where T : Absorption term

T(μa,h)=exp(2μa1+cos(2γt)cosθt)

and

f=F(η,cos(θd)1h2)

float f = Hair_F( CosThetaD * sqrt( saturate( 1 - h*h ) ) );
float Fp = Pow2(1 - f);
float Tp = exp(-AbsorptionColor * 2 * abs(1 - Pow2(h * a) / CosThetaD));

we only need to evaluate h, D, T

由于复杂性,需要做一些简化:

2.1 D :

DTT(ϕ)=D(ϕ,0.35,π)D(ϕ,s,μ)=eϕμss(1+eϕμs)2

approximation :

DTT(ϕ)e3.65cosϕ3.98

 float Np = exp( -3.65 * CosPhi - 3.98 );
2.2 eta :

η=η2sin2θdcosθd

approximation :

η=1.55η1.19cosθd+0.36cosθd

error < 0.68%

2.3 h :

a=1ηhTT=sign(ϕ)cosϕ21a22asign(ϕ)sinϕ2

approximation :

hTT(1+a(0.60.8cosϕ)cosϕ2)

float h = CosHalfPhi * ( 1 + a * ( 0.6 - 0.8 * CosPhi ) );
2.4 T :

approximation :

T(θ,ϕ)=C1h2a22cosθd

3. TRT

h, the offset for Fresnel :

hTRT=32

absorption term :

TTRT(θ,ϕ)=C0.8cosθd

Distribution :

DTRT(ϕ)=34D(ϕ,0.15,0)DTRT(ϕ)e17cosϕ16.78

But it’s still missing something ! We need to render a volume of hair not just a single strand

4. Multiple scattering

五. Implementation

file : HairBsdf.ush

function : HairShading()

【notice : HairShadingRef() is a Reference, 由宏REFERENCE控制是否开启,默认是关闭。

HairShading()是HairShadingRef()的近似估计, Lots of curve fitting and function aproximation

Coding

//R
S += Mp * Np * Fp * (GBuffer.Specular * 2) * lerp(1, Backlit, saturate(-VoL));
//TT
S += Mp * Np * Fp * Tp * Backlit;
//TRT
S += Mp * Np * Fp * Tp;
//Multiple Scattering
float3 EvaluateHairMultipleScattering(
	const FHairTransmittanceData TransmittanceData,
	const float Roughness,
	const float3 Fs)
{
	return TransmittanceData.GlobalScattering * (Fs + TransmittanceData.LocalScattering) * TransmittanceData.OpaqueVisibility;
}
S  = EvaluateHairMultipleScattering(HairTransmittance, ClampedRoughness, S);
S += KajiyaKayDiffuseAttenuation(GBuffer, L, V, N, Shadow);

(Np * Fp) represent N : azimuthal scattering function

for M

//R
float Mp = Hair_g(B[0] * BScale, SinThetaL + SinThetaV - Shift);
//TT
float Mp = Hair_g( B[1], SinThetaL + SinThetaV - Alpha[1] );
//TRT
float Mp = Hair_g( B[2], SinThetaL + SinThetaV - Alpha[2] );

for N = (Np * Fp)

//R
float Np = 0.25 * CosHalfPhi;
float Fp = Hair_F(sqrt(saturate(0.5 + 0.5 * VoL)));
//TT
float Np = exp( -3.65 * CosPhi - 3.98 );
float h = CosHalfPhi * ( 1 + a * ( 0.6 - 0.8 * CosPhi ) );
float f = Hair_F( CosThetaD * sqrt( saturate( 1 - h*h ) ) );
float Fp = Pow2(1 - f);
//TRT
float Np = exp( 17 * CosPhi - 16.78 );
float f = Hair_F( CosThetaD * 0.5 );
float Fp = Pow2(1 - f) * f;

where

float Hair_g(float B, float Theta)
{
	return exp(-0.5 * Pow2(Theta) / (B * B)) / (sqrt(2 * PI) * B);
}

Parameters

  • BaseColor
    • C in the equation
  • Specular
    • Scales the R term
  • Roughness
    • βR=Roughness2
    • βTT=0.5Roughness2
    • βTRT=2Roughness2
  • Scatter
    • Scales multiple scattering term
  • Shift
    • αR=2Shift
    • αTT=Shift
    • αTRT=4Shift
posted @   Heskey0  阅读(317)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南

本站勉强运行 1191 天 16 小时 08 分 55 秒

喜欢请打赏

扫描二维码打赏

支付宝打赏

点击右上角即可分享
微信分享提示