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);

在这里插入图片描述


二、AngleAttenuation函数的传入参数

  • 调用

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

1、参数:spotDirection.xyz

  • 该参数是通过内置变量获取的

    在这里插入图片描述

  • 该内置变量是C#提前计算好的

    在这里插入图片描述

2、_AdditionalLightsSpotDir

  • 我们来看一下C#中怎么计算得出该参数

    在这里插入图片描述

    在这里插入图片描述

  • 一开始会赋值一个聚光灯方向默认值

    在这里插入图片描述

  • k_DefaultLightSpotDirection,默认值为(0,0,1,0)

    在这里插入图片描述

  • 非平行灯下,在对距离衰减修改后,还会判断是否是聚光灯
  • 是聚光灯,则会修改聚光灯方向的默认值

    在这里插入图片描述

  • 修改时,会获取聚光灯方向,并对其取反

    在这里插入图片描述

3、参数:lightDirection

  • 之前计算出的,额外光方向的单位向量

    在这里插入图片描述

4、参数:distanceAndSpotAttenuation.zw

  • 该参数是读取的内置参数

    在这里插入图片描述

  • 该内置变量是C#提前计算好的

    在这里插入图片描述

5、_AdditionalLightsAttenuation

  • 我们来看一下C#中,怎么计算该参数

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述


三、AngleAttenuation函数的程序体

在这里插入图片描述

  • 角度衰减公式:

    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=cosInnerAngle−cosOuterAngleSdotL−cosOuterAngle​

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

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

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

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

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

  • 我们可以看出目标点越靠近聚光灯中心,我们的结果越趋向 1,则越亮

    请添加图片描述

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

  • C#中提前把角度取Unity传入的一半,然后转弧度,再计算余弦值
  • 取一半的原因是,我们传入的值是需要的角的两倍

    在这里插入图片描述

在这里插入图片描述

请添加图片描述

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

  • C#中提前把角度取Unity传入的一半,然后转弧度,再计算余弦值
  • 取一半的原因是,我们传入的值是需要的角的两倍

    在这里插入图片描述

  • 我们主要看非特效情况下

    在这里插入图片描述

    请添加图片描述

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=cosInnerAngle−cosOuterAngleSdotL−cosOuterAngle​

  • 该公式其实只是起到了 平滑曲线过渡的作用

    在这里插入图片描述

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

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

    在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

  • 原因在于,这是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=cosInnerAngle−cosOuterAngleSdotL−cosOuterAngle​

=

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}

=cosInnerAngle−cosOuterAngleSdotL​−cosInnerAngle−cosOuterAnglecosOuterAngle​

=

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}

=SdotL∗cosInnerAngle−cosOuterAngle1​+cosInnerAngle−cosOuterAngle−cosOuterAngle​

  • 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=cosInnerAngle−cosOuterAngle1​

  • 使

    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=cosInnerAngle−cosOuterAngle−cosOuterAngle​

    在这里插入图片描述

    在这里插入图片描述

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

return atten * atten;

  • 平方前

    请添加图片描述

  • 平方后

    请添加图片描述

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://www.net2asp.com/5b8b7e064f.html