Unity 渲染教程(十四):雾

前向渲染中的雾

到目前为止,我们一直把光线看作是在真空进行传输的。当你的场景是设置在太空里的时候,这可能是准确的,但是在其他情况下,光线必须穿过大气层或是液体。在这种情况下,光线可以被吸收、散射和反射到空间的任何地方,而不仅仅是撞击固体表面。

准确地渲染大气干扰需要昂贵的体积方法,这是我们通常负担不起的。取而代之的是,我们将满足一个近似方法,它只依赖于一些恒定的雾参数。它被称为雾,因为这种效果通常被用于雾状大气。由清晰的大气层造成的视觉扭曲通常是如此的微妙,以至于在较短的距离内都可以忽略它们。

标准雾

Unity的光源窗口包含了一段场景中雾的设置。在默认情况下它是禁用的。当被激活的时候,你会得到默认的灰色雾。但是,这只适用于使用前向渲染路径渲染的对象。当延迟模式处于激活状态的时候,在雾的设置区域就会提到这一点。

默认的雾处于激活状态。

稍后我们将讨论延迟渲染模式中的雾。现在,让我们把注意力集中在前向渲染的雾上。为此,我们需要使用前向渲染模式。你可以更改全局渲染模式,或者强制主摄像机使用所需的渲染模式。因此,设置摄像机的渲染路径为前向渲染模式。现在让我们禁用高动态光照渲染渲染。

使用前向渲染模式的摄像机。

创建一个小的测试场景,就像在平面或立方体上的几个球体一样。使用Unity的默认白色材质。

不明显的雾。

环境光照设置为默认强度1,你会得到一些非常明亮的物体,而且没有明显的雾。

线性雾

为了让雾更加的明显,把它的颜色设置成黑色。这代表了一种吸收光线而不会散射的大气,就像浓黑的烟雾那样。

将雾的模式设置为线性。这和现实的情况不相符,但是很容易配置。你可以设定雾开始有影响的距离,以及它进行完全遮挡的距离。在中间雾的强度线性增加。这是用视图中的距离来测量的。在雾开始影响的距离之前,能见度是正常的。过了这段距离,雾将逐渐模糊物体。最后,除了雾的颜色外,什么也看不见。

线性雾。

线性雾的因子是通过函数来计算的,其中c是雾的坐标,S和E是雾开始和结束的位置。然后将这个因子限制在0-1的范围内,并用于在雾和物体的渲染颜色之间进行插值。

为什么雾不会影响到天空盒?

雾的效果调整了前向渲染物体的碎片颜色。因此,它只影响那些物体,而不会影响天空盒。

指数雾

Unity支持的第二种雾模式是指数雾,这是一种更接近于雾的近似。它使用函数,其中e是欧拉数,d是雾的密度因子。这个方程永远不会得到零,不像线性版本。将密度增加到0.1,使雾看起来更靠近镜头。

指数雾。

指数平方雾

最后一种模式是指数平方雾。这就像指数雾,但是使用了函数,这样就能在近距离产生较少的雾,但是它强度增长的速度会更快。

指数平方雾。

添加雾

现在我们知道了雾是什么样的,让我们把对它的支持添加到我们自己的前向渲染过程中。为了便于比较,将一半的物体设置为使用我们自己的材质,而剩下一半的物体则使用默认的材质。

我们的材质在左边,右边是标准材质。

雾模式由着色器关键字控制,因此我们必须添加一个多编译指令来支持它们。 有一个预定义的multi_compile_fog指令,我们可以用于此目的。 它为FOG_LINEAR,FOG_EXP和FOG_EXP2关键字带来了额外的着色器变体。 将这个指令添加到两个前向渲染通道里面。

#pragma multi_compile_fog

接下来,让我们在“MyLighting”中添加一个函数,以将雾应用到我们的片段颜色。 它将当前颜色和内插器作为参数,并应返回应用了雾的最后的颜色。

float4 ApplyFog (float4 color, Interpolators i) {

returncolor;

}

雾的效果是基于视距,等于相机位置和片段的世界位置之间的矢量的长度。 我们可以访问这两个位置,所以我们可以计算这个距离。

float4 ApplyFog (float4 color, Interpolators i) {

floatviewDistance = length(_WorldSpaceCameraPos - i.worldPos);

returncolor;

}

然后我们使用这个信息作为雾密度函数的雾坐标,它由UNITY_CALC_FOG_FACTOR_RAW宏计算。 这个宏创建了unityFogFactor变量,我们可以使用这个变量在雾和片段颜色之间进行插值。雾的颜色存储在unity_FogColor中,它在ShaderVariables中定义。

float4 ApplyFog (float4 color, Interpolators i) { </

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农老K

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值