之前的错误和欠缺

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的更多相关文章

  1. huawei USG防火墙子接口技术的应用案例

    网络拓扑: 在中小企业的办公网络的设计中,通常为了安全考虑,需要将不同部门之间的互访的流量经过防火墙中转,同时结合vpn stance将业务进行隔离,在本例中,使用两台USG防火墙做HA作为整个办公网 ...

  2. 【腾讯Bugly干货分享】人人都可以做深度学习应用:入门篇

    导语 2016年,继虚拟现实(VR)之后,人工智能(AI)的概念全面进入大众的视野.谷歌,微软,IBM等科技巨头纷纷重点布局,AI 貌似将成为互联网的下一个风口. 很多开发同学,对人工智能非常感兴趣, ...

  3. Python虚拟环境工具-Virtualenv 介绍及部署记录

    在开发Python应用程序时,系统默认的Python版本可能会不兼容这个应用程序, 如果同时开发多个应用程序, 可能会用到好几个版本的python环境, 这种情况下,每个应用可能需要各自拥有一套&qu ...

  4. 从TensorFlow0.12升级到TensorFlow1.13

    sudo pip install --upgrade tensorflow-gpu $ sudo pip install --upgrade tensorflow-gpu[sudo] password ...

  5. 记一次成功部署kolla-ansible ocata版本过程

    1.安装的docker版本 [root@controller ~]# docker --versionDocker version 17.09.1-ce, build 19e2cf6 2.安装的ans ...

  6. 记一次安装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 ...

  7. OpenStack基础知识-项目打包的步骤

    学习过包管理相关的知识后,我们就要以OpenStack的方法来创建一个我们自己的项目.这个项目的名称是webdemo,就是一个简单的web服务器.这个项目会贯穿这个系列文章.在本文中,我们首先要创建w ...

  8. 当前,我们的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 ...

  9. Python(七) —— mock接口开发

    mock接口开发 接口开发有很多框架,诸如 Django,flask,相比较而言,flask 是轻量级web开发框架,用来开发 mock 接口的不二之选.那你可能会问,什么叫 mock 接口呢?moc ...

随机推荐

  1. C#知识体系(一) --- 常用的LInq 与lambda表达式

    LinQ是我们常用的技术之一.因为我们绕不开的要对数据进行一系列的调整,如 排序. 条件筛选.求和.分组.多表联接 等等. lambda则是我们常用的语法糖,配合linq使用天衣无缝,不知不觉就用上了 ...

  2. 易图软件之EaseMap Desktop 1.0发布

    概述 易图软件之EaseMap Desktop 1.0是一款基于arcgis runtime for wpf开发的地图编辑软件. 软件代码编写历时1个月终于完成. 目前这个版本的功能包括: 地图基本操 ...

  3. iOS 源代码管理工具之SVN

    源代码管理工具之SVN 源代码管理工具SVN是一款非常强大的源代码管理工具,现在国内70%-90%的公司都在使用SVN来管理源代码,下面就让小编给大家着重介绍一下SVN的使用,SVN的使用主要分为下面 ...

  4. (转)C#实现MD5加密

    首先,先简单介绍一下MD5 MD5的全称是message-digest algorithm 5(信息-摘要算法,在90年代初由mit laboratory for computer science和r ...

  5. 支持coclock模式

    1. /mediatek/custom/htt82_tb_jb5/cgen/cfgdefault/CFG_GPS_Default.h GPS Coclk: 0xFE (enable) 0xFF (di ...

  6. android 手机屏幕有关的几个工具(屏幕宽高,dp和px互相转换)

    平时适配页面时经常会需要根据屏幕的宽高来设置控件的大小,很多时候在代码中还会需要dp和px互相转换. 今天把最常用的几个记录一下,经测试包括2.3 ~ 5.0之间的版本都可用,其他版本未测,不过应该也 ...

  7. Android SDK代理服务器解决国内Android SDK不能更新下载问题

  8. git format-patch & git apply & git clean

    一.打补丁 git format-patch & git apply 最近在工作中遇到打补丁的需求,一来觉得直接传文件有些low(而且我尝试了一下,差点把项目代码毁了) ,二来也是想学习一下, ...

  9. JS对象实现随机满天小星星实例

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  10. centos 6.8 安装 nginx-1.11.4

    yum -y install gcc-c++ wget http://nginx.org/download/nginx-1.11.4.tar.gz wget  https://www.openssl. ...