《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+(1s)(tcwarm+(1t)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(nl)+1,r=2(nl)nl,s=(100(rv)97)

其中常见的数学操作:限制操作 ∓ \\mp ,如限制高光混合因子取值范围;点乘操作,对于单位向量来说,可以直接计算两个向量的夹角余弦,可用于计算光线与法线夹角等;线性插值操作,在着色器内置函数中很常见,如lerpmix等。 r = 2 ( n ⋅ l ) n − l \\mathbf r=2(\\mathbf n\\cdot\\mathbf l)\\mathbf n-\\mathbf l r=2(nl)nl是用于计算光线 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=1nclightiflit(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=1n(lin)+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=plightp0plightp0《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