Unity可编程渲染管线系列(三)光照(单通道 正向渲染)

本文详细介绍了Unity中可编程渲染管线的光照实现,包括漫反射着色、支持方向光、点光源和聚光灯,以及如何处理可见光限制。通过调整着色器和管线设置,实现了每个对象最多8个灯光的渲染,同时探讨了逐物体光照优化,支持最多16个可见光源。此外,还讨论了顶点光和像素光的计算以及过多或无可见光的处理策略。
摘要由CSDN通过智能技术生成

目录

1 受光的着色器

1.1 Lit 着色器

1.2 法线向量

1.3 漫反射光

2 可见光

2.1 光缓冲

2.2 填充缓冲区

2.3 配置灯光

2.4 可变的灯光数量

3 点光源

3.1 灯光位置

3.2 距离衰减

3.3 灯光范围

4 聚光灯

4.1 聚光方向

4.2 角度衰减

5 逐物体光照

5.1 灯光索引

5.2 多可见光

5.3 顶点光

5.4 过多的可见光

5.5 0可见光

本文重点:

1、漫反射着色

2、支持方向光、点光源和聚光灯

3、每帧允许16个可见光源

4、每个对象最多计算四个像素光和四个顶点光

这是涵盖Unity可编写脚本的渲染管线的教程系列的第三部分。这次,我们将通过一个Drawcall为每个对象最多着色8个灯光来增加对漫反射光照的支持。

本教程使用Unity 2018.3.0f2制作。

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

(256个球 8个灯光 214个 draw calls)

1 受光的着色器

为了支持灯光,我们必须在管线中添加一个照明着色器。照明的复杂性可以从非常简单的(仅包括漫射光)到非常复杂的成熟的基于物理的阴影。或者像卡通渲染一样,它也可以是不真实的。我们将从最小的照明着色器开始,该着色器可用于计算没有阴影的漫反射的定向光。

1.1 Lit 着色器

复制Unlit.hlsl并将其重命名为Lit.hlsl。将新文件中所有unlit的地方替换为Lit,特别是包含定义以及顶点和片段函数名称。

复制Unlit.shader并将其重命名为Lit.shader,在新文件中再次将Unlit替换为lit。

不应该要使用一个lit的通道(pass)吗?

因为我们的管线仍然非常的基础,所以先不管。

现在,我们可以使用新的着色器创建一个受光的不透明材质,尽管它仍然与不受光的变体完全一样。

(不受光的着色器资产)

1.2 法线向量

为了计算定向光的贡献,我们需要知道表面法线。因此,我们必须向顶点输入和输出结构都添加法线向量。有关如何计算照明的详细说明,请参见渲染4,第一个照明

在LitPassVertex中将法线从对象空间转换为世界空间。因为我们假设仅使用统一的比例尺,所以我们可以简单地使用模型矩阵的3×3部分,然后在LitPassFragment中对每个片段进行归一化。对非均匀比例尺的支持会需要我们使用转置的世界到对象矩阵。

为了验证我们最终得到正确的法向矢量,请将它们用作最终颜色。但是仍然要跟踪该材质,因为我们稍后将其用于反照率。

(显示原始世界空间法线向量)

1.3 漫反射光

漫射光的贡献取决于光入射到表面的角度,该角度是通过计算表面法线的点积与光的出射方向得出的,从而消除了负的结果。在定向光的情况下,光矢量是恒定的。现在让我们使用一个硬编码的方向,笔直向上。将漫射光与反照率相乘以获得最终颜色。

(从入射光的0°到90°角度的漫反射衰减)

(顶面的漫反射)

2 可见光

为了能够使用场景中定义的灯光,我们的管线必须将灯光数据发送到GPU。一个场景中可能有多个灯光,因此我们也应该支持多个灯光。有多种方法可以做到这一点。Unity的默认管线针对每个对象在单独的通道中渲染每个灯光。轻量级管线针对每个对象在一次通道中渲染所有灯光。HD管线使用延迟渲染,该渲染将渲染所有对象的表面数据,然后每光源渲染一遍。

我们将使用与“轻量级”管线相同的方法,因此每个对象都要渲染一次,并考虑所有光照。通过发送GPU当前可见的所有灯光的数据来实现。场景中不影响渲染的任何灯光都会被忽略。

2.1 光缓冲

一次渲染所有灯光意味着所有灯光数据必须同时可用。目前仅限于定向光,这意味着我们需要知道每种光的颜色和方向。为了支持任意数量的灯光,我们将使用数组存储此数据,并将其放入一个单独的缓冲区中,该缓冲区名为_LightBuffer。像在C#中一样,在着色器中定义数组,但方括号在变量名称之后而不是类型后面。

但是,我们不能任意定义数组的大小。数组定义必须立即声明其大小。让我们使用4的数组长度。这意味着我们可以一次支持多达四个可见光。使用宏定义此限制,以方便参考。

在灯光缓冲区下方,添加一个DiffuseLight函数,该函数使用灯光数据来进行光照计算。它需要一个光索引和法线向量作为参数,从数组中提取相关数据,然后执行漫射照明计算并将其返回,并由光的颜色进行调制。

在LitPassFragment中,使用for循环对每个光调用一次新函数,从而累积影响片段的总漫射光。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值