TECHARTNOMAD | TECHARTFLOWIO.COM

TECH.ART.FLOW.IO

[번역][올드스쿨]My little journey to next gen skin shading.

jplee 2023. 10. 4. 15:59

역자의 말.

2023년이라는 시대(?)에 아직도 Pre-Integrated Skin 을 놓을 수 없다는 것이 문제가 아닌가~ 라는 생각을 하게 되는 요즘입니다.

Scalability 에 맞춰서 셰이딩 모델 자동 변경 디파인 작업을 하다가 여기까지 오게 되었는데요....

Penner 의 BRDF lut 과 Unreal Engine 의 BRDF lut 의 차이가 있음으로 간단히 이 기사를 번역 해 봤습니다. 알쓸신잡 일 수도 있지만요~


원문

 

 

My little journey to next gen skin shading.

Computer graphics and real time rendering.

grephicsnerd.blogspot.com

최근 저는 스킨 셰이딩 모델에 관한 논문 / UE4 셰이더 코드 / 다양한 웹 페이지를 읽으며 시간을 보냈습니다. 매우 흥미로웠고 몇 가지 성과가 있어서 공유하고자 합니다.


Sub Surface Scattering
피부는 반투명 표면이며 일반적으로 산란 이론에 기반한 셰이딩 모델을 사용하여 렌더링됩니다.

Light enters at some point and travels inside of translucent tissue and comes out at other point. This looks simple but needs some tricks to work in real time renderer.

Diffusion Profile
모든 적절한 스킨 셰이딩 모델은 이 이론과 데이터를 기반으로 합니다. 이 이론은 입사점에서의 거리에 따라 빛이 어떻게 산란되는지를 설명합니다.
사람들은 실제 피부를 사용하여 빛이 얼마나 산란되는지 데이터를 측정합니다.

Perpendicular laser on real skin
컬러 채널 간 확산 곡선 차이
가우시안 함수를 사용하여 이 곡선에 맞추기
실제 적합 가우시안 파라미터

그리고 커브는 가우시안 함수의 합에 맞춰져 있습니다. 이 맞춰진 함수는 인접한 확산 색상 픽셀을 흐리게 하거나 확산 BRDF 텍스처를 사전 통합하는 데 사용됩니다. 인터넷에 아시아계 또는 아프리카계 미국인의 측정 데이터가 있는지 궁금하지만 성공하지 못했습니다. 피가 파란색인 외계인은 어떨까요? 나중에 걱정해야 할지도 모르겠네요.

 

Screen Space Sub Surface Scattering
Jorge Jimenez's method.

 

Screen-Space Perceptual Rendering of Human Skin

We propose a novel skin shader which translates the simulation of subsurface scattering from texture space to a screen-space diffusion approximation. It naturally scales well while maintaining a perceptually plausible result. This technique allows us to en

www.iryoku.com


핵심 아이디어는 장착된 가우시안 커널을 사용하여 화면 공간의 확산 조도를 흐리게 하는 것입니다. 물론 블러 거리는 깊이와 각도에 따라 조정되어 정확합니다.
이 기법은 디퍼드 렌더러에 매우 적합하며 품질도 매우 우수합니다.
그러나 기본 확산 조도가 낮고 블러가 너무 많이 보이는 낮은 품질로 인해 이것이 최선의 방법이라는 데 동의하지 않는 사람들도 있지만 여전히 훌륭한 피부 렌더링 방법입니다.
제 생각에는 UE4 버전의 서브서피스 프로파일이 완벽하기 때문에 이에 대해 많은 연구를 하지 않았습니다.

Pre-Integrated Skin (Penner)
Another popular method is Penner's Pre-Integrated Skin.

 

Penner pre-integrated skin rendering (siggraph 2011 advances in real-time rendering course)

Penner pre-integrated skin rendering (siggraph 2011 advances in real-time rendering course) - Download as a PDF or view online for free

www.slideshare.net

기본 아이디어는 피부 표면을 원으로 가정하고 두 가지 매개 변수(피부 표면의 경사각과 곡률)에 따라 확산 프로파일을 통합하는 것입니다. 그는 이 두 가지 요소가 피부 산란에서 가장 중요한 부분이라고 생각합니다.

 

이렇게 하면 아래와 같은 텍스처가 생성됩니다.


실제 hlsl 셰이더 코드는 다음과 같습니다,

float3 ScatteredLight = Texture2DSampleLevel(PreIntegratedBRDF, PreIntegratedBRDFSampler, float2(saturate(dot(N, L) * .5 + .5), Curvature), 0).rgb;
U : 코사인으로 색인화

 

 V : r(곡률)로 인덱싱
 
이 기술에는 다른 많은 세부 사항이 있지만 기본 아이디어는 다음과 같습니다.

 


 

 

 
UE4 버전의 사전 통합 스킨 셰이딩 모델
전체적인 구조는 동일합니다,
-사전 통합 BRDF 텍스처(파라미터와 같은 코사인 및 곡률에 의한 인덱스)

하지만 UE4 버전과 원본 사이에는 몇 가지 차이점이 있습니다.
-사전 통합 스킨 BRDF는 그림자가 있는 영역에만 적용됩니다.
음영이 없는 영역은 기본적으로 라이팅되어 음영 처리됨(이는 잘못되어 피부를 너무 밝게 만듭니다).
-BRDF 텍스처는 컬러 채널(주파수)에 따라 디퓨전 프로파일이 달라지지 않습니다.

텍스처 톤이 회색입니다.

BRDF 텍스처에는 그레이스케일(컬러 채널 간 동일한 확산)이 포함되어 있으며 아티스트가 제공한 서브서피스 컬러가 곱해집니다.
사실 아티스트가 제공하는 서브서피스 컬러는 나쁘지 않은 아이디어입니다. 하지만 UE4의 사전 통합된 스킨 셰이딩 모델을 사용하여 사실적인 사람의 피부를 만드는 것은 매우 어렵습니다.
 
에픽에서 고퀄리티 스킨 렌더링으로 서브서피스프로필 모델을 추천하는 이유도 바로 이 때문이라고 생각합니다.

원본 논문에 따라 제대로 구현하면 아래와 같은 결과를 얻을 수 있습니다.

내 구현

디퍼드 렌더러의 한계로 인해 노멀 블러링을 구현할 수 없었고 거친 노멀 맵으로 약간 거칠게 보일 수 있었지만 아트 디렉션에는 괜찮았습니다. (노멀 맵을 제어할 수 있었기 때문입니다).
 
반투과
이 두 가지 방법을 사용하면 렌더링된 사람의 피부가 이미 피부처럼 보입니다. 하지만 더 많은 것이 필요합니다.
피부는 반투명 조직이기 때문에 입사광은 실제로 얇은 부분을 투과합니다.
그리고 아래와 같은 효과가 있어야 합니다,
얇은 귀를 통해 투과되는 빛.
 
Jorge Jimenez 는 이에 대한 논문을 썼습니다.
 
 

Real-Time Realistic Skin Translucency

April 23, 2010 Web launched! Diffusion theory allows the production of realistic skin renderings. The dipole/multipole models allow us to solve challenging diffusion theory equations in a very efficient manner. By using texture-space diffusion, a Gaussian-

iryoku.com


가장 중요한 아이디어는 빛이 입사하는 지점부터 실제 음영 지점까지의 두께를 계산하는 것입니다. 이 두께를 통해 얼마나 많은 빛이 투과되는지 알 수 있습니다.
그림자 투영 셰이더에서 이 두 점을 알고 있습니다. (그림자 깊이 값과 셰이딩된 월드 포인트)

사실 UE4는 이미 이 투과율 값을 계산하고 있으며, 이를 "서브서피스 섀도 텀"으로 정의합니다. 이 텀은 보통 다양한 서브서피스 라이팅 텀에 곱해집니다. (예: TWO_SIDED_FOILAGE). 하지만 두 스킨 셰이딩 모델 모두 이 효과가 부족한 것 같습니다.

그래서 미리 통합된 스킨 셰이딩 모델에 Jorge Jimenez의 반투명 효과를 추가했습니다.
환경 조명 사용



그림자 깊이 범위 정밀도 문제로 인해 두께(투과율 또는 표면 아래 그림자 항)를 계산하는 데는 스팟 라이트가 가장 정확한 것으로 보입니다. 포인트 라이트에는 이 기능이 없습니다.

간접광을 사용한 스킨 BRDF
위의 방법은 모두 직접 조명에 대한 것입니다. 가끔 게임 캐릭터가 간접 조명(그림자 영역)만 있는 조명 조건에 있을 수 있습니다. 그러면 이 모든 멋진 스킨 셰이딩이 사라집니다.

UE4는 서브서피스 컬러를 (구형 하모닉스 프로브에서) 확산 조도에 곱합니다. 이 정도면 괜찮을 수 있습니다. 하지만 이 슬픈 상황에 대해 우리가 할 수 있는 일이 있습니다. 레디 앳 던의 그래픽 프로그래머들은 간접 프로브를 사용하여 피부 BRDF를 적용하는 훌륭한 기술을 제안합니다.

아이디어는 다음과 같습니다,
조도 구형 고조파 프로브로 점을 찍는 전달 함수로 클램핑된 코사인을 사용합니다. 이것은 클램핑 코사인 함수를 나타내기 위해 투영된 구역 고조파 계수입니다.
RAD 프로그래머의 아이디어는 확산 피부 BRDF를 표현하기 위해 투영된 특수 영역 고조파 전달 함수를 사용하는 것입니다. 그들은 논문에서 그들의 아이디어를 친절하게 설명했습니다.
 

SIGGRAPH 2013 Course: Physically Based Shading in Theory and Practice

© Disney/Pixar 2013. Course Description Physically based shading is increasingly important in both film and game production. By adhering to physically based, energy-conserving shading models, one can easily create high-quality, realistic materials that ma

blog.selfshadow.com


이를 구현한 아래 이미지는 곡률에 따라 인덱싱된 영역 고조파 계수를 생성한 것입니다.
X축은 곡률, Y축은 영역 고조파 순서입니다.
 
First row : order 0, Second row : order 1, Third row : order 2 x axis : surface curvature (with 30000 randome sample during monte carlo integration)



그리고 이것이 그 결과입니다. 결과는 꽤 인상적이었습니다.

라이트 프로브의 일반 확산 조도와 비교할 수 있습니다.

사용된 조명 조건입니다.

Emissive sphere and 1 light probe(no direct light)

아래 생성 코드를 사용하여 3개의 구역 고조파 계수를 투영합니다.

Order 0

_func = [this](double theta, double rInv)
            {
                float R = rInv * 255;
                float radius = 2.0f * 1.f / ((R + 1) / (float)SizeX);

                float cosTheta = FMath::Cos(theta);
                auto BRDF = IntegrateDiffuseScatteringOnRing(cosTheta, radius);

                return 0.28209479177 * BRDF.X *sin(theta);
            };
            D0R = 2 * PI * MonteCarloIntegral1D(0, PI / 2, NumMonteCarloSample, rInv);


Order 1

_func = [this](double theta, double rInv)
            {               
                float R = rInv * 255;
                float radius = 2.0f * 1.f / ((R + 1) / (float)SizeX);

                float cosTheta = FMath::Cos(theta);
                auto BRDF = IntegrateDiffuseScatteringOnRing(cosTheta, radius);
                return 0.4886025119 * cos(theta) * BRDF.X * sin(theta);
            };
            D1R = 2 * PI * MonteCarloIntegral1D(0, PI / 2, NumMonteCarloSample, rInv);


Order 2

_func = [this](double theta, double rInv)
            {
                float R = rInv * 255;
                float radius = 2.0f * 1.f / ((R + 1) / (float)SizeX);

                float cosTheta = FMath::Cos(theta);
                auto BRDF = IntegrateDiffuseScatteringOnRing(cosTheta, radius);
                return 0.31539156525 *  (3 * pow(cos(theta), 2) -1) * BRDF.X *sin(theta);
            };
            D2R = 2 * PI * MonteCarloIntegral1D(0, PI / 2, NumMonteCarloSample, rInv);


저는 이 링크에서 스킨 BRDF 통합을 사용했습니다.

 

In-depth: Skin shading in Unity3D

In this reprinted <a href="http://altdevblogaday.com/">#altdevblogaday</a> in-depth piece, Iron Galaxy Studios programming intern Jon Moore looks at rendering h

www.gamedeveloper.com

나중에 더 발전된 스킨 렌더링 기술이 나올 것 같습니다. 하지만 지금은 이 정도면 충분합니다.