Unity Shader - 屏幕空间次表面散射

前言

在上篇文章中我们简单实现了一个伪次表面散射模拟效果,这次我们就基于屏幕空间模糊的方式来模拟皮肤的次表面渲染。

实现

大致流程:

  1. 提取次表面散射对象Mask遮罩。
  2. 高斯模糊处理 + Mask遮罩。
  3. 最后和原图叠加。

https://pic1.zhimg.com/80

1.提取皮肤遮罩

这里为了简单方便,直接采用Command Buffer提取需要次表面散射的对象Mask遮罩。
注意这里用了一个纯色Shader处理

C# 代码:

// 纯色Shader
Shader purecolorShader = Shader.Find("lcl/Common/PureColor");
// Shader purecolorShader = Shader.Find("lcl/Common/VertexColor");

if (purecolorMaterial == null)
    purecolorMaterial = new Material(purecolorShader);

if (maskTexture == null)
    maskTexture = RenderTexture.GetTemporary(Screen.width, Screen.height, 16, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default, 4);

commandBuffer = new CommandBuffer();
commandBuffer.SetRenderTarget(maskTexture);
commandBuffer.ClearRenderTarget(true, true, Color.black);
for (var i = 0; i < targetObjects.Length; i++)
{
    Renderer[] renderers = targetObjects[i].GetComponentsInChildren<Renderer>();
    foreach (Renderer r in renderers)
        commandBuffer.DrawRenderer(r, purecolorMaterial);
}

原图:
origin

提取结果:

mask

2.高斯模糊后处理

高斯模糊具体可以看之前的一篇文章:Unity Shader - 均值模糊和高斯模糊

模糊效果:

blur

然后乘上Mask遮罩:

//对模糊处理后的图进行uv采样
fixed4 blurCol = tex2D(_BlurTex, i.uv);
// mask遮罩
fixed4 maskCol = tex2D(_MaskTex, i.uv);
blurCol *= maskCol;

mask_blur

3.叠加原图

最后叠加上原图:

//对原图进行uv采样
fixed4 srcCol = tex2D(_MainTex, i.uv);
//对模糊处理后的图进行uv采样
fixed4 blurCol = tex2D(_BlurTex, i.uv);
// mask遮罩
fixed4 maskCol = tex2D(_MaskTex, i.uv);
blurCol *= maskCol;
float fac = 1-pow(saturate(max(max(srcCol.r, srcCol.g), srcCol.b) * 1), 0.5);
// float fac = fixed4(1,0.2,0,0);

return srcCol + blurCol * _SSSColor * _ScatteringStrenth * fac;
originsss
原图SSS

4.厚度

吸收(Absorption)是模拟半透明材质的最重要特性之一。
光线在物质中传播得越远,它被散射和吸收得就越厉害。
为了模拟这种效果,我们需要测量光在物质中传播的距离,并相应地对其进行衰减。

可以在下图中看到具有相同入射角的三种不同光线,穿过物体的长度却截然不同。

quicker.png

这里我们就采用外部局部厚度图来模拟该现象,当然,该方法在物理上来说并不准确,但是可以比较简单快速的模拟出这种效果。

烘焙厚度图可以用Substance Painter
或者用Unity的插件:Mesh Materializer把厚度信息存储在顶点色里面。

这里我是直接把厚度信息存储在顶点色里面,输出厚度信息如下:

这里取反了一下,越亮的地方,散射越强。

thickness

最终效果:

左边:开启SSS、右边:关闭SSS

sssss

工程源码:https://github.com/csdjk/LearnUnityShader/tree/master/Assets/Scenes/SubsurfaceScattering/ScreenSpaceSSS

参考

https://zhuanlan.zhihu.com/p/42433792

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值