PBR实现2.0
之前的错误和欠缺
1. 过于简单的划分diffuse和specular,非常光滑的非金属材料也是很能反光的
2. 费奈尔效应的处理,F0的选取也比较随意
3. 没有GI,更不支持AO
正确划分diffuse和spcular
之前我的PBR实现非金属无论怎样光滑都是没有反光的,这显然很不对。完全忽略了非金属的反射
金属性越高,反射率越高,分给Specular计算的Albedo越多。1.0的金属会反射所有的光,也就没有diffuse。但是非金属不太一样,0.0的非金属也仍旧又一定的反射能力,这个就是电介质反射率需要参与计算的地方。
在UnityStandardUtils.cginc中可以找到下面的分离方法,实际上是将Matellic的数值remap到[DielectricSpec,1]的范围。
inline half OneMinusReflectivityFromMetallic(half metallic)
{
// We'll need oneMinusReflectivity, so
// 1-reflectivity = 1-lerp(dielectricSpec, 1, metallic) = lerp(1-dielectricSpec, 0, metallic)
// store (1-dielectricSpec) in unity_ColorSpaceDielectricSpec.a, then
// 1-reflectivity = lerp(alpha, 0, metallic) = alpha + metallic*(0 - alpha) =
// = alpha - metallic * alpha
half oneMinusDielectricSpec = unity_ColorSpaceDielectricSpec.a;
return oneMinusDielectricSpec - metallic * oneMinusDielectricSpec;
} inline half3 DiffuseAndSpecularFromMetallic (half3 albedo, half metallic, out half3 specColor, out half oneMinusReflectivity)
{
specColor = lerp (unity_ColorSpaceDielectricSpec.rgb, albedo, metallic);
oneMinusReflectivity = OneMinusReflectivityFromMetallic(metallic);
return albedo * oneMinusReflectivity;
}
unity_ColorSpaceDielectricSpec里面存的是Unity选用的电介质反射率,alpha通道是1-dielectricSpec
Matellic:0 Gloss:0.5 的效果
)
从左至右:PBR1.0,Standard, PBR2.0, Standard
F0的选取
F0是入射角为0时的反射光,也就是分配给Specular计算的Albedo。之前的PBR实现实现会会整体偏亮就是因为Matellic肯定比正常的F0要大的多。
Matellic:0 Gloss:0.5 的效果

从左至右:PBR1.0,Standard, PBR2.0, Standard
过亮的问题看起来解决了,但是整体感觉更粗糙一些。
为什么我的shader颜色偏黑
这是Gloss:0,Matellic:0~1的对比图。关闭了场景的环境光。第一行是CustomPBR,第二行是Standard

最早是发现经过之前两个调整之后,整体颜色偏暗。经过几个对比测试之后确定是Specular部分偏低。也就是上图Matellic0.0和Matellic1.0对比在Diffuse为主的非金属上颜色基本正常,只有Specular的金属上色彩偏差最大。
这个问题让我非常迷惑,在一些对比测试中将公式改为和Unity一致也没有解决这个问题。进一步看到在Unity中对GammaSpace的Specular进行了一次开方修正。
同样的在CustomPBR中进行处理之后效果就正常了。

对Gamma这块我还不是很明白,搜了一下Gamma这个修正坑很深。以后再研究,要是哪位有相关的资料分享那就太好了。
没有GI怎么行
没有GI的情况下物体在场景里面实在是太突兀,先将Unity 的GI整合进来,学习一下Unity的GI。
UnityGI的处理
环境光照也是光照,也分为diffuse和specular。无论计算过程多么复杂,最后都是要得到环境光照的这两个分量,然后和基本光照叠加。
Unity的叠加方式。这里是简化说明,本体在UnityStandardBRDF.cginc中
//indirectDiffuse 就是GI的diffuse
diffuse = (indirectDiffuse + directDiffuse) * diffuesColor; //directF:计算了Fresnel的specularColor
//indirectSpecular:GI的specular部分,包括各种Probe
//indirectF:计算了GI的Fresnel的SpecularColor
specular = lightColor * directSpecularTerm * directF + indirectSpecular * indirectSpecularTerm * indirectF;
整合UnityGI
会用到的struct在UnityLightingCommon.cginc里。
Unity的GI运算在UnityGlobalIllumination.cginc里。
我们要用的方法是这个
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half3 normalWorld, Unity_GlossyEnvironmentData glossIn)
我们所需要的间接diffuse 和间接specular就在UnityGI.indirect
需要作的也就是给这个方法凑参数,构造一个UnityGIInput。这个结构体的大部分都很直观。
i_ambientOrLightmapUV
有lightmap的时候没有ambientColor,没有lightmap的时候只有ambientColor。这两个肯定是互斥的。
box和probe
在Unity中会有两个SpecCube生效,unity_SpecCube0,场景的反射源。unity_SpecCube1,当前的reflectionProbe,一起提供了IBL所需要的数据(其实应该是IBL的结果吧……待研究)
整合效果
Matellic:1.0 Gloss:0.7 Ambient:Red 在红色方块附近有一个ReflectionProbe

弓箭效果

下一步
1. 研究GI,看看能不能自己实现一个。现在GI方面有很多不明
2. Gamma修正,这个对最终画面影响很大,不能不看
PBR实现2.0的更多相关文章
- huawei USG防火墙子接口技术的应用案例
网络拓扑: 在中小企业的办公网络的设计中,通常为了安全考虑,需要将不同部门之间的互访的流量经过防火墙中转,同时结合vpn stance将业务进行隔离,在本例中,使用两台USG防火墙做HA作为整个办公网 ...
- 【腾讯Bugly干货分享】人人都可以做深度学习应用:入门篇
导语 2016年,继虚拟现实(VR)之后,人工智能(AI)的概念全面进入大众的视野.谷歌,微软,IBM等科技巨头纷纷重点布局,AI 貌似将成为互联网的下一个风口. 很多开发同学,对人工智能非常感兴趣, ...
- Python虚拟环境工具-Virtualenv 介绍及部署记录
在开发Python应用程序时,系统默认的Python版本可能会不兼容这个应用程序, 如果同时开发多个应用程序, 可能会用到好几个版本的python环境, 这种情况下,每个应用可能需要各自拥有一套&qu ...
- 从TensorFlow0.12升级到TensorFlow1.13
sudo pip install --upgrade tensorflow-gpu $ sudo pip install --upgrade tensorflow-gpu[sudo] password ...
- 记一次成功部署kolla-ansible ocata版本过程
1.安装的docker版本 [root@controller ~]# docker --versionDocker version 17.09.1-ce, build 19e2cf6 2.安装的ans ...
- 记一次安装kolla遇到DockerException: Error while fetching server API version: Timeout value connect was Timeout的问题
1)环境信息: docker版本:17.09,当docker的版本是12.06时,也会报这个错误 [root@localhost ~]# docker --version Docker version ...
- OpenStack基础知识-项目打包的步骤
学习过包管理相关的知识后,我们就要以OpenStack的方法来创建一个我们自己的项目.这个项目的名称是webdemo,就是一个简单的web服务器.这个项目会贯穿这个系列文章.在本文中,我们首先要创建w ...
- 当前,我们的DJANGO项目的requirements.txt文件
晒一晒,看用得多不多..:) amqp==1.4.7 anyjson==0.3.3 billiard==3.3.0.21 celery==3.1.19 celery-with-redis==3.0 c ...
- Python(七) —— mock接口开发
mock接口开发 接口开发有很多框架,诸如 Django,flask,相比较而言,flask 是轻量级web开发框架,用来开发 mock 接口的不二之选.那你可能会问,什么叫 mock 接口呢?moc ...
随机推荐
- 如何在MATLAB R2010a 中使用Visual C++ 2010编译器
安装补丁VS2012MEXSupport.zip http://www.mathworks.com/matlabcentral/answers/93013-how-can-i-use-microsof ...
- 面向小白的JS笔记 - #Codecademy#学习笔记
前言 最初浏览过<JavaScript秘密花园>,前一段时间读过一点点<JavaScript语言精粹>和一点点<JavaScript高级程序设计>(一点点是指都只是 ...
- (转)appendChild()、insertBefore()是移动element节点!
原文地址 appendChild().insertBefore()是移动element节点,看书的时候注意过,也可以做一个简单的例子测试一下: <div id="div1"& ...
- Python 基础之在ubuntu系统下安装双版本python
前言:随着python升级更新,新版本较于老版本功能点也有不同地方,作为一个初学者应该了解旧版本的规则,也要继续学习新版本的知识.为了能更好去学习python,我在ubuntu安装python2和py ...
- Dr.com──加密方式(网页端)
Dr.com是城市热点公司开发的宽带计费系统,可以控制网络进行管理,认证,计费,限速……许多的高校与企业都有使用. 从接触到drcom就很感兴趣(原因想必大家都懂...) drcom登陆(认证)方式又 ...
- js +1的动画效果
var fnPlusAnimate = function(str, options){ if (typeof str === 'object') { options = str; str = unde ...
- 使用html模板
创建html---点击next--选择写好的模板
- Linux虚拟机安装(CentOS 6.5,图文详解,需要自查)
Linux虚拟机的安装(图文详解) 下篇会接续Hadoop集群安装(以此为基础) 一.安装准备 VMWorkstation.linux系统镜像(以下以CentOS6.5为例) 二.安装过程详解 关闭防 ...
- 最短路径问题——floyd算法
floyd算法和之前讲的bellman算法.dijkstra算法最大的不同在于它所处理的终于不再是单源问题了,floyd可以解决任何点到点之间的最短路径问题,个人觉得floyd是最简单最好用的一种算法 ...
- ios常见的页面传值方式
iOS页面间的传值细分有很多种,基本的传值方式有三种:委托Delegate传值.通知NSNotification传值.Block传值,其他在项目中可能会遇到的还有:UserDefault或文件方式传值 ...