PISCOnoob

导航

Unity PostProcessing With Normal Texture

写在前面:

本文章为个人学习笔记,方便以后自己复习,也希望能帮助到他人。

由于本人水平有限难免出现错误,还请评论区指出,多多指教。

部分图元和素材来源于网络,如有侵权请联系本人删除。

参考资料与链接会在文章末尾贴出。

=======================================================================

1 Read Depth and Normals

本文会简单介绍如何让unity camera渲染一个包含depth和normals的纹理,前文回顾:

PISCOnoob:Unity Postprocessing with Depth Texture

首先在C#脚本中编写代码:

这已经是我们访问法线所需的所有设置了!接下来我们编辑我们的shader。

定义变量_CameraDepthNormalsTexture。

有了这个设置,我们现在可以在fragmentShader中读取DepthNoramlsTexture。把结果绘制到屏幕上,我们已经可以看到一些有趣的东西。

但其实我们能看到的并不是我们真正想要的,我们只看到红色和绿色的值以及远处的一些蓝色。这是因为顾名思义,这个纹理既包含法线纹理又包含深度纹理,所以我们必须先对其进行解码。unity 为我们提供了一种可以做到这一点的方法。我们需要给它深度法线值以及函数将写入深度和法线的其他两个值。


与深度纹理不同的是,我们现在拥有的深度值在相机和远裁剪平面之间已经是线性的。

让我们回到使用法线。我们将法线作为颜色输出到屏幕上。

 

 

但是可以看到如果我们旋转相机,我们可以颜色会变化,即看到表面上的一点并不总是具有相同的法线,这是因为法线是相对于camera存储的。因此,如果我们想要在world space的法线,我们必须重新计算。

我们要将view space法线转换为world space,因此我们需要在C#脚本中将转换矩阵传递给我们的shader。

 

2 Color the Top

现在我们有了世界空间法线,我们可以做一个简单的效果来熟悉一下。我们可以用一种颜色为场景中所有对象的顶部着色。

为此,我们只需将法线与向上向量进行比较。我们通过点积来做到这一点,当两个归一化向量指向相同的方向(当表面是平面时)时返回 1,当它们正交时返回 0(在我们的例子中是在墙上),当它们彼此相反时返回 -1其他(在我们的例子中,这意味着摄像机上方的屋顶)。

或直接输出normal的g通道:

为了更清楚什么在顶部,什么不算在顶部,我们加一个变量并与up做step来区分顶部和不在顶部。

下一步是在我们没有将表面定义为顶部的地方恢复源图像颜色。为此,我们只需从MainTex中读取,然后在该颜色和我们定义为顶部的颜色之间进行线性插值。

然后我们还可以将向上的颜色与顶部颜色的 alpha 值相乘,这样当我们降低 alpha 值时,顶部会让一些源图像颜色通过。

本文主要简单介绍一下depthNormalTexture怎么使用,但并没有一个好的效果例子。有小伙伴说可以做雪的效果,但做雪的话通常来说直接在shader里面实现会比后处理要好得多hhh。

posted on 2022-11-02 09:40  PISCOnoob  阅读(31)  评论(0编辑  收藏  举报