tajourney tajourney
  • 首页
  • 渲染
    • PBR
    • NPR
  • 引擎
    • Unity
    • UE
  • DCC
    • Houdini
    • PhotoShop
    • Blender
  • 优化
  • 工具
  • 杂谈
    • 游戏
  • 友链
  • 关于
    • About Me
    • 网站公告
    • 维护记录
    • QA
  • 注册
  • 登录
首页 › 渲染 › PBR › Unity PBR轮子(3)SkinLit

Unity PBR轮子(3)SkinLit

糯米
2年前PBR阅读 1,304

本篇文章的理论基础主要来自SIGGRAPH2011的一篇PPT(见专栏导言附录7),主要使用了预积分(LUT)的方案。

以及部分参考了GDC动视分享(见专栏导言附录4),这也是目前UE在用的Separable SSS的方案(当然UE里也有预积分的方案)。

Unity PBR轮子(3)SkinLit-tajourney
UE SeparableSSS.ush

随着模型越来越精细,如果我们渲染能力不提升上去的话,会不可避免的陷入“恐怖谷”。所以有必要对人体材质进行更高级的渲染。而且除此之外,我们还会对皮肤进行更“精美”的定制(),以符合人的审美。(这个不难理解,毕竟现在是个手机相机都附带类似美颜的功能了233)。

皮肤渲染技术发展史

Unity PBR轮子(3)SkinLit-tajourney
引用自https://zhuanlan.zhihu.com/p/42433792

渲染分析

Unity PBR轮子(3)SkinLit-tajourney

除了上面PPT说的部分,一个完整的皮肤渲染包含了很多,比如细节纹理等。本篇我们准备的素材来自《底特律变人》中的Kara小姐姐,下图是游戏中的一段CG:

Unity PBR轮子(3)SkinLit-tajourney

SSS(次表面散射)

关于次表面散射的理论部分,可以参考我单独写的文章,本篇采用的是Pre-Integrated Skin的方案。

(1)计算曲率

看完上面的文章,你应该看完了曲率公式的推导,那么曲率怎么在shader里求呢?还是以下面的这篇siggraph为例:

Unity PBR轮子(3)SkinLit-tajourney

我们需要知道模型的normal以及pos,然后利用fwidth函数即可。

        float deltaNormalWS = length(fwidth(N));

        float deltaPosWS = length(fwidth(posWS));

        //引入Bias和Scale进行调节
        Curvature = saturate(CurvatureBias + CurvatureScale * 0.001 * deltaNormalWS/deltaPosWS);
Unity PBR轮子(3)SkinLit-tajourney
曲率(Bias = 0 , Scale = 1)

不过,需要注意的是在低端机下(不支持OpenGLES2.0 +),无法使用fwidth这个API。代替的方式是我们可以预计算曲率,生成一张曲率图。

(2)Bent Normal

Unity PBR轮子(3)SkinLit-tajourney

为了处理皮肤细小表面的细节,siggraph中提到对光照的不同通道使用不同的法线贴图(4种),但是这种做法过于耗费内存,所以提出了Bent Normal的做法。注意,这里的Bent Normal和计算AO时提到的Bent Normal并不完全相等(都是修改法线的技术)。这里是模拟皮肤表面的表面细节,是用模糊的方法(采样法线图的mipmap)做的,也可以叫做pre-integrated normal maps,AO里提到的Bent Normal则是从一个点到其他点的未被遮蔽的所有法线的平均法线方向。

float4 bentNormal = SAMPLE_TEXTURE2D_LOD(_NormalMap,sampler_NormalMap,input.uv,_BentNormalMipLevel);
bentNormal =  UnpackNormalScale(bentNormal,_Normal); //和Normal共用一套sampler

需要注意的是上面求得的是tangent space的bentnormal,用TBN矩阵转换一下。

在Unity中对比下使用BentNormal前后:

Unity PBR轮子(3)SkinLit-tajourney
BentNormal OFF

Unity PBR轮子(3)SkinLit-tajourney
BentNormal On

(3)SSS效果总览:

Unity PBR轮子(3)SkinLit-tajourney
关闭SSS
Unity PBR轮子(3)SkinLit-tajourney
开启SSS
Unity PBR轮子(3)SkinLit-tajourney
SSS On/Off

Specular Reflections

动视PPT的分享中介绍到这部分,使用了Two Lobes Rendering(specular lobes,也可以叫做Dual Specular(GGX))+ Microgeometry Render(Noise)的技术。

Two Lobes Rendering 这部分其实就是用不同的Roughness叠加了两层高光,需要注意的是要遵循能量守恒。

而Microgeometry Render实际上是就是多用了个Detail Map。

Specular Reflections效果总览:

Unity PBR轮子(3)SkinLit-tajourney
specular lobes off
Unity PBR轮子(3)SkinLit-tajourney
specular lobes on
Unity PBR轮子(3)SkinLit-tajourney
specular lobes off/on
Unity PBR轮子(3)SkinLit-tajourney
Microgeometry Render

GI(Faking)

在StandardLit中我已经讲过SH+IBL的实现,不同的是specularAO的处理。在专栏导言附录4的PPT中,作者同时采用了多种AO结合。

如何在URP中拿到SSAO的结果在SimpleLit中也讲了,不同的是在StandardLit中我们是通过GetSpecularOcclusionFromAmbientOcclusion函数得到的Specular Occlusion,在PPT中作者提出了一种基于经验的获取面部皮肤Specular Occlusion的方式。

Unity PBR轮子(3)SkinLit-tajourney
float3 specularOcclusion = lerp(pow(occlusion,_SpecularPow),1.0,saturate(NoV * NoV - 0.3));

以及作者提到了一种trick方式:Color-Bleed AO

下面逐个演示效果(min with SSAO):

Unity PBR轮子(3)SkinLit-tajourney
SpecularOcclusion(From AmbientOcclusion)
Unity PBR轮子(3)SkinLit-tajourney
Fake SpecularOcclusion (SpecularPow = 8.0)
Unity PBR轮子(3)SkinLit-tajourney
Fake SpecularOcclusion (SpecularPow = 1.0)
Unity PBR轮子(3)SkinLit-tajourney
Fake SpecularOcclusion (SpecularPow = 8.0) with Color-Bleed AO

GI总览:

Unity PBR轮子(3)SkinLit-tajourney
间接光漫反射
Unity PBR轮子(3)SkinLit-tajourney
间接光镜面反射
Unity PBR轮子(3)SkinLit-tajourney

透光

见PPT 164-191

谈到了三种技术:(单采样,多重采样和球谐)

  • Single-Sample Transmittanc
  • Multi-Sample Transmittance
  • Spherical Harmonics Transmittance
Unity PBR轮子(3)SkinLit-tajourney
Unity PBR轮子(3)SkinLit-tajourney

三种方案优点和缺点:

Unity PBR轮子(3)SkinLit-tajourney

作者最后提到以上三种方案都是针对procedural light,而对于light probes的散射则可以忽略不计(影响很小)。

文中还提到了对multipole diffusion profile进行简化。

本篇我只实现简单的透光,而且transmission直接给了个定值,一些不该透射的区域也受到了影响(因为是游戏里扒的素材,游戏内并没有实现透光效果,所以没thicknessMap,我也懒得在SD里做一份了),这里主要侧重于如何实现。从thicknessMap中计算或者复杂些按照上诉方法都可以,效果肯定比下面gif里实现的更好,更细腻。

Unity PBR轮子(3)SkinLit-tajourney
Unity PBR轮子(3)SkinLit-tajourney

后记

本篇+理论篇的博客撰写花费了大约两周的时间,然而敲代码的时间加起来不到一天= =果然只敲代码的话还是爽(本篇纯代码,不含SG或者ASE),但是要整理成图文真的很费时费力。

对于Skin的实现,还有Disney SSS,目前UE4和Unity HDRP都有相应的实现方式,改天也试着实现一下。

换了个模型查看效果(gif录制有些地方压缩后变色了没办法):

Unity PBR轮子(3)SkinLit-tajourney
总览
Unity PBR轮子(3)SkinLit-tajourney
specular lobes Off/On 注意嘴唇部细节
Unity PBR轮子(3)SkinLit-tajourney
SSS Off/On 注意脸颊阴影部分

Unity PBR轮子(3)SkinLit-tajourney
Transmittanc Off/On 注意耳朵,脸颊以及眼部被遮蔽区域

3.21 后记

今天看了下URP官方实现的skinlit(因为要写hairLit顺便看了下),整理了一下差异,有时间再讲讲一些细节:

Unity PBR轮子(3)SkinLit-tajourney
Unity PBR轮子(3)SkinLit-tajourney
URP Demo

官方Demo 视频:https://www.bilibili.com/video/BV1g8411p78X

官方Demo github:https://github.com/UnityTechnologies/URP-Defender-Character-Demo

赞(3)
搜索
近期文章
  • 终末地人物渲染(更新中) 2025年3月17日
  • Unity APV体素化光栅化实现 2025年2月5日
  • Unity 不同 ReflectionProbe 打断 Instancing 解决方案 2025年1月15日
  • Renderdoc 原神截帧记录 2024年8月22日
  • Houdini VAT:Vellum Cltoh笔记 2 2024年7月17日
归档
  • 2025年3月 (1)
  • 2025年2月 (1)
  • 2025年1月 (1)
  • 2024年8月 (1)
  • 2024年7月 (2)
  • 2024年1月 (1)
  • 2023年10月 (3)
  • 2023年9月 (4)
  • 2023年8月 (5)
  • 2023年7月 (4)
  • 2023年6月 (4)
  • 2023年5月 (1)
  • 2023年4月 (3)
  • 2023年3月 (11)
  • 2023年2月 (11)
  • 2023年1月 (1)
  • 2022年7月 (1)
  • 2022年6月 (2)
  • 2022年5月 (1)
  • 2022年4月 (1)
  • 2022年3月 (1)
  • 2022年2月 (1)
  • 2022年1月 (7)
  • 3
Copyright © 2022-2025 tajourney. Dev by nuomi 版权所有.
鲁ICP备19015245号
  • 首页
  • 渲染
    • PBR
    • NPR
  • 引擎
    • Unity
    • UE
  • DCC
    • Houdini
    • PhotoShop
    • Blender
  • 优化
  • 工具
  • 杂谈
    • 游戏
  • 友链
  • 关于
    • About Me
    • 网站公告
    • 维护记录
    • QA
糯米
日语学习中
68
文章
15
评论
44
喜欢