首页 > 其他分享 >Unity3d反射(Reflection)

Unity3d反射(Reflection)

时间:2022-08-17 13:46:15浏览次数:74  
标签:贴图 Unity3d Reflection 反射 地板 所示 Alpha 通道

无论是VR、AR,还是游戏开发,都绕不开反射材质,一些童鞋说用反射探测器(Reflection Probe)制作反射,总感觉地板的反射不正确,本文小姐姐就这一话题,和大家一起探讨一下反射材质的制作。

本文将以下图所示的场景为例,来制作地板的反射,大家都应该注意到了,地面上还有一个地台,地台上还有一个圆形的地台,小姐姐也打算为这两个地台也制作一些反射。

在这里插入图片描述

首先我们用反射探测器来制作一下反射,看看其反射不正确的问题到底出在哪里。如下图所示,在场景中添加一个反射探测器,并调整反射探测器的手柄,使其包络整个房子空间。

在这里插入图片描述

用反射探测器制作物体反射,得经烘焙(实时模式除外)并配合物体材质的光滑度(Smoothness)甚至金属性(Metallic),才会呈现反射效果,所以我们先烘焙一下整个场景,然后调整地面材质的光滑度,如下图所示,此时地板有了反射效果。

在这里插入图片描述

仔细观察之后,我们发现房间柱子的反射明显不对,如下图所示:

在这里插入图片描述

再换个角度来观察,柱子的反射还是不对,而且窗户和墙面没有反射,如下图所示,这显然是不正确的反射。

在这里插入图片描述

接下来我们选中反射探测器,勾选Box Projection(立方体投影)选项,反射似乎有了变化,仔细观察,反射还是不正确,如下图所示:

在这里插入图片描述

我们这里暂且不追究地板的反射为什么不正确,而是导入一个茶壶和万向节物体,重新烘焙之后,调整这两个物体的光滑度,结果如下图所示。

在这里插入图片描述

我们拉近到茶壶和万向节物体,从不同角度观察,发现其反射是正确的,如下图所示:

在这里插入图片描述

由此可见,反射探测器仅适用于曲面物体的反射,不适用平面物体,这也正是很多人用反射探测器制作地板反射不正确的根本所在,那么平面物体的反射如何制作呢,下面我们就来讨论。

接下来我们可按下图所示的步骤来设定地板的平面反射:

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

最后调整的效果如下图所示,由图可见,这回地板的反射关系正确了。

在这里插入图片描述

实际上很多童鞋制作的地板反射并不是上图这样的,而是如下图所示,很显然下图的地板反射太假、太滑、太脆弱,没有一点厚重感,苍蝇蚊子落上去会摔成骨折。真正的平面反射一般并非全反射,而是区域反射,上图小姐姐给地板贴图添加了Alpha通道,地板的反射是由这个通道控制的,下图之所以全反射,是因为没有控制反射的Alpha通道。

在这里插入图片描述

PlanarReflection(平面反射)Shader的贴图要求带有控制反射的Alpha通道,如下图所示:

在这里插入图片描述

下面我们来看看平面反射shader的几个参数,具体如下图所示,其中主贴图(Main Tex(RGBA))用其后括号中的RGBA特别强调这张贴图必须是带有Alpha(A)通道的RGB图像,可以是PSD、TGA或TIFF格式(因为这些格式可以保存Alpha通道),如果这张贴图是没有Alpha通道的图像,shader会默认Alpha通道为为白色,这个shader中白色Alpha通道会全反射,黑色Alpha通道为不反射,介于白色和黑色之间的灰阶Alpha通道为不同强度的反射。

在这里插入图片描述

下面我们把前面两张地板反射的截图对比一下,如下图所示,第一张是小姐姐制作了Alpha通道的地板的反射,形成了区域反射。第二张是没有Alpha通道的地板反射,刚才我们说过,如果没有Alpha通道,shader会按白色的Alpha通道对待,即全反射。

在这里插入图片描述在这里插入图片描述

区域反射到底是怎么形成的呢,下面我们就将上面第一张地板贴图用ps打开,如下图所示,可以看到这张贴图是PSD格式的。

在这里插入图片描述

接下来切换到通道面板,如下图所示,由图可见,这张PSD贴图带有Alpha通道:

在这里插入图片描述

现在我们关闭RGB通道,只显示Alpha通道,如下图所示,由图可见,Alpha通道中,不用区域分布着不同灰度的颜色,白色部分将使地板反射最强,黑色部分将使地板不反射,不同的灰色,将使地板呈现不同程度的反射,宏观上形成了不同区域不同程度的反射,所以称之为区域反射。

下面我们极端一点,直接在Alpha通道中填充白色,如下图所示,然后将其以PSD格式(PSD格式可以保存Alpha通道)保存在Unity的Assets文件夹中。

回到Unity中,将刚才那张PSD格式的贴图指定给地板,我们发现,地板成了全反射,如下图所示:

再回到ps中,在Alpha通道中填充黑色,如下图所示,然后保存。

回到Unity中,更新后地板没有反射了,如下图所示:

返回到ps中,这回我们将Alpha通道填充成灰色,如下图所示,然后再保存。

再次切换回Unity,更新后地板的反射如下图所示:

通过上面的实验,我们发现平面反射Shader的反射状况和主贴图本身无关,只和主贴图的Alpha通道有关系,换句话说,主贴图的Alpha通道控制着这个shader的反射,或者说平面反射shader的反射状况完全由Alpha通道控制。同时我们得到这样的概念,在主贴图的Alpha通道中,白色反射强度最高,黑色最低,灰色反射强度较弱。刚才的例子中,我们在Alpha通道中,每个像素填充了一样的颜色,可以想象,不同像素中如果填充不同的灰度色,那么地板的反射将成为不均为的反射,这样做是非常困难的,所以一般我们不这样去做Alpha通道。

  有了上面的概念,下面我们就来制作区域反射的Alpha通道,一般情况下,大家都只给地板贴一张不带通道的jpg图像,要用这个平面反射Shader制作出比较自然的区域反射效果,就得给贴图创建一个Alpha通道,否则Shader会认为Alpha通道是白色的,最后制作的反射就成了极不自然的全反射了。接下来用ps打开用于反射的贴图,如下图所示,由于贴图没有alpha通道,所以需要为贴图创建一个,因此切换到通道面板,按下图提示来创建一个Alpha通道。

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

将按上述图示步骤制作的带有Alpha通道的贴图指定给地板材质Shader的Main Tex(主贴图),则地板的反射状况如下图所示:

返回ps继续调整Alpha通道的曲线,如下图所示:

在这里插入图片描述

我们发现上图Alpha通道中白色太多,这样会使地板反射太强,所以按Ctrl+I,将Alpha通道反相,白色和黑色对调,这样Alpha同多种白色会少很多,如下图所示:

在这里插入图片描述

保存上图的修改,返回Unity更新后地板反射如下图所示,由图可见,地板产生了区域反射。

在这里插入图片描述

Alpha通道可根据自己的偏好随便调整,没有什么定式。下面按下图所示的步骤,配合脚本和shader来进一步调整地板的反射:

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

通过以上的图解分析,相信大家对平面反射及其区域反射有了很深的映像,这里做个小结,平面反射及区域反射的关键是控制反射的Alpha通道、反射通道强度以及反射贴图的分辨率(如下图所示),把握好这几个要素,就能做出出色的平面反射效果。

在这里插入图片描述

有了上面的经验,我们就可轻松做出方形和圆形地台的反射,因为整个房间时一个物体,所以不需要再为方形地台和圆形地台加载脚本,只需将这两个地台材质的shader也改为PlanarReflection,然后为这两个地台的贴图也制作用于控制反射的Alpha通道即可,如下图所示:

在这里插入图片描述在这里插入图片描述

最终效果如下图所示:通过以上的演示,解决了平面及区域反射和曲面反射的并存,在实际项目中平面反射和曲面反射就是并存的,比如摆放茶杯、水壶、和一些器皿的桌面等。

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

很多童鞋在测试一些知识点时,常常忽略了播放状态的测试,结果在实际项目中应用时,一播放不是代码不兼容,就是没有任何效果,这里需要强调一下,相机视图和播放状态不是一回事,所以我们播放一下上面的场景,看看有没有平面区域反射和曲面反射失效和不兼容现象,经播放测试后,没有任何问题,也没有卡机现象,如下图所示:

在这里插入图片描述

需要说明的是,现实生活中平面及区域反射一般都比较弱,而且是模糊反射,当然也有比较强的和比较清晰的平面反射实例,掌握了以上所述的平面及区域反射,相信大家都可以轻松搞定。

对于材质比较简单平面及区域反射,以上的方法完全可以满足反射材质制作的需要,但是对于复杂的材质,只能另择他法,因为上面的shader只能接受一张带Alpha通道的贴图,对于有凹凸、AO、高度需求的材质,无处加载法线、AO等贴图,这正是这个shader的不足之处。

标签:贴图,Unity3d,Reflection,反射,地板,所示,Alpha,通道
From: https://www.cnblogs.com/guangzhiruijie/p/16594864.html

相关文章

  • python基础——超类&反射&装饰器&生成器
    一、超类1.1什么时候用到超类?如果子类需要复用父类的代码(属性、代码)时,需要通过超类实现classA:class_name="A"#类的属性def__init__(self,name,......
  • JavaSE:第十三章:一分钟了解反射
    首先分享一篇关于反射的博文,因为我发现这篇博文写的很详细,然后开始我的表演:首先学习反射之前,我要提出疑问:反射是个什么东西?它是用来做什么的?平时的应用场景有哪些?为啥......
  • 【JAVA反序列化_一】反射基础
    image-20220816132943277【JAVA反序列化_一】反射基础须知:​这个图相信不陌生,是shiro反序列化利用工具,其中这利用链说实话当我第一次见的时候满脸问号,于是就想探究......
  • Go语言反射reflect标准库03-通过反射获取值信息相关操作
    通过反射获取值信息当我们将一个接口值传递给一个reflect.ValueOf函数调用时,此调用返回的是代表着此接口值的动态值的一个reflect.Value值。我们必须通过间接的途径......
  • Go语言反射reflect标准库03-通过反射获取类型信息相关操作
    10.3通过反射获取类型信息在Go语言中通过调用reflect.TypeOf函数,我们可以从一个任何非接口类型的值创建一个reflect.Type值。reflect.Type值表示着此非接口值的类......
  • 长篇图解java反射机制及其应用场景
    一、什么是java反射?在java的面向对象编程过程中,通常我们需要先知道一个Class类,然后new类名()方式来获取该类的对象。也就是说我们需要在写代码的时候(编译期或者编译期之......
  • 注解和反射之动态创建对象执行方法
    点击查看代码packagecom.kuang.reflection;importjava.lang.reflect.Constructor;importjava.lang.reflect.Field;importjava.lang.reflect.InvocationTarget......
  • Java反射原理和实际用法
    背景反射在Java中非常重要,是Java区别于其他编程语言的一大特性。Java中的AOP切面、动态代理等看起来像黑魔法一样的技术,就离不开反射、字节码等。这些技术能在不侵入原有......