Unity可编程渲染管线系列(七)反射(镜面和环境)

本文是Unity可编程渲染管线系列的第七部分,讲解了如何添加镜面高光和反射环境,包括镜面高光的计算、逐物体平滑度、环境反射采样、菲涅耳效应、金属表面处理、非统一缩放值的处理,以及反射探针和透明表面的支持。教程详细介绍了实现这些特性的步骤和原理。
摘要由CSDN通过智能技术生成

目录

1 高亮的高光

1.1 光滑度

1.2 表面数据

1.3 漫反射光

1.4 镜面选项

1.5 镜面高光

1.6 逐物体平滑度

2 反射环境

2.1 采样环境

2.2 调制反射

2.3 菲涅尔

2.4 金属表面

3 非同一的缩放值

3.1 移除假设条件

4 反射探针

4.1 盒投影

4.2 探针混合

4.3 HDR解码

5 透明表面

5.1 预乘Alpha

5.2 预设

本文重点:

1、添加镜面高光

2、反射环境

3、支持非同一的缩放

4、和反射探针一起工作

5、结合反射和透明度

这是涵盖Unity的可脚本化渲染管道的教程系列的第七部分。它涵盖了反射,镜面高光和采样反射探针的添加。

本教程是CatLikeCoding系列的一部分,原文地址见文章底部。“原创”标识意为原创翻译而非原创教程。

本教程使用Unity 2018.3.0f2制作。

(倒影生动起来)

1 高亮的高光

到目前为止,我们仅使用了简单的漫射照明,没有任何照明。我们现在将改变它,增加对镜面照明的支持。我们将使用与Unity的Lightweight渲染管道中使用的模型相同的模型。“渲染4,拳头照明”教程介绍了镜面照明的原理,但使用了不同的模型。

1.1 光滑度

完美的漫反射表面(即完美的漫射器)根本没有镜面反射。表面是如此粗糙,以至于没有聚焦反射发生。表面越光滑,反射的光线就越多,而不是扩散。我们将通过从0到1的平滑度材料属性(默认值为?)进行控制。

(光滑度 滑动条)

添加相应的着色器变量。

1.2 表面数据

囊括镜面反射会使我们的照明模型更加复杂。让我们将其所有代码放在一个单独的文件Lighting.hlsl中。在里面定义一个LitSurface结构,该结构包含执行照明计算所需的所有表面数据。那就是表面的法线,位置,漫反射和镜面反射的颜色及其粗糙度。还会包含视图方向,它实际上不是表面的属性,但是相对于我们正在使用的表面点而言是恒定的。

添加一个GetLitSurface函数,该函数返回Lit的表面数据。在此HLSL文件中,我们将不依赖于着色器特定的属性,纹理或定义,因此必须将所有相关数据定义为参数。尽管我们把平滑度作为输入,但是在内部,我们使用粗糙度,只是反过来而已。此外,我们现在使用金属工作流程并将自己局限于电介质材质。介电材质是非金属的,仅反射少量的光,相当于平均0.04的灰度镜面反射。就像Unity的光照代码一样,我们将对其进行硬编码。

根据迪斯尼模型(Disney model),此时我们拥有的粗糙度实际上是一个称为感知粗糙度的值。物理粗糙度是其平方。我们都需要。

在Lit.hlsl中包含Lighting.hlsl。

现在,在执行任何光照计算之前,我们可以在LitPassFragment中获取表面。视线方向就是相机位置减去片段位置(归一化)。

1.3 漫反射光

我们将把照明计算移到Lighting.hlsl。为此,为其提供一个LightSurface函数,以表面和光的方向为参数。它执行漫反射点乘积,并将其乘以表面的漫反射色。我们假设这里是理想的光线,纯白色而没有衰减。

调整MainLight,使其仅将表面作为参数,而不是位置和法向矢量。让它调用LightSurface而不是执行点乘积本身。和以前一样,在此处应用衰减和光色。

以相同的方式调整DiffuseLight,将其重命名为GenericLight,从现在开始可以更好地描述其目的。

现在,LitPassFragment必须将表面作为参数传递。而且,漫反射现在也沿途(而不是在末尾)计入颜色。在开始时,我们仍然必须将其纳入顶点照明。

我们还必须对顶点灯光使用GenericLight。顶点照明是纯漫反射的,因此仅需要位置和法线。颜色为白色,其他值无关紧要。让我们为Lighting.hlsl添加一个方便的包装函数。

然后在LitPassVertex中使用它。

1.4 镜面选项

在添加镜面高光之前,让我们可以跳过它,以便仍然支持完美的漫反射材质。我们将通过添加到表面并作为GetLitSurface的参数的布尔字段来指示默认情况下将其设置为false。这个想法是,你可以对参数进行硬编码,或者使其依赖于着色器关键字。

如果是完美的散光器(diffuser),则平滑度和镜面反射度应始终为零。

可以为您提供一个基本的Unity URP渲染管线镜面Shader示例。这个Shader将为物体表面创建一个镜面反射效果。 首先,您需要在Unity中创建一个新的URP项目。然后,您可以创建一个新的Shader文件并将以下代码添加到其中: ```csharp Shader "Custom/URP Mirror" { Properties { _Color ("Color", Color) = (1, 1, 1, 1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _Metallic ("Metallic", Range(0, 1)) = 0.5 _Smoothness ("Smoothness", Range(0, 1)) = 0.5 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Standard fullforwardshadows #include "UnityCG.cginc" struct Input { float2 uv_MainTex; }; sampler2D _MainTex; fixed4 _Color; float _Metallic; float _Smoothness; void surf (Input IN, inout SurfaceOutputStandard o) { fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb; o.Metallic = _Metallic; o.Smoothness = _Smoothness; o.Alpha = c.a; o.Specular = 1; // 启用高光 o.Specular *= c.a; // 根据纹理透明度调整高光强度 } ENDCG } FallBack "Diffuse" } ``` 这个示例中的Shader使用了标准的SurfaceOutputStandard结构,以便与Unity URP渲染管线兼容。它具有_Color(颜色)、_MainTex(主纹理)、_Metallic(金属度)和_Smoothness(光滑度)属性,您可以在材质面板中调整它们。 Shader中的surf函数定义了如何计算表面输出。在这个例子中,我们首先从_MainTex纹理中采样颜色,并将其乘以_Color属性。然后,我们将乘以纹理透明度后的结果设置为表面的漫反射颜色(o.Albedo)。_Metallic和_Smoothness属性用于设置金属度和光滑度。 在这个示例中,我们还启用了高光(o.Specular),并根据纹理透明度调整了高光强度。 最后,请将此Shader文件保存,并将其应用于您想要添加镜面反射效果的物体上。您可以通过创建一个新材质,然后将其Shader属性设置为您创建的Shader来实现这一点。 希望这可以帮助到您!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值