Unity入门精要04(0)-更复杂的光照
创始人
2025-05-29 17:38:33
0次

本书知识点是真的多(

1.渲染路径

Unity中的渲染路径有如下选项 

   

对某一Pass指定了渲染路径后,Unity会在过程中自动填充系统的变量,便于使用。

1.1 前向渲染路径

   前向渲染的伪代码如下

一句话概括前向渲染就是:对于每个光源在其范围能影响物体的都计算一次所有的Pass(除了Base Pass以外),计算完光照后再把计算结果叠加起来。

但这如果在多光源的情况下会造成极大的性能消耗。因此Unity通常会自动进行光照质量的限制,

当然也可以自己设置

 

 在Render Mode处如果设置为Important,那么该光源就是逐像素光源。

详细参考可见  ↓↓↓

Forward rendering path - Unity 手册 (unity3d.com)

1.2 前向渲染的两种Pass

  

关于编译指令可参考

Declaring and using shader keywords in HLSL - Unity 手册 (unity3d.com)

使用这些编译指令可以产生Shader变种

 Base Pass 最基础的Pass,一个Base Pass只会进行一次平行光和其它所有的逐顶点和SH光

使用方法:在第一个Pass中加入

Tags { "LightMode"="ForwardBase" }
#pragma multi_compile_fwdbase//加入此编译命令,可以使之后光照衰减所使用的变量可以被正确赋值
//即能在BasePass中访问到正确的光照变量

 在第二个Pass中写下

Tags { "LightMode"="ForwardAdd" }
Blend One One//多光源叠加要开启混合,具体的混合操作可以看透明效果实现的那篇文章
#pragma multi_compile_fwdadd//此编译命令表示该Pass是用来进行多光源叠加的
//效果同上

Additional Pass,会计算影响该物体的所有逐像素光源,每个光源都进行一次Pass.

为了使Additional Pass 能和Base Pass进行混合,我们开启了混合命令,具体的混合命令请看《Unity入门精要》中的透明效果部分。

效果如下,我们设置绿色的为平行光,红色的为点光源

在帧调试器的时候,渲染顺序是调用Base先渲染平行光,然后调用Additional点光源远近依次渲染 

1.3 逐像素,SH光源和顶点照明(已经被抛弃)

  逐像素比较简单,略过,着重记录一下SH光源(魔方工作室的面试考到过)

球谐函数就是一组分布在球上的函数,这恰好可以描述光照在一个物体上的光照。 

详细参考:球谐光照——球谐函数 - 知乎 (zhihu.com)

2.延迟渲染。

如果游戏中有大量的实时光照,那么用前向渲染消耗会非常大,因为每个光照都会计算所有的Additional Pass,出大问题(

延迟渲染似乎只能在URP和SRP中使用?(不太清楚)

那么什么是延迟渲染?

延迟渲染分为两个Pass,第一个Pass通道用来将信息存储在G缓冲区(实际上就是输出到一张渲染纹理上)中

然后再第二个Pass进行计算光照和进行合成

可以把延迟渲染想象成一个拼图游戏。首先,你需要把所有的拼图碎片(物体)按照一定的规则(投影)放到一个大的画板(缓冲区)上,每个碎片都有自己的颜色、形状、质感等信息。这个过程叫做几何渲染(geometry rendering)。

然后,你需要把一些灯泡(光源)放到画板上,每个灯泡都有自己的颜色、亮度、方向等信息。这个过程叫做光照渲染(light rendering)。

最后,你需要把画板上的所有碎片和灯泡的信息混合起来,形成一个完整的拼图(图像)。这个过程叫做合成渲染(composition rendering)。

因此在实时光照和大量光照中延迟渲染性能更优。但延迟渲染也是有缺点的,例如

·不能支持真正的抗锯齿(因为延迟渲染使用了非常多的缓冲区来储存信息,而缓冲区的分辨率一般是和屏幕空间不同的,如果相同的话,缓冲区会占用非常多的带宽)

·不能处理半透明(因为延迟渲染相比于前向渲染是将光照计算放在三维物体投影到二维纹理之后进行光照计算。而我们在进行延迟渲染过程中是需要G-buffer,而G-buffer只能处理最前面的混合后的像素,不能记录半透明物体后面的像素)

·对显卡有一定要求,显卡必须支持MRT

延迟渲染的具体操作方法:使用两个Pass,第一个Pass用于渲染G_Buffer,用来储存漫反射颜色,高光反射颜色,自发光,平滑度,法线,深度,金属度等信息渲染到基于屏幕空间下的G缓冲区

 如图所示,更详细的可见

LearnOpenGL - Deferred Shading

 第二个Pass来计算光照,默认情况下只能用Standard 光照模型,如果要用其它的,就要替换掉原有的Internal-DeferredShaing.shader文件

延迟渲染可以访问的内置变量和函数

 3.光源类型

平行光,只有方向没有位置

点光源

聚光灯

面光源

4.光照衰减

  4.1光照衰减纹理

Unity内部使用了一张名为_LightTexture0的纹理来计算光源衰减。如果对光源使用了Cookie,那么衰减查找纹理是_LightTextureB0。

通俗来讲,这个纹理就是将光照衰减映射到纹理上,然后从(0,0)(离光源最近)依次查询到(1,1)(离光源最远)。为了知道物体上的某一点受到光照后的颜色究竟是什么?我们把物体上的所有顶点转换到光源空间下(这里就体现了Shader中的编程核心思想,要知道物体的样子,就是知道物体的颜色,要知道物体的颜色,就要根据光照模型计算,要获取光照模型中的相应参数,就应转换到相应的空间下去计算),在光源空间下查询光照衰减纹理

完整的光照衰减计算代码

#ifdef USING_DIRECTIONAL_LIGHTfixed atten = 1.0;
#else#if defined (POINT)//点光源float3 lightCoord = mul(unity_WorldToLight, float4(i.worldPos, 1)).xyz;fixed atten = tex2D(_LightTexture0, dot(lightCoord,lightCoord).rr).UNITY_ATTEN_CHANNEL;//利用顶点在光源空间的中的距离的平方进行采样(避免开方)//利用宏UNITY_ATTEN_CHANNEL获取衰减纹理中(_LightTexture0)衰减值所在的分量#elif defined (SPOT)//聚光灯float4 lightCoord = mul(unity_WorldToLight, float4(i.worldPos, 1));fixed atten = (lightCoord.z > 0) * tex2D(_LightTexture0, lightCoord.xy / lightCoord.w + 0.5).w * tex2D(_LightTextureB0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;#elsefixed atten = 1.0;#endif
#endif

重点说明一下聚光灯(比较复杂) 

在聚光灯下_LightTextureB0是阴影纹理,_LightTexture0是储存光照强度和聚光灯颜色

1.

(lightCoord.z > 0) 这里的代码其实有歧义,因为在计算聚光灯光照的时候,我们通常采用的是锥形视锥,而不是平截头视锥,因为锥形视锥更适合表示聚光灯的光照区域。在锥形视锥中,视锥的顶点在 z 轴的负半轴上,因此 z 坐标始终是负数。而这里可能重新定义了朝向也说不定。所以这里开头是判断是否在视锥中(关于这个知识,可以去看Games101中的透视投影,每次投影的时候都需要将物体平移到原点,然后旋转相机为正(或者说是光源视锥)然后投影,然后再平移旋转返回原来的样子)

2. 

tex2D(_LightTexture0, lightCoord.xy / lightCoord.w + 0.5).w

第一个tex2D函数采样聚光灯的光强和颜色信息,lightCoord.xy / lightCoord.w 这里的含义是为了将其变为非齐次坐标变为齐次坐标,我们将物体的顶点从世界空间转换到光源的视锥空间的时候,因为矩阵乘法会给w赋上一定的权重,离视点越远,x,y,z越小,投影出来就会越小(这里需要理解齐次坐标的含义,我们将(x,y,z,w)叫做齐次坐标,它实际上表示的点应该为(x/w, y/w, z/w) 就是非齐次坐标,w中储存的是顶点的逆深度(1/z)),我们使用了转换矩阵转换到光源的视锥空间,然后又使用投影矩阵投影到二维上(因为纹理是二维的,可以形象的理解压缩成二维,贴在纹理上一个一个找),但是此时的x,y仍是齐次坐标,因此要除以w,消除w所带来的透视效果,变成原本的非齐次坐标。得到真正的二维坐标,而加上0.5则是保证映射到[0,1]上(纹理的范围)

那么为什么只取w分量呢?因为tex2D函数返回RGBA四个通道,我们取第4个通道,即透明度来表示光照衰减系数。

3. 

tex2D(_LightTextureB0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL

这个阴影贴图是根据光源空间中的深度信息计算得到的,因此需要将光源空间中的坐标进行 dot 运算得到深度值,然后取两个 R 分量构成 UV 坐标,用于采样阴影贴图纹理。这样做是因为阴影贴图可能采用不同的投影方式,如果不用 dot 运算来获取深度值并计算 UV 坐标,可能会导致阴影贴图采样出现错误。

最后使用宏UNITY_ATTEN_CHANNEL获取我们生产的衰减纹理中衰减值所在的分量

4.2 使用数学公式计算衰减

 

 

相关内容

热门资讯

在大吉订购APP订购交易亏损被...   近期,不少投资者反映在“大吉订购App”上投资白银、铂金等商品遭遇严重亏损。该平台宣称提供现货订...
铂银壹号APP商品订购交易亏损...   许多中小投资者误以为网上的“商品现货订购”是合规合法的理财渠道,殊不知这背后隐藏着巨大的合规风险...
兴鑫淘金APP贵金属订购交易亏...   白银、贵金属或其他商品类投资,除国家批准的正规期货交易场所及持牌期货公司外,市面上大量第三方交易...
铂银掘金APP无资质的违规平台...   铂银掘金等平台的投资者,往往是被“注册送现金”“充值返现券”“首单免亏”等广告话术吸引,进而下载...
八方淘金APP订购交易不合规,...   “八方淘金APP”“铂银掘金APP”“铂银壹号APP”等软件被指以“现货订购”为名,实际采用高杠...
在指尖订购APP订购商品亏损被...   指尖订购APP这类平台,表面是“订购交易”,实则是披着电商外衣的非法期货陷阱。绝大多数投资者被蒙...
在犀贝易购APP做商品订购交易...   市面上打着“现货投资”“贵金属交易”旗号的APP并不少,但真正合规、受监管的平台并不多。犀贝易购...
易达淘金APP虚假商品订购交易...   易达淘金APP存在严重的虚假宣传与违规交易行为。该平台打着“商品订购”的旗号,实则通过不合规的交...
大浪淘金APP白银订购亏损被骗...   大浪淘金APP最隐蔽的套路,在于其完全封闭的内盘交易系统。表面上,它宣称与国际贵金属市场接轨;实...
一品好购APP上订购白银出现亏...   一品好购APP原名“一品订购”,运营方为上海宝智未来信息技术有限公司。近期不少投资者反映在该平台...
九州订购APP贵金属订购投资骗...   九州订购APP正通过抖.音、快手、今日头条等平台大量投放投资广告,用“5元起投”“充值返现”“0...
坚锅淘金APP交易软件并不正规...   当前,市面上大量所谓的“现货商城订购”交易软件,早已偏离了正常的实物商品买卖,演变为高杠杆、高手...
斗金订购APP贵金属期货交易骗...   斗金订购APP的投资者往往被铺天盖地的广告宣传所诱导——注册即送现金、充值返现券等看似诱人的福利...
警惕!云启购APP违规经营,披...   "5元起投、充值返现、稳赚不赔"——这些诱人的广告语背后,可能是一个精心设计的金融陷阱。  近期...
量子淘金APP贵金属投资不合规...   "4元起投""充值返券""月入过万"——这些极具诱惑力的广告语在短视频平台、社交软件上铺天盖地。...
鑫汇智投APP贵金属商品订购骗...   鑫汇智投APP非法期货投资骗局,受害者在投资过程中根本不懂交易,也不去研究和验证这个平台是否正规...
矅光智策APP平台违规经营非法...   矅光智策APP对外宣称是“商城订购”“现货交易”,但查询其经营范围,并未显示具备开展现货期货交易...
黄金珠宝怎么选?内侧刻字都代表... 潮新闻客户端 记者 马焱 通讯员 任倩影 9月8日下午,“云游杭州 乐购金秋”——“浙城·浙放心”活...
原创 冰... 最近全球国债市场正在上演魔幻一幕: 美债、日债、欧债遭遇猛烈抛售,收益率冲到几十年新高,美国财政部都...
日韩股市开盘表现分化 上证报中国证券网讯 9月9日,日韩股市开盘表现分化,韩国综合指数开盘上涨0.26%,报6972.87...