《Real-Time Rendering》第四版学习笔记——Chapter 5 Shading Basics
Posted 董小虫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Real-Time Rendering》第四版学习笔记——Chapter 5 Shading Basics相关的知识,希望对你有一定的参考价值。
引言
着色模型根据应用可以主要分为两大类:写实风格(photorealism)和风格化外观(stylized appearance)。
一、着色模型
着色模型描述了物体的颜色对于各种因素(如表面方向、视角、光照等)应该如何产生颜色变化。
着色模型通常包含一些属性来控制外观的变化。
以Gooch着色模型为例。该着色模型是非写实风格的着色模型,主要目的是提升工程制图领域的细节清晰度。其主要理念是对比表面法线和光源位置,同时收到视角影响。数学定义如下:
c
s
h
a
d
e
d
=
s
c
h
i
g
h
l
i
g
h
t
+
(
1
−
s
)
(
t
c
w
a
r
m
+
(
1
−
t
)
c
c
o
o
l
)
\\mathbf c_shaded=s\\mathbf c_highlight+(1-s)(t\\mathbf c_warm+(1-t)\\mathbf c_cool)
cshaded=schighlight+(1−s)(tcwarm+(1−t)ccool)
其中部分中间变量定义如下:
c
c
o
o
l
=
(
0
,
0
,
0.55
)
+
0.25
c
s
u
r
f
a
c
e
,
c
w
a
r
m
=
(
0.3
,
0.3
,
0
)
+
0.25
c
s
u
r
f
a
c
e
,
c
h
i
g
h
l
i
g
h
t
=
(
1
,
1
,
1
)
,
t
=
(
n
⋅
l
)
+
1
2
,
r
=
2
(
n
⋅
l
)
n
−
l
,
s
=
(
100
(
r
⋅
v
)
−
97
)
∓
\\mathbf c_cool=(0,0,0.55)+0.25\\mathbf c_surface,\\\\ \\mathbf c_warm=(0.3,0.3,0)+0.25\\mathbf c_surface,\\\\ \\mathbf c_highlight=(1,1,1),\\\\ t=\\cfrac(\\mathbf n\\cdot\\mathbf l)+12,\\\\ \\mathbf r=2(\\mathbf n\\cdot\\mathbf l)\\mathbf n-\\mathbf l,\\\\ s=(100(\\mathbf r\\cdot\\mathbf v)-97)^\\mp
ccool=(0,0,0.55)+0.25csurface,cwarm=(0.3,0.3,0)+0.25csurface,chighlight=(1,1,1),t=2(n⋅l)+1,r=2(n⋅l)n−l,s=(100(r⋅v)−97)∓
其中常见的数学操作:限制操作
∓
\\mp
∓,如限制高光混合因子取值范围;点乘操作,对于单位向量来说,可以直接计算两个向量的夹角余弦,可用于计算光线与法线夹角等;线性插值操作,在着色器内置函数中很常见,如lerp
或mix
等。
r
=
2
(
n
⋅
l
)
n
−
l
\\mathbf r=2(\\mathbf n\\cdot\\mathbf l)\\mathbf n-\\mathbf l
r=2(n⋅l)n−l是用于计算光线
l
\\mathbf l
l对于
n
\\mathbf n
n的反射光向量,这个方法一般在着色语言里是内置函数reflect
。
通过综合使用各种操作,可以实现多种多样的着色模型。
二、光源
在真实世界中,会有多个拥有各自不同的尺寸、形状、颜色、能量密度的光源,也有间接光需要考虑。尤其是对于写实风格的着色模型,需要将以上各种参数都要考虑到;而风格化的着色模型则会根据应用需求和视觉效果,会有不同的使用光源的方式。
着色模型对于有光照和无光照的情况下会有不同的处理方式;一些判断是否受到光照的标准:与光源的距离、阴影、表面是否朝向光源(即法线 n \\mathbf n n与光线向量 l \\mathbf l l夹角小于 9 0 ο 90^\\operatorname\\omicron 90ο),或者是多种因素综合考虑。
连续的光密度,可以简单用0到1来线性插值,或者通过其他的方法来映射无限制的的数量。常见的线性插值方法(RGB颜色、多光源):
c
s
h
a
d
e
d
=
f
u
n
l
i
t
(
n
,
v
)
+
∑
i
=
1
n
c
l
i
g
h
t
i
f
l
i
t
(
l
i
,
n
,
v
)
\\mathbf c_shaded=f_unlit(\\mathbf n,\\mathbf v)+\\sum_i=1^n\\mathbf c_light_if_lit(\\mathbf l_i,\\mathbf n,\\mathbf v)
cshaded=funlit(n,v)+i=1∑nclightiflit(li,n,v)
其中, f u n l i t f_unlit funlit可以简单的为 ( 0 , 0 , 0 ) (0,0,0) (0,0,0),表示无光照情况下为黑色;或者使用一些风格化的外观;或直接使用一些如天空盒或环境光;
光照影响可以看作是一簇光线照射于平面上的密度。光线密度与表面法线
n
\\mathbf n
n、光线的反方向
l
\\mathbf l
l夹角的余弦成正比,即如果是单位向量则是两个向量的点乘(点乘结果为正;如果为负,则是表示光线从背面进入,无影响)。故公式可以精确为:
c
s
h
a
d
e
d
=
f
u
n
l
i
t
(
n
,
v
)
+
∑
i
=
1
n
(
l
i
⋅
n
)
+
c
l
i
g
h
t
i
f
l
i
t
(
l
i
,
n
,
v
)
\\mathbf c_shaded=f_unlit(\\mathbf n,\\mathbf v)+\\sum_i=1^n(\\mathbf l_i\\cdot\\mathbf n)^+\\mathbf c_light_if_lit(\\mathbf l_i,\\mathbf n,\\mathbf v)
cshaded=funlit(n,v)+i=1∑n(li⋅n)+clightiflit(li,n,v)
总的而言,影响到最终结果的因素有:无光照函数、有光照处理函数、法线和光线夹角、光源颜色等。
2.1 方向光
方向光是最简单的光源模型。方向光的 l \\mathbf l l和 c l i g h t \\mathbf c_light clight在场景中保持不变,且光源无位置。一般情况下,方向光源用于描述距离远远大于场景尺寸的光源。举例:太阳光。
扩展性方向光:方向 l \\mathbf l l不变, c l i g h t \\mathbf c_light clight随距离发生改变。常用于在场景中限制光在部分区域生效。
2.2 精确光(Punctual Lights)
精确光表示的是存在位置的光源,无尺寸、无形状,即点状光源。注意:点状光源与点光源的区别:点光源表示在不同方向上的光线相同,与聚光灯类型不同。
光线方向计算:
l
=
p
l
i
g
h
t
−
p
0
∥
p
l
i
g
h
t
−
p
0
∥
⇒
d
=
p
l
i
g
h
t
−
p
0
,
r
=
d
⋅
d
,
l
=
d
r
\\mathbf l=\\cfrac\\mathbf p_light-\\mathbf p_0\\|\\mathbf p_light-\\mathbf p_0\\| \\Rightarrow \\beginarrayl\\mathbf d=\\mathbf p_light-\\mathbf p_0,\\\\r=\\sqrt\\mathbf d\\cdot\\mathbf d,\\\\\\mathbf l=\\cfrac\\mathbf dr\\endarray
l=∥plight−p0∥plight−p0⇒《Real-Time Rendering》第四版学习笔记——Chapter 4 Transforms
《Real-Time Rendering》第四版学习笔记——Chapter 9 Physically Based Shading
《Real-Time Rendering》第四版学习笔记——Chapter 9 Physically Based Shading
《Real-Time Rendering》第四版学习笔记——Chapter 4 Transforms
《Real-Time Rendering》第四版学习笔记——Chapter 4 Transforms
《Real-Time Rendering》第四版学习笔记——Chapter 2 The Graphics Rendering Pipeline