引擎十一:体积感SSS,SSR

Posted avi9111

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了引擎十一:体积感SSS,SSR相关的知识,希望对你有一定的参考价值。

在2011年的时候,没写错,是11年前,某岛国的每年一度的graphic论坛,提出了多个贴图的次表面散射,Screen Space Subsurface Scatter

接着的2012年,同一个团队,再次提出次时代人物皮肤的研究 - XXXXX

但都不是哥这个文章展示的代码,哥没这么高端,但确实实现了一个SSS

这十年间,无数国内“牛人”提出了各种在Unity实现SSS的方法

当然,另一个SSS方法,就是最近这几年的LUT-SSS,但是就承认这是米哈游首先提出的概念有这么难么,反正哥第一次从国内看到LUT这个概念来自原神的分享,但这也不是也下内容涵盖的

(嗯,上面提出了5种sss,这个文章只是其中一种)

个人引擎还是停摆中,正参考一个不错的开源引擎:overload,采集灵感,也因为上一节的反射探针该引擎没有(个人引擎更是没有),所以还是继续用Unity做以下演示

次表面散射入门

次表面散射 - 以下简称SSS。。。。。。。。。。。。

上一节完成了PBR渲染,实现反射(基于Cubemap),

本来觉得像素风手和武器发光的部分就酱

<主要是想偷懒,lut不想研究,关键字,米哈游,原神,渲染分享>

结果这个亚索皮肤,绿色手发光的部分,看上去用SSS实现也不错

<做了一个开关,可以选择0.关闭,1.全身,3.detailsMap只映射手的部分>

一般的SSS可以用在玉石等半透明渲染

这个文章说到皮肤的 lut 实现:

谈一谈英雄联盟手游渲染2——高级篇 - 知乎

但我不确定是不是同一样的东西,某大神提出的反面再创造一个光,正反两面打光就可以做到”简单“的Mobile版本的次表面散射:

关键的关键还是在于这是打光,也就还是一个光照模型

原理

公式就不在这里推了,不画图了,无非就是一个平面,一个光线反射+折射,网上很多

<当然各种 N L V H 的定义必须掌握,个人水平不到,说不清楚,如从0开始学,还请自行百度>

掌握渲染的方法有4个

看书

日常观察

看视频

看博客

光照模型公式快速略过

(待补充)

关键代码:

inline float SubsurfaceScattering (float3 viewDir, float3 lightDir, float3 normalDir, 
                float frontSubsurfaceDistortion, float backSubsurfaceDistortion, float frontSssIntensity)

    float3 frontLitDir = normalDir * frontSubsurfaceDistortion - lightDir;
    float3 backLitDir = normalDir * backSubsurfaceDistortion + lightDir;
                
    float frontSSS = saturate(dot(viewDir, -frontLitDir));
    float backSSS = saturate(dot(viewDir, -backLitDir));
                
    float result = saturate(frontSSS * frontSssIntensity + backSSS);
    return result;
float sss = SubsurfaceScattering(i.viewDir,i.lightDir,i.normalDir,_FrontDistortion,
                    _BackDistortion,
                    _FrontIntensity);
float3 sssColor = lerp(_InnerColor,_LightColor0,saturate(pow(sss, _InnerColorPower))).rgb * sss;
float3 finalColor = sssColor + col.rgb;//最终需要次表面散射,加上原颜色

后记:

这个实现有bug的,某些角度会有强白光,转动远镜头时看上去”一闪一闪的“代码和大神一模一样的,大神还用了4盏点光源,所以避免了单一平行光的这个强白光bug,这个之后再看怎么修复吧;

虽然说用了Fake的SSS方法(不完善,新方法,必然引入了bug),减少了性能消耗,但没有真机测过,要是上测试,还会有更多各种BUG;

只是符合个人状态的实现,主要想讲一些SSS理论,因为实现真的可以多种多样,各个团队需求也不一样;

有空还是要把真的SSS实现一遍,并掌握;

因为是Fake的方法,两面打光这个”设计“很厉害(大神的思路),但确实不是理工科的设计,整个渲染肯定不会很”物理化“,肯定不是纯粹的PBR;

参考:

Simple Subsurface Scatterting for Mobile – (一)通透材质的次表面散射 – WalkingFat

https://www.youtube.com/watch?v=RPkhbjmmvS0

​​​​​​Translucent Shader for Unity3D | James O'Hare, Game Character Artist: Blog


【Unity Shader】在URP里写Shader(三):URP简单光照Shader - 知乎

后记之后记

真的不记得当年写过上面这样的文档,现在再也写不出来了(公式推导,过两天11月前应该会补一下吧)

参考x2

有2个开源项目,不容易了,感觉现在或者一直以来TA都没点分享精神,这个有分享算不错的了。。。。。

https://www.jianshu.com/p/6a5e1f780988





 

以上是关于引擎十一:体积感SSS,SSR的主要内容,如果未能解决你的问题,请参考以下文章

0018---求球的表面积和体积

MAPGIS栅格数据表面积体积土方量计算分析对比

0017---正方体的表面积和体积

c语言:求圆周长圆面积圆球表面积圆球体积圆柱体积。

求立方体的体积表面积(c++)

Java实现圆柱体表面积和体积的计算