Unity中URP下额外灯角度衰减

文章目录

  • 前言
  • 一、额外灯中聚光灯的角度衰减
  • 二、AngleAttenuation函数的传入参数
    • 1、参数:spotDirection.xyz
    • 2、_AdditionalLightsSpotDir
    • 3、参数:lightDirection
    • 4、参数:distanceAndSpotAttenuation.zw
    • 5、_AdditionalLightsAttenuation
  • 三、AngleAttenuation函数的程序体
    • 1、我们先来看一下SdotL的结果
    • 2、cosOuterAngle:聚光灯外圈与聚光灯夹角的余弦值
    • 3、cosInnerAngle:聚光灯内圈与聚光灯夹角角的余弦值
    • 4、最后,就可以使用公式来计算了
    • 5、但是,我们在程序体中,看见的却是这样一句话
    • 6、最终、Unity还对其做了平方处理,目的是加强角度衰减效果


前言

在上一篇文章中,我们推导了URP下额外灯的距离衰减。

  • Unity中URP下额外灯的距离衰减

在这篇文章中,我们推导一下URP下额外灯的角度衰减。角度衰减只有在聚光灯中才有用。


一、额外灯中聚光灯的角度衰减

  • 衰减包括:距离衰减 和 角度衰减
  • 我们这篇文章主要分析 角度衰减,角度衰减是聚光灯独有的。

AngleAttenuation1(spotDirection.xyz, lightDirection, distanceAndSpotAttenuation.zw);

Unity中URP下额外灯角度衰减_第1张图片


二、AngleAttenuation函数的传入参数

  • 调用

AngleAttenuation1(spotDirection.xyz, lightDirection, distanceAndSpotAttenuation.zw);

1、参数:spotDirection.xyz

  • 该参数是通过内置变量获取的
    Unity中URP下额外灯角度衰减_第2张图片

  • 该内置变量是C#提前计算好的
    Unity中URP下额外灯角度衰减_第3张图片

2、_AdditionalLightsSpotDir

  • 我们来看一下C#中怎么计算得出该参数
    Unity中URP下额外灯角度衰减_第4张图片
    Unity中URP下额外灯角度衰减_第5张图片
  • 一开始会赋值一个聚光灯方向默认值
    Unity中URP下额外灯角度衰减_第6张图片
  • k_DefaultLightSpotDirection,默认值为(0,0,1,0)
    Unity中URP下额外灯角度衰减_第7张图片
  • 非平行灯下,在对距离衰减修改后,还会判断是否是聚光灯
  • 是聚光灯,则会修改聚光灯方向的默认值
    Unity中URP下额外灯角度衰减_第8张图片
  • 修改时,会获取聚光灯方向,并对其取反
    Unity中URP下额外灯角度衰减_第9张图片

3、参数:lightDirection

  • 之前计算出的,额外光方向的单位向量
    Unity中URP下额外灯角度衰减_第10张图片

4、参数:distanceAndSpotAttenuation.zw

  • 该参数是读取的内置参数
    Unity中URP下额外灯角度衰减_第11张图片
  • 该内置变量是C#提前计算好的
    Unity中URP下额外灯角度衰减_第12张图片

5、_AdditionalLightsAttenuation

  • 我们来看一下C#中,怎么计算该参数
    Unity中URP下额外灯角度衰减_第13张图片
    Unity中URP下额外灯角度衰减_第14张图片
    Unity中URP下额外灯角度衰减_第15张图片

三、AngleAttenuation函数的程序体

Unity中URP下额外灯角度衰减_第16张图片

  • 角度衰减公式: a n g l e A t t e n u a t i o n = S d o t L − c o s O u t e r A n g l e c o s I n n e r A n g l e − c o s O u t e r A n g l e angleAttenuation=\frac{SdotL - cosOuterAngle} {cosInnerAngle - cosOuterAngle} angleAttenuation=cosInnerAnglecosOuterAngleSdotLcosOuterAngle

  • 我们先看一下这些参数分别代表什么

  • SdotL:S(聚光灯方向的相反方向)点积 L(指向聚光灯方向单位向量)

  • cosOuterAngle:聚光灯外圈与聚光灯夹角的余弦值

  • cosInnerAngle :聚光灯内圈与聚光灯夹角角的余弦值

1、我们先来看一下SdotL的结果

  • 我们可以看出目标点越靠近聚光灯中心,我们的结果越趋向 1,则越亮
    Unity中URP下额外灯角度衰减_第17张图片

2、cosOuterAngle:聚光灯外圈与聚光灯夹角的余弦值

  • C#中提前把角度取Unity传入的一半,然后转弧度,再计算余弦值
  • 取一半的原因是,我们传入的值是需要的角的两倍
    Unity中URP下额外灯角度衰减_第18张图片

Unity中URP下额外灯角度衰减_第19张图片

Unity中URP下额外灯角度衰减_第20张图片

3、cosInnerAngle:聚光灯内圈与聚光灯夹角角的余弦值

  • C#中提前把角度取Unity传入的一半,然后转弧度,再计算余弦值
  • 取一半的原因是,我们传入的值是需要的角的两倍
    Unity中URP下额外灯角度衰减_第21张图片
  • 我们主要看非特效情况下
    Unity中URP下额外灯角度衰减_第22张图片
    Unity中URP下额外灯角度衰减_第23张图片

4、最后,就可以使用公式来计算了

  • 角度衰减公式: a n g l e A t t e n u a t i o n = S d o t L − c o s O u t e r A n g l e c o s I n n e r A n g l e − c o s O u t e r A n g l e angleAttenuation=\frac{SdotL - cosOuterAngle} {cosInnerAngle - cosOuterAngle} angleAttenuation=cosInnerAnglecosOuterAngleSdotLcosOuterAngle

  • 该公式其实只是起到了 平滑曲线过渡的作用
    Unity中URP下额外灯角度衰减_第24张图片

  • 该公式的作用:限制最后余弦值的结果,还达到了平滑过渡的效果

  • 当 targetPos 夹角大于 outerDir 的夹角时,余弦值反而小了,则取outerDir夹角余弦值来替代
    Unity中URP下额外灯角度衰减_第25张图片

  • 当 targetPos 夹角小于 innerDir 的夹角时,余弦值反而大了,则取innerDir夹角余弦值来替代

Unity中URP下额外灯角度衰减_第26张图片

5、但是,我们在程序体中,看见的却是这样一句话

Unity中URP下额外灯角度衰减_第27张图片

  • 原因在于,这是Unity为了节省性能,对该公式进行了化简

a n g l e A t t e n u a t i o n = S d o t L − c o s O u t e r A n g l e c o s I n n e r A n g l e − c o s O u t e r A n g l e angleAttenuation=\frac{SdotL - cosOuterAngle} {cosInnerAngle - cosOuterAngle} angleAttenuation=cosInnerAnglecosOuterAngleSdotLcosOuterAngle

= S d o t L c o s I n n e r A n g l e − c o s O u t e r A n g l e − c o s O u t e r A n g l e c o s I n n e r A n g l e − c o s O u t e r A n g l e =\frac{SdotL } {cosInnerAngle - cosOuterAngle}-\frac{cosOuterAngle} {cosInnerAngle - cosOuterAngle} =cosInnerAnglecosOuterAngleSdotLcosInnerAnglecosOuterAnglecosOuterAngle

= S d o t L ∗ 1 c o s I n n e r A n g l e − c o s O u t e r A n g l e + − c o s O u t e r A n g l e c o s I n n e r A n g l e − c o s O u t e r A n g l e =SdotL*\frac{1} {cosInnerAngle - cosOuterAngle}+\frac{-cosOuterAngle} {cosInnerAngle - cosOuterAngle} =SdotLcosInnerAnglecosOuterAngle1+cosInnerAnglecosOuterAnglecosOuterAngle

  • Unity在C#中,对其提前进行了计算
  • 使 d i s t a n c e A n d S p o t A t t e n u a t i o n . z = 1 c o s I n n e r A n g l e − c o s O u t e r A n g l e distanceAndSpotAttenuation.z=\frac{1} {cosInnerAngle - cosOuterAngle} distanceAndSpotAttenuation.z=cosInnerAnglecosOuterAngle1
  • 使 d i s t a n c e A n d S p o t A t t e n u a t i o n . w = − c o s O u t e r A n g l e c o s I n n e r A n g l e − c o s O u t e r A n g l e distanceAndSpotAttenuation.w =\frac{-cosOuterAngle} {cosInnerAngle - cosOuterAngle} distanceAndSpotAttenuation.w=cosInnerAnglecosOuterAnglecosOuterAngle
    Unity中URP下额外灯角度衰减_第28张图片
    Unity中URP下额外灯角度衰减_第29张图片

6、最终、Unity还对其做了平方处理,目的是加强角度衰减效果

return atten * atten;

  • 平方前
    Unity中URP下额外灯角度衰减_第30张图片

  • 平方后

你可能感兴趣的:(Unity,unity,游戏引擎)