0基础UnityURP渲染管线人物渲染_皮肤_头发_眼睛_各向异性_SSS之实践

关于次表面散射

一般脸部的Shader,都是脸部最重要,

- 这和同人的需求不同

- 而且国内手游对这样的脸部实现需求就还好

- 本人美术不懂,

- 本人比较懒,图形学原理也不懂,

- 本人还是有些追求的,之后可能会说怎么调贴图,

所以,今天还只是说说HLSL的代码

不吹不黑,参照国外一个皮肤Skin效果实现的次表面散射

真的,国外随便一个美术老哥都能写程序(由于商业原因,他不会告诉你他用了Ampliy Shader Editor)

<所以这样的shader代码就看过就好,不要考虑扩展性,魔改性了,当然,稳健性性还是有的,外国人做事还是比较稳>

*其实一比较,Unity官方的URP LDRP的Shader内核框架还是比较靠谱,非常工业化

*写完这个文章后,还发现这个英国老哥真的就只会Ampliy Shader Editor(个人认为最好的连连看,没有之一),洋洋傻傻写了几千行,写了几年,写出这几个Shader

目录

关于次表面散射

RRF_HumanShaders/Skin/RRF_HSP_URP_SkinBasic-------------------------------------------------

SSSMap 和国内的 LUT 贴图区别点

RRF_HumanShaders/HairShader2/HairShader2_AS_RRF_VRTC_URP----------------------------

<效果可以说相当强悍>

 其他网站上高赞的头发渲染

RRF_HumanShaders/EyeShaders/EyeShader_Model4URP-------------

后记

参考:


RRF_HumanShaders/Skin/RRF_HSP_URP_SkinBasic
-------------------------------------------------

SSSMap - 带有 subsurface scatter 信息的贴图;如果暂时没有这个贴图,就使用Albedo,如果有能力创造这个贴图,A通道==Thickness,越白色代表皮肤越薄,如耳朵,鼻孔,眼睛周围等

SSS Mip - 一个模糊控制,让SSS效果更柔和

SSS_FromAlpha - SSS的A通道控制项

_Final_SSS - 和SSS_FromAlpha做了两层插值,这个值调成1好了

SSSMap 和国内的 LUT 贴图区别点

* 目测,它两原理是一样的,都是

* 其实上面关于皮肤渲染的设置,很多都是很废的,关键只有一个:如何调出皮肤的LUT贴图

 美术我们不懂,就看看代码吧

//居然还是用Ampliy shader或者Forge写的代码,不意外的意外
float4 tex2DNode45 = tex2D( _SSS_Map, uv_SSS_Map );

我们来看看Lut的原理:

《这里。。。省略推导LUT 1000行公式》

《这里。。。省略次表面散射1000个推理图》

《这里。。。省略5个论文》

《这里。。。省略了2个演讲》

《这里。。。生路了十个视频》

然后,我们有了这样的公式:

(从下面代码找到一个老朋友:NdotL, 因为是lut图,基本就是uv采样皮肤的阈值,NdotL控制U(左右),scatter线性控制V(上下))

	half NdotL = saturate(dot(normalWS, light.direction));
	float lutU = NdotL * 0.5 + 0.5;
	float lutV = scatter + _CuvratureOffset;
	half3 lut = SAMPLE_TEXTURE2D(_ScatterLUT, sampler_ScatterLUT, float2(lutU, lutV)).rgb;
	half3 radiance = light.color * light.distanceAttenuation * light.shadowAttenuation * lut;

据说是王者荣耀的还原效果,可以和上面代码比较(同样是uv采样lut)

//采样代码
float3 SSS = tex2D(_SSSMap,float2(NL*0.5+0.5,Mix.b)))

我们来看看国外老哥的皮肤Shader原理:

《代码就不贴了,不是商业考虑,而是真的不值得贴》

//伪代码
float NdotL;
float SSSColorInterval = lerp(.r,.a,_FromAlpha);
float4 SSSColor; 
float4 color = NdotL * SSSColorInterval * clamp(SSSColor) * LitAtten * (LitPower * NdotL);

RRF_HumanShaders/HairShader2/HairShader2_AS_RRF_VRTC_URP-----------------------------------------------------

 

采用了RVTC

RVTC == Validation(R) Root(G) Tip(B) Cutout(A)  

<效果可以说相当强悍>

就一个albedo的贴图,To -> PVTC,只要刚好A通道的CutOut美术设计好,即可达成头发细碎

* 而看代码后,当然发现这个老哥RGB三个通道都是没用到的,只用了A通道,我随便找的一个贴图刚好对上了A通道,这也行

《Extrac的效果也是很炸裂》

 Extrac效果1-2

 其他网站上高赞的头发渲染

是怎么回事?其实效果很一般的,其实只实现了高光《截图之后再放出吧》

看看,对比没实现前普通BaseColor贴图,上面的高赞的效果其实只实现了高光转移

 《就是,远看还行》,光靠高光肯定不行

  • 头发一根根的效果最终还是靠cutout
  • 浓密程度,各项异性也需要深究
  • 头发"动画"飘动又是另外一个课题

RRF_HumanShaders/EyeShaders/EyeShader_Model4URP-------------

眼睛的渲染:

一般眼影:shadow|lashes

眼睫毛贴错了,眼球不是正中央,专业美术也未必人人是眼神专家 

2个无用知识点又增加了

 

 原稿长这样,有点要放弃了,摆烂了

后记

虽然这个文章有吐槽英国老哥的意思,可是

  • 凡是都是双面刃,老哥可能程序不行,但老哥的美术那是真的牛,理论可能很多人看起来很挫,但是实践是真的效果炸裂
  • 什么能力都比不上“坚持”二字,老哥坚持做了几年,或者说美术人那份执着,是我们理工科的永远学不来的“天赋”
  • ~!@!@*()#)()!*@

参考:

英雄联盟手游截帧分析(持续偷塔中...) - 知乎

Unity的PBR扩展 - UWA Blog


 

猜你喜欢

转载自blog.csdn.net/avi9111/article/details/124362483