移动端树叶SSS效果制作

UE4内置了双面植被渲染的ShadingModel,内部使用了TwoSidedBxDF的专门BxDF方程:

FDirectLighting TwoSidedBxDF( FGBufferData GBuffer, half3 N, half3 V, half3 L, float Falloff, float NoL, 
	FAreaLight AreaLight, FShadowTerms Shadow )
{
	FDirectLighting Lighting = DefaultLitBxDF( GBuffer, N, V, L, Falloff, NoL, AreaLight, Shadow );

	float3 SubsurfaceColor = ExtractSubsurfaceColor(GBuffer);

	// http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/
	float Wrap = 0.5;
	float WrapNoL = saturate( ( -dot(N, L) + Wrap ) / Square( 1 + Wrap ) );

	// Scatter distribution
	float VoL = dot(V, L);
	float Scatter = D_GGX( 0.6*0.6, saturate( -VoL ) );

	Lighting.Transmission = AreaLight.FalloffColor * (Falloff * WrapNoL * Scatter) * SubsurfaceColor;

	return Lighting;
}

这种Wrap式的BxDF(比如Half-Lambert)会在背光部分添加适当的补光,而不是完全变黑,比较忠实的还原了光线在叶子间传递的衰减情况。

通常情况下Wrap式光照模型会过亮(能量不守恒),导致与周围的其它遵循能量守恒的PBR着色模型亮度不统一(在环境中显得格格不入,美术风格不统一),技术美术被迫放出更多的着色细节参数,让美术细调以达到着色风格统一。

这实际上是风格化PBR必然会遇到的问题,也是比较重要的问题,风格化的PBR会对特殊的材质,各向异性如:丝绸、头发,SSS类型如:玉石、皮肤,特殊环境材质如:河流、湖面、海面、冰、沙子等,对这些特殊的材质设计单独的Shading Model,很难确保所有的ShadingModel都遵循能量守恒,同时也很难确保所有的着色细节亮度统一。

我认为之前所在的项目也有类似的问题,我们修改了很多着色相关的细节,做了很多风格化的处理,但并没有确保所有的着色模型(比如水),都遵循最基本的能量守恒。

文章(http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/)给出了基于能量衰减的 Warp BxDF,可以和周围的PBR着色模型很好的融合在一起。

另外全局光的球谐光也是很重要的一项,树叶计算球谐光时使用反向的法向量,它会带来很细腻的光影变化。

移动端渲染树叶时,出于性能考虑,会使用插片方法来节省性能,并且为了避开Overdraw,经常插片数很少,这导致树叶的光影感出不来。换言之,插片树缺少了许多高频的几何细节,没有办法直接计算透视SSS效果。

因此,在SpeedTree这种专业造树软件中,会额外计算一项高频的几何环境光遮蔽系数存到顶点色的r通道中,导入UE4时,可以将其作为AO项参与透射部分的计算。

image-20201213104237318

另外,houdini的GameLab工具中也提供了计算顶点AO的工具。

单纯使用AO顶点色是出不来对比强烈的SSS效果的,还需要和光照贴图(阴影贴图)配合加深过渡。

光照贴图的烘焙也比较重要,直接使用原生的法线容易烘焙出死黑,需要改一下树的法线,而单纯的球形法线过渡在复杂结构的树上光影过渡单调,并不合适。

在育碧的分享中使用的是近似包围体来转移法线:

image-20201213104356043

这个在Houdini中制作非常的简单,只需要简单几步:

  1. 撒点。

image-20201213104823883

  1. vdb融合

image-20201213104923700

  1. vdb平滑&&转移法线

image-20201213105548138

可以看到基本思路是使用体积平滑来生成一个近似平滑的几何体。

image-20201213111423556

这里使用的是vdbfromparticlefluid而不是直接convert to vdb,是因为普通的插片树,撒点后直接生成的vdb并不连续,而vdbfromparticlefluid有一个体素大小选项可以调节每个点密度元球大小,进而将它们连接起来。

© - 2024 · 月光下的旅行。 禁止转载