unity 渲染是怎么进行渲染的?自带吗???

译者:崔嘉艺(milan21)

审校:王磊(未来的未来)

  • 根据视野方向来偏移纹理坐标

  • 使用一个高度字段来创建有深度的错觉。

  • 通过一个高度字段来跟踪一条射线

  • 近似或是搜索┅个相交点

这是关于渲染基础的系列教程的第二十部分。在前面的部分里我们涉及了图形处理器的实例化这一次,我们将添加迄今为止鈈支持的标准着色器功能的最后一部分也就是视差贴图。








由于透视带来的效果当我们调整我们的视角的时候,我们会看到事物被观察箌的相对位置发生了变化这种视觉上的现象被称为视差。在高速前进的时看向侧边是最明显的当快速移动的时候,附近的东西看起来佷大而遥远的背景看起来很小,并且移动较慢

至少在透视模式下使用相机的时候,我们已经在渲染的时候考虑到了透视带来的影响 洇此,几何体会变现出视差效果

我们还使用法线贴图将表面不规则的错觉加到平滑的三角形上。这会影响到光照但是不影响三角形表媔的实际形状。因此这个效果不会显示视差的效果。这限制了我们通过法线地图可以添加的深度上的错觉

下面是一张反照率图贴图和法线贴图,表明这里有许多高度上的差异

反照率图贴图和法线贴图。

导入这些纹理然后创建一个使用它们的材质和一个着色器My First Lighting Shader。 用单個四边形创建一个新的场景旋转(90,00),使其平放着并给它赋予这个材质。

有法线贴图的四边形和没有法线贴图的四边形的效果对仳图

没有法线贴图的,四边形显然是很平坦的添加法线贴图使这个四边形看起来像是表面不规则的。然而高度上的差异似乎很小。當从一个比较浅的视角观察四边形的时候这变得明显。 如果高度上的差异较大表面特征的相对视觉位置由于视差会发生很大的变化,泹是在我们这种情况里没有发生这个效果我们看到的视差是平坦的表面。

当从一个比较浅的视角观察四边形的时候看到的效果

我们可鉯提高法线贴图的强度,但这并不会改变视差 此外,当法线贴图变得太强烈的时候看起来会很奇怪。光照的效果告诉我们这是一个陡峭的斜坡而视差告诉我们它是平坦的。 所以法线贴图只适用于不会出现明显视差变化的小的变化

当法线贴图变得太强烈的时候,依然佷平坦

为了获得真正的深度感,我们首先需要确定应该有多深法线贴图不包含此信息。 所以我们需要一个高度图有了这个高度图,峩们就可以会创建假的视差就像我们创建假的斜坡一样。下面是我们材质的贴图它是灰度图,黑色代表最低点白色表示最高点。 因為我们将使用这个贴图创建一个视差效果它通常被称为视差贴图而不是高度贴图。

确保在导入的时候禁用sRGB(颜色纹理)这样在使用线性渲染的时候数据不会被弄乱。

为了能够使用视差贴图我们必须为MyFirst Lighting Shader.着色器添加一个属性。 就像对遮挡效果所做的事情一样我们也要给咜一个强度参数来缩放整个效果。因为视差效果相当强我们将其范围设置为0-0.1。

视差贴图是一个着色器功能我们使用_PARALLAX_MAP关键字来启用。将所需的编译器指令添加到基础渲染通道附加渲染通道和延迟渲染的渲染通道中。

阴影投射渲染通道不需要视差处理么

我们的视差效果會影响纹理。 当使用反照率图的Alpha通道中的不透明度的时候纹理仅影响阴影。它很少与视差贴图结合起来使用即使是这样,阴影贴图中嘚视差效果也很少会被注意到 所以通常不值得花费额外的计算时间来这么做。但是如果您想这么做的话,您可以把视差处理添加到阴影投射渲染通道并相应地调整My Shadows 着色器。

要访问新的属性请将相应的变量添加到 MyLighting。

为了让材质可配置化可以在MyLightingShaderGUI中添加DoParallax方法。 您可以复淛它的DoOcclusion方法并更改属性名称标签和关键字。像遮挡贴图一样unity 渲染的标准着色器希望将高度数据存储在纹理的G通道中。所以我们也会这樣做并在工具提示中指出这一点。

现在可以为我们的材质分配视差贴图了这样做以后,将其强度设为一个比较低的值比如说是0.03。

为叻应用视差效果我们必须使表面的某些部分看起来像是在别的地方。这是通过调整片断程序中的纹理坐标来完成的在My Lighting.中MyFragmentProgram上方的某个地方创建一个ApplyParallax函数来做这个事情。这个函数将在需要的时候调整内插数据因此请给它一个inout Interpolators参数。

在使用内插数据之前应该在我们的片段程序中调用ApplyParallax函数。唯一例外的是 LOD的渐变这是因为它取决于屏幕的位置。我们不会调整这些坐标

首先,通过简单地将视差强度加到U坐标仩来调整纹理坐标只有在启用视差功能的时候才能做这一点。

改变视差强度现在会使纹理发生滚动 增加U坐标将纹理移动到负U的方向。 這看起来不像视差效果因为它是一个均匀的位移,而且它与视点的位置独立

视差由相对于观察者的透视投影引起。所以我们必须考虑箌这一点来偏移纹理坐标这意味着我们必须根据视角方向来偏移坐标,这对于每个片段程序是不同的

视角方向沿着表面会发生变化。

紋理坐标存在于切线空间中为了调整这些坐标,我们需要在切线空间中知道视角的方向这将需要一个空间变换,而空间变换意味着矩陣乘法我们已经在片段着色器中有一个切线空间的矩阵,但是它们是从切线空间到世界空间的变换在这种情况下,我们需要向另一个方向变换我们可以将另一个矩阵传递给片段程序并在片段程序中使用这个矩阵,但是这么做会开销很大

视角的方向被定义为从表面到楿机的矢量,并且做了归一化 我们可以在顶点程序中确定此向量,然后将其转换到片段程序我们推迟归一化的执行时间,直到插值后財进行归一化我们最终得到正确的方向。那么我们只需要将正切空间的视图方向加进来作为新的内插器就可以了

我们有空间来容纳第⑨个插值器么?

当目标是着色器模型3以及以上的硬件是的,有足够的空间但是目标是在着色器模型3之下的硬件,那么我们智能使用八個通用高精度插值器当我们目标是着色器模型3以及以上的硬件的时候,我们可以使用TEXCOORD8 不支持这种的硬件通常不是很强大,所以您不会想在这些硬件上使用视差贴图的

我们可以在顶点程序中使用来自网格数据的原始顶点切线和法向量创建一个对象空间到切线空间的变换矩阵。因为我们只用它来转换一个向量 -而不是一个位置 - 我们可以用3×3矩阵来满足要求

接下来,我们需要在对象空间中的顶点位置到视点嘚方向这样我们就可以使用ObjSpaceViewDir函数。变换会使用我们的矩阵这样我们就有需要的信息。

ObjSpaceViewDir函数在unity 渲染CG中定义它将相机位置转换到对象空間中去,然后从其中减去所提供的顶点位置这个位置是定义在对象空间中的。请注意这会产生从顶点指向相机的向量。它还没有进行歸一化这正是我们想要的。

现在我们可以访问ApplyParallax中的切线空间的视角方向首先,对它进行归一化使其成为一个正确的方向向量。 然后将其XY分量添加到由视差强度调制的纹理坐标上去。

这样做有效地将视角方向投影到纹理表面上当以90°的角度看直线的时候,切线空间中的视角方向等于表面法线(0,0,1),这导致不需要位移视角越浅,投影越大位移效应越大。

用于UV偏移的投影后的视图方向

所有这一切嘚效果是,基于视差强度表面看起来在切线空间中向上拉起,看起来高于实际的位置

沿着投影后的视角方向便宜UV坐标。

到目前为止峩们可以使表面看起来比实际更高,但它仍然是均匀的位移 下一步是使用视差贴图来缩放位移。对贴图进行采样使用其G通道作为高度,应用视差强度并用它来调节位移。

低的区域现在仍然在那里而高的区域则被拉高。标准着色器抵消了这种影响所以低的区域也向丅移动,而中间区域仍然保留在它们原来的位置上这是通过从原始高度数据中减去1/2来完成的。

视差贴图在合理的强度的效果以及超越匼理的强度的效果。

这产生了我们正在寻找的视差效果但它只能在低强度下工作。位移迅速变得太大而撕开了表面

我们目前使用的视差贴图技术被称为具有偏移限制的视差贴图。我们只是使用视角方向的XY部分其最大长度为1。因此纹理的偏移是有限的。这个效果可以嘚到一些体面的结果但并不代表有正确的透视投影。

更精确的计算偏移量的方法是将高度场视为几何表面以下的体积并通过它来发射┅个视线。这个射线从相机射到表面从表面的上方进入高度场体积,并继续前进直到它击中由高度场所定义的表面为止。

如果高度场均匀为零则射线将继续前进到达体积的底部。距离有多远取决于射线进入体积的角度这个距离没有限制。角度越浅的话距离越远。 朂极端的情况是当视角接近零的时候会使得使射线射向无限远的地方。

射线到达底部在有限便宜和正确偏移下的效果对比。

为了找到適当的偏移量我们必须对视角方向向量进行缩放,所以它的Z分量变为1我们将它除以自己的Z分量来做到这一点。因为我们以后不需要使鼡Z分量所以我们只需要把X分量和Y分量除以Z分量。

虽然这导致更正确的投影但这么做会使得浅视角的效果产生瑕疵。标准着色器通过向Z汾量添加偏差来减轻这一点这里用 的偏差是0.42,所以它从不接近于零这扭曲了透视,但是让这些瑕疵更易于管理 让我们也加上这个偏迻。

类似标准着色器中的视差贴图效果

我们的着色器现在支持与标准着色器相同的视差效果。虽然视差贴图可以应用于任何表面但是投影假设切线空间是均匀的。曲面具有弯曲的切线空间因此会产生不正确的结果。只要视差强度和曲率小就可以避免这一点。

一个球體上的视差贴图效果

此外,阴影坐标也不受视差贴图的影响 结果就是,在强视差的情况下阴影可以看起来很奇怪,似乎漂浮在表面嘚上方

阴影不受视差贴图影响。

您是否赞同unity 渲染将偏移设为0.42 您想使用不同的值,还是让它在零 还是想使用偏移来进行限制? 让我们來把这些内容变成可配置化!

}

该楼层疑似违规已被系统折叠 

让峩们先做第四步先看到所有的粒子,再想办法更新

这里楼主图快,用一个比较简单的办法

每个粒子渲染24个顶点,用6个Quad组成一个Cube

至於为什么要Cube,没有为什么。 我就是喜欢Cube


}

我要回帖

更多关于 unity 渲染 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信