在实际项目中,更加的统一,流程规格化。
以前绘制贴图啥的,可能风格不同,
PBR是渲染方式,宏观的概念,并不指代具体材质。PBS是其核心。
前者standard是金属流,后者是高光流。
两种工作的产出贴图不一样,工作效果是一样的。
倒背如流!!!
BRDF是PBS的光照模型。
光到达金属表面,进去或者反射。进去的全部被吸收,所以金属射到我们眼里的光,都是它反射到我们眼里面的。
金属反射的颜色,注意是反射的高光颜色,可以是带有颜色的,RGB某一个颜色的。
非金属就不一样了,它发射的高光都是黑白灰的,不具有彩色。
注意只要是没进入物体内部反射出去的这部分都是高光反射。
所以金属只有高光反射。(纯金属)
漫反射是进去了,然后又从进入的面出来了。各个方向射出去。
生锈的金属算是非金属。
水并不导电,不是金属,纯水不导电,水导电是因为有杂质。
也就是把平面放大了看,看发生了什么,就是上边的那俩行为,而我们就要模拟这个行为,那么由于平面上各个部分也是不同的,所以我们用贴图来实现不同。
右边的图表示的是,把一个看似光滑的球表面一处给使劲放大,是可以看到它的凹凸不平的。
粗糙度对光线的影响。
上边说的粗糙度的影响,原理其实就是能量守恒,当粗糙度上升,其实主要是很多方向偏了,被散射走了,所以整体亮度会暗一些,没那么亮。
线性空间才能保证计算的渲染的正确性,才能对最终效果的真实性有一个保证。
线性空间和gamma空间是对立的。
gamma空间在亮度相同的情况下是更曝的,在1.5的时候就基本完全爆掉了,没有细节了 。而线性空间下,高光和暗部和中间的过渡地带还都是清晰可见的。
=============================================================================================
对于渲染方程,我们实际情况是对他进行一些简化的,因为完全按照这个来操作,时间消耗非常之大。
大致理解这个式子就是:输入的光,首先会由于入射角带来一个衰减,然后根据BxDF来算出反射的,但是对于入射的不只是一个方向,所以这里就积分起来所有的,就得到指定出射方向上的光亮度。
而上边最为重要的就是BxDF。
双向,视角方向和入射角方向,这俩固定了,再谈亮度。
BRDF针对不透明的,因为他只考虑反射部分。
BRDF是反射的部分,也就是简化成入射点和出射点为同一个点,然后向外反射的部分,平面上边的部分。
BTDF就是和BRDF类似的,考虑平面下面的部分,透射的部分。
BSDF就是这俩相加的结果。
BSSRDF就是引入了次表面散射等现象,这个次表面散射,其实是光进入介质之后,然后在出去的时候,出去的点已经远离了入射点的情况,这就会产生次表面散射的现象。这是BRDF没有涉及到的。
聊一聊PBR的一些重要前置概念 - 简书 (jianshu.com)
简谈实时皮肤渲染之预积分SSS - 简书 (jianshu.com)
描述次表面散射(Subsurface Scattering):BSSRDF 简介 - 知乎 (zhihu.com)
学习PBR路程(二、渲染方程与BxDF) - 知乎 (zhihu.com)
健壮,就是你在正常范围内调参数的时候,效果不会偏的太离谱。
这里说了一个美术的让步,因为一般情况下这个高光的颜色是固定的,非金属都是黑白灰的,不同的金属有着各自固定的颜色。而让步美术,就是让这个颜色变成可调节的,更好的服务美术效果。
关于Unity里面的金属流和高光流,就是在导出贴图的时候,他俩不一样。
注意通道的颜色不一样,意味着通道内装的东西不一样。
然后再材质里面,我们可以看到这里的两个standard。
这个是他的材质面板。他的纹理显示和我们默认properties写的结果不一样,是因为这里的都是用脚本来自定义的额。
导出。
这里把贴图导入到材质中。这个是Unity 自带的金属流PBR的四张贴图:
这里的Metallic和smoothness是放在了同一张贴图里面。前者占据RGB,后者占据A。但是这里R=G=B,三个是存储的相同的信息。这里说了一个针对什么OpenGL2.0啥的,如果压缩,ADC1什么玩意的格式,我们是不能使用alpha通道的,所以我们把贴图给调整一下,让金属度放在R,光滑度放在G通道。为了节省空间,B里面我们塞一个AO。
然后形成我们自己的一套贴图形式:
同时删除了自发光贴图。注意法线选择的是右边的那个版本;、
当我们制定了自己的贴图版本之后,就不能使用它Unity的shader了,因为贴图对不上号。
他这里光滑度贴图只能来自metallic或者albedo的alpha通道,而我们放在了金属度的G通道,所以这里如果再用它的就没法传递进去光滑度贴图。
所以我们需要自己写一个自己的材质。
线性空间的修改,线性空间只支持OpenGL2.0以上版本,安卓4.3以上版本。
===============================================================================================
在一个没有光的房子里,打第一盏灯,房间从暗变成亮的,这时候再打一盏相同的灯,房间会变亮,虽是相同的灯,但是变亮的程度却不如第一添加的时候变亮的程度大,也就是亮度并没有达到一盏灯时候的两倍。
这个是人眼的一些机制导致的。
现实中实际的亮度值,是线性递增的,一盏灯是一定的亮度值,加上第二盏灯就是二倍的亮度。
对于人眼看上去却不是,他会有一个下凹的形状。如上图。
对于一些电子脉冲的显示器,以一定的脉冲冲击显示器,得到一种亮度,加倍脉冲得到一种亮度,对比这俩亮度第二种亮度依旧不是第一种的二倍。
所以这里人眼和电子脉冲显示器存在这么一个共性的巧合。
这里有意思的是:我们用人眼去看显示器的时候:
就是显示器显示的是2.2次方,人眼再看就是再来一个2.2次方。也就是更暗。
这个情况并不好,所以做显示器的硬件厂商,就尝试处理这个问题。
就是把显示器显示之前给他做一个矫正处理,放大的曲线让他是:x的2.2分之一次方的曲线。
输出之前,先2.2分之一,然后输出显示出来再来一个2.2,这样显示的亮度就是实际亮度了,人眼再一看,又会下凹一下,但是这个下凹一下,是符合人眼正常情况下看光照的亮度变化的,这样才看上去合理真实。
如果一个图片是sRGB,他的信息就会使上凸的曲线,也就是他最终的颜色要比实际的亮。
设置sRGB与否都无所谓,他都认为你是,都会在你设置的颜色的基础上变得更亮来存储,注意这个是存储的亮度,看到的就不一定了,受到眼睛和显示器的影响。
存储之后会进入shader,那么进入shader去对颜色进行加工处理,这时候就体现出弊端了,shader中处理颜色并不是原线性空间下的颜色,而是gamma 0.45下的。那么这就是错的,shader输出的颜色自然也不是那么准确的,比如亮度在叠加的时候,可能会大于实际相加的亮度,0.5 + 0.5 > 1,这里的0.5和1是gamma0.45下的,如果在线性下本应该等于1,现在大于1,那就产生了过曝。
线性空间下,会在shader处理之前,移除gamma矫正。
这个就完全正确了。
注意这里我们的颜色信息贴图就必须勾选上sRGB了,注意是颜色信息,存储颜色的。如果其他的法线等数值贴图,就不必勾选了额。因为并不把它里面的像素作为屏幕像素直接显示。只是用来做一些计算罢了。
DCC产出的图会自动进行一个gamma矫正,也就是增亮一下,放在gamma 0.45下,所以上边开局就是上凸的。
这里可以这么理解,就是sRGB上边说了他是变亮的,那么不勾选,他就认为你没变亮,他认为你是线性的,所以直接进入shader,然后再凸,这个凸是为了下面的显示器显示后为线性的。
所以这里的问题就在于,他认为你是线性,但实际你是凸起的,DCC产出的就是凸起的。
========================================================================================
创建PBRshader的时候,最好用这个作为模板。
然后把材质都用上刚刚创建的shader。
这里是一个surface shader。我们要转换成顶点片段着色器。
对于surface shader,这里会有一个选项,就是show generated code。
打开后,刚刚的五六十行表面着色器,变成了一千多行的代码。
我们要把这个代码给替换掉刚刚的表面着色器代码。效果是一样的。
注意看这里的几个pass,把该删除的东西都给删除了。
这里替换的时候,右边Aa,意思是考虑大小写,大小写不一致的不算。第二个意思是全单词,意思是:vert_surf1 这个他就不会替换,只有找到了单独的vert_surf才会替换。
替换按钮。
这个什么编译相关的,讲优化的时候会讲这个。
然后下面俩一个是雾效的定义和前向渲染的定义。
剩下的都是在内部会直接引用的,我们不写也ok。可以直接删了。
下面是GPU实例化的开启与否,渲染优化相关的。低端机不支持。
这里我们不考虑GPU实例化,下面的可以直接删除。
这里直接把if删除就好了,让他必然执行这一段。
由于这里是一步步看,过程中会修改删除,这时候一定要避免出错,因为这个不是自己写的,找错很麻烦,所以修改一点就保存一下看看是否有错。没错了再往下。
三行直接删除。
删除。
位置改一下。
删除。
这里的lightmap是光照贴图,也就是把光照信息烘焙到贴图上,这里静态物体可能会使用,这里不考虑所以直接删除。
然后删除上边的if条件。
这里俩精度的,删除上边半精度的,保留高精度的即可,然后条件删除。
这个struct就是v2f,我们改个名字。
这两句是一样的,我们换成下面的
这里的pack0我们不知道是干啥的,可以直接搜索,看看他是怎么用的,搜索到其他的pack0可以看出这个就是uv。改个名。
删除
然后这里它的vert的参数结构体是一个appdatafull,而不是自己定义结构体,这个东西,我们可以再cginc中找到。
其实就是准备好的一些结构。
这种通用的并不好,因为因为可能用不到其中一些,造成空间浪费。
这个也是不需要的,因为lmap是光照贴图的采样,光照贴图相关的都不要。
先对参数修改名字。
c定义换到下面来
注意这里最核心的一句就是c的赋值这句,这里调用的函数就是PBR的实现操作。
下面的这个宏的实现,就是赋值为1.可以手动赋值。但是这里可以删除,用不着。其他地方可以实现alpha的赋值1。
这个核心的函数的三个参数在这里。
可以换成
关于
UNITY_INITIALIZE_POTPUT:
然后下面的一部分是对结构体里面的数进行一个填充,
这里它初始化,然后调用了surf填充。但是我们可以直接填充的,下面之前的surf定义直接删除就行了。
不用surf,这两句也删了
填充金属度的时候,需要加一个属性
这里的normal可能麻烦一些。
先补充上这三个轴。
window中有一个参考大全可以没事看看。
把normal补全。
然后解决报错问题。
然后是核心函数的第二个参数,这个比较简单,这里可以少用一个变量。
最后一个关于GI:
这里Unity GI里卖弄有一个直接光和一个间接光,都在上边了。
======================================================================================================\
这里自己写一个头文件,然后放在同级目录的文件夹下面,include上。
需要写上CGIncludes。
头文件里面干啥:
复制这一段。
头文件固定格式。
贴进去。
这样我们就可以修改这个文件,之前那个系统文件最好不要直接改动。
然后这里自己写的头文件,由于是要对原来的函数进行一个重写,我们这里改个名字,加一个1,这样调用的时候调用加了1的,就不会出现重定义了。这里把UnityGl这个也复制了过来,同样也加个1.
仔细看下面的这个函数,他在调用UnityGI时的输入参数,第一个是GIInput,这个不用说了,名字就知道了,第二个就是我们模型的AO图,第三个就是normal,第四个:
他的类型是上边。
一个是粗糙度,一个是反射的UV采样,这里是UVW,就是环境光照采样cubemap那种,是用一个向量来进行采样的, UVW。
然后再看:
这里由于准备的数据都是光滑度,没有粗糙度,所以这里用1减去光滑度,也就是上边的函数的作用。
这里走到上边之后,会进入base函数,这个里面就是把直接光的东西给填上,这个就是从data中直接拿的。然后主要干的东西就是间接光的diffuse。
间接光部分还缺少specular,也就是下面的一句。
找到这给函数的实现,然后
这个判断条件对应的是下面:
是反射探针,reflection probe,开启box projection。它的意思说了一下,但是没听明白。
这个判断的这一部分,暂不需要。跳过。
这里一个选项,如果取消勾选的话,那么接下来的一个判断就会成立:
如果没有勾选,也就使用unity默认的一个值作为高光,这个到BRDF再讲。
如果勾选了:
终点就落在了高亮的那句。
他的参数,第一个采样。
然后关于他的第二个参数,回到我们在frag中准备的giInput:
这里不适用lightmap,所以可以直接删除这一块。保留高亮那一句即可。
这一部分可以直接注释掉。
上边说完了他的三个参数,进入函数内部。
这里执行了一个操作。粗糙度 = 粗糙度*(1.7 - 0.7 * 粗糙度)
先看上边,我们用粗糙度实现的结果就是,随着粗糙度的变化,然后物体表面对外界的反射越来越模糊,但是代码里面怎么实现这个,代码里面没办法一点点的去让这个图片变得模糊。
采用的方式,就是通过采样更高等级的mipmap图,让显示的结果变得更模糊。
就模拟出了粗糙度变化的效果。
可以在这里看出来。
这里就是先算出来那一层的mipmap,然后根据UVW采样即可。采样完成之后进行一个解码。
其中的perceptualRoughnessToMipmapLevel就是上边那一句,就是拿着参数乘以6,因为mipmap是0到5,六个层级。
这里转了一圈得到mip,为啥不是直接拿着roughness就作为mip?
是因为:mip和roughness之间的变化不是线性对应的。所以用了上边那个1.7那一坨进行了处理,然后又得到mip值的。
================================================================================================================================
当GI计算出上边的所有的颜色之后,我们就要进入
这一个了,这一个其实就是我们的核心,因为有了输入的颜色,把这些颜色加以作用就会得到输出颜色,也就是fragment的输出结果。
复制下来,
函数的内容可以看出,就是前面准备各种变量,然后执行BRDF计算,然后返回。
这里有上下三行和alpha有关的,都是和透明模式下相关的。
然后上边有一个函数调用,对BRDF的三个参数产生了影响。
注意这里函数名字是根据金属度来计算高光和diffuse,这个是计算传入BRDF计算的高光和diffuse,并不是最后颜色的。
金属性越强,最后高光接近本色。
后边他注释也说了一句,绝缘体高光反射率一般都是4%。
然后1-反射率,是1-高光的反射率,得到的是漫反射的反射率。这个怎么理解?
反射率就是反射出去的比上输入的,那么反射出去的要么是高光,要么是漫反射,所以这俩加上等于1.
dielectricSpec表示的就是高光反射率,而金属度越大的时候,反射率接近1.
漫反射率乘以漫反射颜色,就作为最后的albedo。
这里有这一坨东西,首先BRDF3_Unity_PBS是效果最差的,其次2,1是最好的。就是Unity内部实现了三种PBR。
第一个SHADER_TARGET < 30就是对机器性能判断的,性能太差,自动选用最差的pbr。
这里就说明了,其他的UNITY_PBS_USE_BRDF1/2/3,其实都是根据性能来的。
就是和这里对应的,根据standard shader quality来定义对应的宏,从而选择对应的PBR。
然后我们这里默认是high,所以就会执行
这个,我们复制它。
这里有一个#error用法,运行后:
可以用来调试shader。
=============================================================================================================
这一节开始,探索BRDF内部。
l和v就表示双向。view和light
之前说的四部分,这里直接把GI都混进去了。
第一行这个,首先diffuseColor就是传进去的albedo,就是贴图乘以漫反射的反射率的结果。
后面括号里面是gi的间接漫反射,和直接漫反射相加,直接漫反射这里收到光的颜色影响,所以他俩相乘了一下。
注意,其中的很多的值都是参数传递进来的,只有diffuseTerm是在这里新出现的,我们看一下他是如何实现的:
前两句,一个是光滑度求出粗糙度,直接1减去。
然后是获得归一化的半角向量。
上边的rsqrt是根号之后再倒数。
突然想起来一个问题,就是,那些背面的像素是什么时候剔除的。
又想起来一个问题,可以学习DUO的玩法,把内容整理一下,然后把问题整理出来。以后可以对着自问自答。
这里有一个if判断,也主要是这里有一个ndotv可能因为一些情况出现负数,那么有一种方式可以修正,但是有一定的性能消耗,对于高性能的机器可以选择这种,就可以把上边的宏定义为1,这样就进入这种
修正处理的方式。还有一种简单的方式来处理,结果的精度会有所下降,但是性能会得到一些节省。所以需要机器的性能进行一个权衡。
剩下的就是各种点积运算。
再往下有一段注释,这里迪斯尼的漫反射公式里面有一个除以PI的操作,但是这里没有了,他在这里解释了一下的原因。
==================================================================================================================
再来看高光,我们的Fresnel就是F,那么这里高光,他会受到灯光颜色的影响,所以这里乘以一个灯光颜色无可厚非。
然后剩余的DG以及分母部分都在specularTerm中。
先看specular:
unity里面是按照上边分开计算的,把G和分母放在一起,V。
这里高光模型计算是有俩的。
其实GGX那个宏就是1,所以直接走上边的那一部分。这里就是获取VD两项。
这里的roughness是
之前是感性上的粗糙度,我们这里给他理性化,学术化。
这里取一个max是因为防止粗糙度为0,这样高光就没了。所以限制它有一个最小0.002。
这里就是看微平面,然后给他看作一个个的点,每一个点只有一个反射方向,当m=h的时候,才正好看到反射的光线,否则就看不到,看到了说明这个点对这里有贡献,否则就没贡献。
按照这种方式来进行一个计算,但是不可能一一去计算,所以这里就是一个概率估算。
a是粗糙度, nh是一个整体。就是之前准备的向量。ndoth。
按照右边代码的写法,而不是直接按照等式直接套上,这是和性能优化有关的。
后面加了一个10的-7,是为了分母不为零。
关于V的计算,第一种计算方式,由于消耗比较大,直接给ban了。
下面的是简化操作,简化了平方根。不是完全精确的方式。
计算完VD之后,
这里首先考虑gamma空间,如果是会进行一下处理。
然后高光还要乘以nl,主要是考虑高光的入射方向和法线做一个系数。然后还有是否开启高光,不开启的话直接赋值为0.。
any函数他的输入如果是一维的,输入0返回0,输入非0返回1.
如果多维的,输入分量全是0则返回0,分量有非0的返回1.
specColor是参数中传递进来的高光颜色(就是通过金属度来推测出的那个高光颜色)。
这里主要处理一种情况,如上注释。
F0表示的是视线和法线夹角为0度反射的颜色。
F90表示视线和法线90度时反射的颜色。
注意代码中使用的是lh,因为h是l和v的角平分线,所以这俩结果是一样的,这样lh用的多,就不必多定义一个变量vh了。
F0的位置传进来的是specColor表示,夹角比较小,反射比较弱的时候的反射。
=============================================================================================
IBL是提升效果比较明显的一部分。最影响效果表现的一部分。
主要是拿着间接光的高光来操作,首先这个高光本身是物体所有地方都有的,需要surfaceReduction来处理一下,有些地方有,有些没有,有些强有些弱。
还有就是不同角度看上去结果不同,乘以后面那个FresnelLerp。
衰减的计算:
这俩根据空间进行一个分支。
粗糙度从0到1,衰减从1到0.5.
gamma空间需要进行一个矫正,他这里需要感性的粗糙度,所以有一个四次方(本来是二次方),1/2.2就是gamma矫正。
这个近似是基本重合的。
然后就是fresnelLerp那一项,高光随着视角而变,所以参数需要nv。
为啥说他影响大呢,把这里环境source设置为custom并且指定cubemap,如果没有ibl,不同的cubemap切换带来的效果变化并不是很大,但是一旦加上ibl这一项,效果变化就会比较大。
对于PBR,我们把环境给调节好,不需要更改额外的参数来获得效果,把四项参数按照实际情况弄进去,然后把环境调节好,就会得到相应环境下对应的效果。
这里的sign有点疑问??
转自:https://china-testing.github.io/[email protected] Learning for OpenCV - 2017.pdf机器学习不再仅仅是一个流行语,它就在我们身边:从保护您的电子邮件到自动标记图片中的朋友,到预测您喜欢的电影。计算机视觉是当今最令人兴奋的机器学习应用领域之一,深度学习驱动创新系统,如自动驾驶汽车和谷歌的De...
1、什么是大前端?传统上,Web应用可分为前端(在浏览器中执行的部分)和后端(在服务器中执行的部分)。前端工程师的职责是以Web技术(HTML、CSS、JavaScript、DOM、Ajax等)实现基于浏览器的用户界面。以相衔接的工作来说,是将视觉设计师、交互设计师的工作成果转化为可运行代码,完成的代码则要交付给后端工程师,进一步完成代码集成、测试、发布和部署。这样一种体系可能存在不少问题。“大前端”则是将传统上归于后端的服务器脚本和模板划归到前端。由于node的出现,前端工程师不需要依赖于后端程序而
原题链接:https://www.luogu.org/problemnew/show/P2747据说是IOI 1993?不过既然这道题没有奶牛,所以应该不是USACO原创题。题意简述:给出n个城市,再给出m条双向边,要求求一条路径,能够从1号城市走到n号城市,再从n号城市返回1号城市,除了1号城市之外,其他城市都只能经过一次。比较有意思的是关于字符串的处理,普遍都使用了STL,然而作为...
Linux下的命令有很多,其中有一个命令,我一直使用都存在问题,那就是cp命令了。每次使用该命令,都提示cp:omitting directiory错误。最后百度了一下才明白,原来cp命令复制目录的时候需要带命令参数的。难怪我一使用cp命令就报错。下面说一下该命令的一些使用技巧:1. cp命令语法cp [options] 或 cp [options] source1 source2 ... d...
文章的例子和实验使用《LDD3》所配的lddbus模块(稍作修改)。提示:在学习这部分内容是一定要分析所有介绍的源代码,知道他们与上一部分内容(kobject、kset、attribute等等)的关系,最好要分析一个实际的“flatform device”设备,不然会只学到表象,到后面会不知所云的。总线总线是处理器和一个或多个设备之间的通道,在设备模型中, 所有的设备都通过总线相...
VisualVM 是一款免费的\集成了多个JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优。这些功能包括生成和分析海量数据、跟踪内存泄漏、监控垃圾回收器、执行内存和 CPU 分析,同时它还支持在 MBeans 上进行浏览和操作。在内存分析上,Java VisualVM的最大好处是可通过安装Visual GC插件来分析GC(Gabage Collection)趋势、内存消耗详细状况。一 Visual GC(监控垃圾回收器)Java Visu..
Python 的itertools库中提供了combinations方法可以轻松的实现排列组合。测试from itertools import combinationstest_data = {'a', 'a', 'a', 'b'}for i in combinations(test_data, 2): print i# 输出('a', 'b')from itertools import combinationstest_data = ['a', 'a', 'a', 'b']fo
一、前台服务的简单介绍前台服务是那些被认为用户知道且在系统内存不足的时候不允许系统杀死的服务。前台服务必须给状态栏提供一个通知,它被放到正在运行(Ongoing)标题之下——这就意味着通知只有在这个服务被终止或从前台主动移除通知后才能被解除。最常见的表现形式就是音乐播放服务,应用程序后台运行时,用户可以通过通知栏,知道当前播放内容,并进行暂停、继续、切歌等相关操作。二、为什么使用前台服务后台运行的...
将上面的坐标传进,得到结果:python测试代码import cv2import numpy as np src = cv2.imread('test3.jpg')# srcPoints = np.float32([[97.0,35.0],[505.0,35.0],[23.0,368.0],[586.0,368.0]])# canvasPoints = np.float3...
题目链接:BZOJ 1503每次写数据结构,都有一种debug到心力交瘁的感觉,我比出纳员还郁闷啊= =。感觉自己写这道题被各种东西坑。它是求第k大的工资,我开始求的是第k小的工资。对于那些一开始的工资就小于标准线的,不计入离开公司的人数里。还有插入和删除各种恶心,每个都要递归处理。我开始写双旋root更新不了,最后只有改。好伤心啊,看来这几天我都得刷数据结构的题了QAQ。#include
缘起地理位置(LBS),o2o这些服务在移动互联网蓬勃发展的时候里会越来越重要,这其实是在说废话。今天心血来潮,在搜索68公交站时,看到了图吧这个地图提供商,很好奇到底有多少地图提供商,就搜索了一下,做个简单的调查加吐槽。正文本次地图服务调查以国家测绘局向社会公布了31家获得互联网地图服务甲级测绘资质的单位为基础,然后在百度上一个一个搜索,点击进入官方网站。这些单位分别如下[1]:
SSD笔记:1 正负样本获得正样本获得我们已经在图上画出了prior box,同时也有了ground truth,那么下一步就是将prior box匹配到ground truth上,这是在 src/caffe/utlis/bbox_util.cpp的 FindMatches以及子函数MatchBBox函数里完成的。值得注意的是先是从groudtruth box出发给每个groudtruth ...