SSS
SSS(Sub-Surface Scattering) (피하산란)
- BSSRDF(Bidirectional surface-scattering reflectance distribution function)
- 입사한 지점과 반사되는 지점이 다름.
- 실시간으로 계산하기에는 부하가 큼
- 여러 기법들
- Texture-Space Diffusion
- Scren-Space SSS
- Pre-Integrated Skin Shading
- other Fake/Fast/Approximated SSS
TSD / Texture-Space Diffusion
SSSSS / Scren-Space Sub-Surface Scattering
- https://www.iryoku.com/sssss/
- https://www.iryoku.com/screen-space-subsurface-scattering/
- https://unityshader.hatenablog.com/entry/2016/12/25/175333
- https://docs.unrealengine.com/udk/Three/ScreenSpaceSubsurfaceScattering.html
- 2018 - [Siggraph2018] Efficient screen-space subsurface scattering using Burley’s normalized diffusion in real-time - Evgenii Golubev (Unity Technologies)
PISS / Pre-Integrated Skin Shading
-
LookUpTexture 이용
-
fwidth : abs(ddx(x)) + abs(ddy(x))
-
DirectX는 ddx_fine/ddy_fine함수도 있음.
half diffuse = LdotN;
half curvature = saturate(length(fwidth(N)) / length(fwidth(positionWS)) * curvatureScale);
half2 pissUV;
pissUV.x = diffuse;
pissUV.y = curvature;
half3 pissTex = SAMPLE_TEXTURE2D(_PissTex, sampler_PissTex, pissUV).rgb;
LocalThickness
// local thickness
half localTicknessTex = SAMPLE_TEXTURE2D(_LocalThicknessTex, sampler_LocalThicknessTex, uv).r;
half3 H = normalize(L + N * _Distortion);
half VdotH = pow(saturate(dot(V, -H)), _Power) * _Scale;
half backLight = _Attenuation * (VdotH + _Ambient) * localTicknessTex;
other Fake/Fast/Approximated SSS
half halfLambert = NdotL * 0.5 + 0.5;
half3 fakeSSS = (1 - halfLambert) * _SSSColor;
half3 color = halfLambert + fakeSSS;
half rim = 1 - NdotL;
// 역광일때만 하려면 VdotL처리
// rim *= VdotL;
half3 fakeSSS = pow(rim, _SSSPower) * _SSSMultiplier * _SSSColor;
half3 color = lambert * fakeSSS;
half rim = 1 - NdotL;
half3 fakeSSS = SAMPLE_TEXTURE2D(_SSS_RampTex, sampler_SSS_RampTex, half2(rim, 0)).rgb;
half2 brdfUV;
brdfUV.x = dot(N, L);
brdfUV.y = dot(N, H);
half3 brdfTex = SAMPLE_TEXTURE2D(_BrdfTex, sampler_BrdfTex, brdfUV * 0.5 + 0.5).rgb;
half LdotN = dot(L, N);
half LdotV = dot(L, V);
half2 rampUV;
rampUV.x = LdotN * 0.3 + 0.5;
rampUV.y = LdotV * 0.8;
half3 rampTex = SAMPLE_TEXTURE2D(_RampTex, sampler_RampTex, rampUV).rgb;
아니면 Albedo맵 / Normal맵 자체에 Blur(rgb에 가중치를 주어서)를 적용한다.
Ref
- Cheap realisticskinshading kor
- SIGGRAPH2010 - Uncharted 2: Character Lighting and Shading
- GDC2011 - Iterating Realistic Human Rendering: Boxers in FIGHT NIGHT CHAMPION
- https://zhuanlan.zhihu.com/p/97892884
- https://blog.naver.com/checkjei/60167971452
- https://therealmjp.github.io/posts/sss-intro/
- https://mgun.tistory.com/1600
- NVIDIA
- 기법별
- using Half lambert
- Pre-Integrated Skin Shading
- GPU Pro 2 - Pre-Integrated Skin Shading
- LocalThickness
- GPU Pro 2 - Real-Time Approximation of Light Transport in Translucent Homogenous Media
- GDC 2011 – Approximating Translucency for a Fast, Cheap and Convincing Subsurface Scattering Look
- Fast Subsurface Scattering in Unity(1, 2)
- 실시간 SSS 셰이더 구현하는 세가지 방법(1, 2, 3)
- SSS Shader for Unity
- Normal blur
- [ 기고 ] Normal Blur Sub-Surface Scattering
- NOC2012 - SubSurfaceScattering + UDK Custom Shader 권오찬
- SIGGRAPH2011 - Penner pre-integrated skin rendering
- BRDF