Chapter 3. Visual Appearance 视觉外观 金小刚 Email: jin@cad.zju.edu.cn 浙江大学CAD&CG国家重点实验室
简 介 “Light makes right” - Andrew Glassner 简 介 “Light makes right” - Andrew Glassner 当绘制三维物体时,模型应不仅从从几何上看正确,而且应具有真实的视觉外观 实现方法:通过给表面设置材料、应用光源、加纹理、用雾、透明、反走样、合成等技术
光源(Light Sources) 人为何可以看见物体? 光子从物体表面发出或反射到达观察者的眼睛。这些光子可以来自光源或其它物体。 这里主要讨论三类光源: (1). 方向(平行)光源 directional lights (2). 点光源 point lights (3). 聚光灯 spotlights
方向光:放在离物体无穷远的地方。 例子:太阳光 点光源和聚光灯都称为位置光源,因为它们都有一个位置。点光源可看成发射光子的点。 发散角 方向光:放在离物体无穷远的地方。 例子:太阳光 点光源和聚光灯都称为位置光源,因为它们都有一个位置。点光源可看成发射光子的点。 聚光灯参数:方向矢量sdir、发散角scut、Spot exponent sexp(控制光从中心向周围的衰减)
一个长方形网格(100×100×2个三角形), 受平行光,点光源和聚光灯照射的光照效果
光源参数:亮度和颜色 一个光源可进一步细分为: ambient, diffuse, specular intensity Notation Description samb Ambient intensity color sdiff Diffuse intensity color sspec Specular intensity color spos Light Source position
在现实世界中,光源会随距离的平方衰减 在实时绘制中,光源通常不随距离衰减。这样做的原因: (1). 容易控制(不必担心距离效应) (2). 计算速度快
材质(Material) 在实时绘制系统中,材质包含的参数:ambient, diffuse, specular, shininess (会聚指数), and emissive 物体的颜色最终由下面的参数决定:材质参数、照射表面的光源参数、光照模型
材质符号表示 Notation Description mamb Ambient material color mdiff Diffuse material color mspec Specular material color mshi Shininess parameter memi Emissive material color
材质参数对外观的影响 第一排:Ambient变化的影响;第二排:Diffuse变化的影响 第三排:Specular变化的影响;第四排:Shininess变化的影响
Lighting and Shading Lighting: 用来指定材质、光源和物体几何之间的相互作用。 三种Shading类型:Flat,Gouraud,Phong 对应于按每个多边形、顶点、象素计算光亮度
Flat Shading:为每个三角形计算一颜色,整个三角形以该颜色填充。 Gouraud Shading:先计算三角形每个顶点的光亮度,然后在三角形上插值光亮度 Phong Shading: 对于每个象素,根据多边形顶点的法向插值计算得到象素的法向,然后用该法向计算光亮度
Flat Shading的优点:简单、快速、可看清曲面蕴涵的小面片。缺点:绘制的曲面看起来不光滑 Flat Shading Gouraud Shading Phong Shading Flat Shading的优点:简单、快速、可看清曲面蕴涵的小面片。缺点:绘制的曲面看起来不光滑 Gouraud Shading:绘制的曲面较光滑、快速(基本上与Flat Shading一样快 ),绝大多数图形硬件支持。
Gouraud Shading的缺点 2 18 288个三角形 256 1024 16384个三角形 绘制效果与物体的层次细节密切相关
Gouraud Shading的其它缺点:丢失高光、丢失聚光灯效果、Mach带效应。 部分解决方法:采用带有光照效果的纹理 Phong Shading可以避免上述缺陷,但算法复杂、计算量大。商用的大部分图形卡不支持。
在Gouraud Shading中,如果把三角形剖分成比象素还小,则Gouraud Shading可取得和Phong Shading一样的绘制效果。但需较大的速度代价。因而该思想很少在实时绘制系统实施。 顶点的照明采用光照模型(Lighting Model)计算。在实时绘制中,所有的光照模型都非常相似,主要分成三部分: ambient, diffuse, specular ambient diffuse specular result
实时绘制的光照模型通常不完全基于物理理论,但容易控制且结果基本可以接收。 大部分图形加速卡采用类似的光照明模型。 Vertex 和Pixel Shading支持程序员把自己的shader写入硬件。
Diffuse Component l l 基于Lambert 定律:对于理想的漫反射表面,其反射光由表面法向n和光矢量l的余弦决定: 几何解释 l
漫反射与摄像机的位置和方向无关,即漫反射分量是View independent。 为了利用光源和物体的漫反射颜色,我们改造上述方程,得到漫反射贡献: 由于表面法向n和光矢量l的夹角大于900时,漫反射分量为0,得到 注:部分波长的光子会被材料吸收。例如,若 则
Specular Component 镜面反射主要使得物体看起来发亮(shiny),有高光。高光帮助观察者了解问题的曲率,并判断光源的位置和方向。 没有镜面反射 有高光
假设表面点为p,v为p到观察者的矢量,r为光矢量对于法向n的反射矢量: 该公式称为Phong光照方程。镜面分量是view dependent
反射矢量r的计算:
OpenGL和DirectX采用的光照方程 由Blinn提出的光照方程的另一形式 采用该方程的原因:不需要计算反射矢量,速度快
OpenGL和Direct3D采用的光照方程 若考虑物体的材质和光源的参数 当n和h的夹角大于900时,镜面反射分量为0,得到
会聚指数越大,则高光区域越窄
但Phong光照模型也会出现缺陷…… Artifacts Gouraud Shading Little tessellation Gouraud Shading High tessellation Per-pixel Shading 当会聚指数较小时(高光区域较大),随着Shading算法的改善,Phong高光反而会出现缺陷。这会在(n.l)<0,高光部分突变为0时出现。
其它镜面高光函数 Schlick的快速逼近方法(不需要指数) Blinn采用微面元(用来模拟粗糙表面)来模拟粗糙表面的自阴影。
与标准模型有很大差别的简单函数 T=0.35 T=0.7 其中T为阈值。如果max(n.h,0)大于T,则用1,否则用0作为乘子。该方程可模拟面光源在镜面上产生的反射效果。T用来控制高光斑的大小。
Ambient Component 在真实世界里,从光源发出的光会在墙上反弹,最后到达物体。但这部分光既不计入漫反射也不计入镜面反射中。为了模拟这部分间接的光照效果,光照明模型应加入泛光项: 这样,即使背离光源的表面看起来也不会是完全黑的。
Lighting Equation Local lighting model: 只计算了从光源直接发出的光,而没有考虑从其它表面发出的光。 ambient diffuse specular result
Lighting Equation 在现实世界中,光强物体与离光源距离的平方成反比,这类衰减还没有考虑。衰减只对位置光源成立,而且,只有漫反射和镜面反射部分受影响。衰减通常用下面的公式来模拟: 其中||spos-p||为光源与绘制点之间的距离。sc用来控制常数衰减; sl用来控制线性衰减; sq用来控制二次衰减。物理真实的距离衰减可通过设置sc=0, sl=0, sq=1来模拟。
考虑衰减的光照明公式: 对于聚光灯, 还需要考虑另一参数cspot。若绘制点位于聚光灯的圆锥之外, cspot=0。若绘制点位于聚光灯的圆锥之内,则 其中l为光矢量,sdir为聚光灯矢量, sexp为控制光从聚光灯中心向周围衰减的指数因子。 如果不是聚光灯,则cspot=1。修正的光照方程为
材质中还有一自发光参数memi,主要用来直接在物体表面加颜色。 在OpenGL,Direct3D等API中,还有一全局泛光参数aglob,用来近似从四面八方发出的背景光。考虑这两个参数的光照明模型:
前面考虑的是单个光源的情形。如果有n个光源,则最后的光照明公式为:
Aliasing and Antialiasing 每个象素采样4个点 每个象素采样9个点 无反走样 三角形、直线、点不同层次的反走样 局部放大
采样和滤波理论 绘制一幅图像可看成是一个采样任务。 采样三维场景获得每个象素的颜色; 在纹理映射中,需要对纹素(texel)重采样; 为了获得一段动画,需要对动画过程采样; 我们将讨论采样、重建和滤波。为了简单起见,主要在一维空间讨论,类似的思想可推广到二维、三维;
一维连续信号的采样 在采样过程中,部分信息会丢失,导致走样。 采样 重建 连续信号 采样信号 重建信号
走样的经典例子:一个旋转的轮子 由于轮子旋转的速度比摄像机记录图像的速度要快,最后轮子看起来转的很慢或者根本没有旋转。 该现象称为时间域采样(temporal aliasing)。
为了使得能从采样信号重建原始信号,采样频率必须比原始信号最大频率的两倍大 (采样定理) 重建信号 原始信号 重建信号 当信号被采样的频率太低时,走样会产生。 为了使得能从采样信号重建原始信号,采样频率必须比原始信号最大频率的两倍大 (采样定理)
重建 箱滤波器 帐篷滤波器 sinc滤波器 在重建时,需要用滤波器。上图为三个常用的滤波器。注意:滤波器的面积始终为1
Box Filter重建 把Box滤波器放在每个采样点上,在y方向比例缩放至采样点的高度,然后求和得到重建信号。 缺点:结果呈阶梯形,不连续。但由于简单,图形学中仍常用。
Tent Filter(也称三角形滤波器)重建 该滤波器对采样点进行线性插值,结果连续,比箱滤波器好。 缺点:C0连续,但C1不连续。在采样点处斜率突然变化。
为了获得完美的重建结果,最好采用理想的低通滤波器。 低通滤波器把所有高于某一(由滤波器定义的)特定频率的高频分量过滤掉。从而把所有的尖锐特征过滤掉。 一个理想的低通滤波器为sinc滤波器
Sinc Filter重建 在采样过程中会引入高频信号,sinc滤波器把所有高于采样频率1/2的正弦波信号过滤掉。
假设采样频率为fs, 即相邻采样之间的区间为1/fs ,则理想的重建低通滤波器为sinc( fs x)。
Resampling(重采样) 重采样用于采样信号的放大或缩小。 假设原采样点位于整数坐标(0,1,2,…),重采样后,新采样点之间的间距为a,则当a>1时,为downsampling;当a<1时为upsampling
upsampling 采样信号 重建信号 重采样信号(放大)
downsampling 采样信号 重建信号 重采样信号(缩小)
基于屏幕的反走样 可能会出现走样的地方:多边形的边、阴影边界、镜面高光边界等颜色突变的地方。 基于屏幕的反走样策略:象素p的颜色取为采样模板上采样点颜色的加权平均 其中n为采样点的数目,c(i, x, y)为采样点的颜色,wi为权因子。 在实时绘制系统中,权因子常取为常数wi=1/n
超采样(Supersampling) 所有采用在每个象素上采样超过一个点的反走样算法称为Supersampling。 Full-Scene Anti-Aliasng (FSAA): 通过高分辨率绘制场景,然后把相邻的采样点进行加权平均得到一幅图像。 例子:若需绘制500X400的反走样图像,则可先绘制1000X800的图像,然后用2X2采样模板进行加权平均(每个象素用4个采样点)
累积缓存反走样法 为了得到场景2X2的采样模板,通过在x或y方向移动半个象素的视域,生成4幅图像,然后在累积缓存中进行加权平均。 累积缓存(Accumulation buffer)为OpenGL的一部分,很多硬件系统支持。可以用来生成运动模糊、景深等效果。 但由于场景需要绘制多次,影响速度,在实时绘制系统中较少使用。
T-buffer T-Buffer一词源于3dfx公司的首席技术官—Gary Tarolli的名字。 T-buffer是Accumulation buffer的一个变种,它包含2个,4个,或者更多个图像buffer和Z-buffer,每个都可以用于绘制。 有一个mask,专门用来决定三角形送往哪个buffer。 数据可以同时送到所有的buffer。对于每个buffer,屏幕的x、y偏移量可个别地设置。
所有的三角形可以只送一次,而不是多次,在buffer中并行处理。每个buffer有稍微不同的的视域偏移量,通过加权平均得到反走样图像。
T-buffer 和 Accumulation buffer比较 Accumulation buffer > Require “n” passes for all geometry > # of passes is practically unbounded T-buffer > Require 1 pass for all static geometry > # of samples depends on implementation limits > Multiple rendering for moving objects # Could be 2-4 for slow moving objects # More for fast moving objects
T-buffer 和 Accumulation buffer的优点 T-buffer 和 Accumulation buffer与FSAA(全屏幕反走样)相比的共同优点:在一个象素单元内,采样模板不一定是均匀的。 每个Pass与其它Pass无关,因而可采用均匀模板外其它的模板,如(0,0.25), (0.5,0.0), (0.75, 0.5), (0.25,0.75)。 上述模板称为旋转网格超采样(Rotated Grid Super-Sampling, 简称 RGSS),这种模板对于接近水平或垂直的直线能提供更好的反走样效果,而这也是应用中最需要的。
RGSS 各种象素采样模板
A-buffer Multisampling:在单个pass中对每个象素采样多次的方法。 A-Buffer是一种Multisampling方法,由Carpenter提出。通常用于在软件中生成高质量的绘制结果,但不能实时生成。它的主要思想是计算覆盖象素网格单元的多边形逼近。 是一种边反走样方法,可以绘制透明物体。
在硬件A-buffer中,为了节省计算量,象素网格单元对应的多边形光亮度值只计算一次,所有象素网格单元内的采样点共享该光亮度值。因此,基本的A-buffer算法不能处理纹理和阴影的反走样。 在A-buffer中,对于每个屏幕网格单元,每个绘制的多边形生成一个Coverage Mask(完全或部分覆盖象素单元)
0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 多边形的角 部分覆盖象素网格单元,网格单元细分为4X4的子网格。覆盖的子网格单元为1,其余为0。16位的mask为:0000 0111 1111 0111
NVIDIA的Quincunx方法 一般的反走样方法一个采样点只影响一个象素, NVIDIA的Quincunx方法单个采样点影响的象素多于一个。 1/2 1/8 由于共享,每个象素平均只需2个采样点,但是效果却比2个采样点的全屏幕反走样好不少。
随机采样(stochastic sampling) 由于场景中可能包含在屏幕上投影非常小的物体,因此规整的采样模板总会存在某种形式的走样。 解决方案:把采样点在象素内随机分布,每个象素有不同的采样模板。这种方法称为随机采样。 随机采样原理:用噪声取代重复性的走样现象,人的视觉系统更能接收。
Jittering(抖动) 最常用的随机采样方法为Jittering,这是一种分层采样(stratified sampling). 原理: 假设每个象素需要n个采样点,我们把象素区域分成n个面积相同的区域,把每个采样点随机地置于其中的一个区域。象素的最终颜色取为采样点的加权平均。
每个象素划分成3X3的子单元,每个采样点在子单元内随机出现 一个典型的Jittering模板 每个象素划分成3X3的子单元,每个采样点在子单元内随机出现
交替采样(Interleaved Sampling) 采用交替随机采样可以把由于每个象素采用相同模板引起的走样缺陷最小化。 可见重复模板走样现象 采用累积缓存反走样,每个象素采样四个点 每个象素的采样模板不相同,模板交替。效果好!
透明、Alpha和合成 在实时绘制中,透明效果的处理通常是简单化和有限的。 如下效果通常没有:折射、透明物体厚度引起的光的衰减等 有一些透明效果总比一点透明效果都没有好! 通过把表面颜色与其后面物体的颜色相混合,实时绘制系统确实提供了绘制半透明表面的能力。
Alpha Blending 为了把透明物体的颜色与其后面物体的颜色相混合,需要Alpha Blending 当物体绘制到屏幕上时,除了RGB颜色值、Z深度外,还可以有一个α可选项(RGBA或者RGB α)。 α值用来描述物体在给定象素的不透明度,1.0表示不透明(完全覆盖); 0.0表示完全不被隐藏;
为了使一个物体看起来透明,我们把它绘制到已有场景的上面,其α值小于1.0; Blending通过over操作来实现: 很显然,当α=1,即物体不透明时,该象素的颜色变为当前物体的颜色.
为了绘制透明物体, 场景通常需要排序。首先绘制不透明物体,然后把不透明物体以Back to Front的次序与其进行混合。由于混合操作是与次序有关的,以任意次序绘制会导致不正确的结果。 以任意次序绘制透明物体,结果不正确 以后向前的次序绘制,结果正确
例:透明的直升飞机 以任意次序绘制透明物体,结果不正确 从后向前的次序绘制(采用depth-peeling技术),结果正确
当无法进行场景排序时,最好用Z缓存进行排序测试。但绘制透明物体时,其Z值不更新。这样在绘制结果中,至少所有的透明物体都会出现。 不需要排序的方法: 采用该方程,由于透明物体的Alpha值不影响目标物体,绘制次序可以任意。但结果看起来不自然。
合成(Compositing) over操作在真实场景和虚拟场景的混合中非常有用。这个过程称为合成(Compositing)。 在合成中,每个象素除了RGB值外,还有Alpha值。 Alpha通道有时也称遮罩(matte),它显示了物体的轮廓形状。
存贮RGBA图像的最常用方法为预乘Alpha(pre multiplied alphas)。在该方法中,RGB值在存贮之前,先乘上Alpha值。此时over操作变得更有效:
Chroma-Keying(色键) 与Alpha通道相关的另一个概念为色键技术。 演员在篮色、黄色或绿色屏幕前拍摄,然后与背景混合。其原理为把该颜色当成透明色。 在电影工业中,该过程称为Blue Screen Matting.
Fog(雾) 在实时图形学中,雾是一种可加到最终图像的大气现象。 无雾效果 有雾效果
采用雾效果的目的 增强室外场景的真实感 由于雾的效果随着离视点距离的增加而真强,因此它有助于帮助观察者判断物体的远近。 有助于提供光滑的通过远平面实现的物体剔除。如果把雾的效果设置成在接近远平面的地方由于浓雾而不可见,则在远平面外的物体看起来可自然隐退。如果没有雾的效果,远平面外的物体会突然出现或消失。 雾的效果可用硬件实现,不会或带来很少的额外计算量。
雾效果的计算方程 假设雾的颜色(由用户指定)为cf,雾因子(fog factor)为f,待绘制物体的颜色为cs ,则象素的最终颜色cp为: 在上述方程中,f 的值不是很直观,它随离视点的距离而递减。这是OpenGL和DirectX采用的方程,其好处是可使计算f的方程变得简单。 另一种描述方式为f’ = 1- f
指数雾(Exponential Fog): 平方指数雾(Squared Exponential Fog): 其中df为控制雾浓度的参数。计算得到 f 以后,把结果截取(clamp)到[0,1]
雾因子衰减曲线
查找表在计算雾因子中的应用 在硬件加速中,有时采用查找表来实现雾函数。 对于给定的一些深度值,先计算并存贮好其雾因子的值。对于任一深度值,雾因子从查找表直接读取(或为最接近两个值的线性插值)。 查找表中可以存贮任意值(而不仅仅是上面的线性或指数函数),从而生成一些特殊效果。
雾既可以在顶点层也可以在象素层计算。 顶点层:雾的效果在光照明方程计算,其它地方用Gouraud Shading插值。 象素层:用每个象素对应的深度值计算。 象素层计算的效果比顶点层要好!
雾效果中深度值的选取 在传统的软件绘制流水线和大部分图形加速卡中,z值是非线性计算的。 若直接采用该深度值计算雾因子,计算的结果并不符合我们的预想。因此有些图形卡支持eye-relative depth来正确计算深度。为了使深度线性变化,把透视变换的效果撤销。
视点旋转后,物体2从没雾状态进入有雾状态! z-depth vs. Radial fog View-axis-based fog Radial fog 视点旋转后,物体2从没雾状态进入有雾状态! 视点旋转后,结果仍然正确
质量最高的雾效果: pixel-level radial fog
Gamma 校正 当一个象素的值计算好后,我们需要把它显示在监视器上。 CRT中电子枪的输入电压与输出光亮度的关系 其中V为输入电压,a和γ(Gamma)为与显示器相关的常数,ε为显示器设置的black level (brightness), I为生成的亮度。 Gamma值的范围为 [2.3,2.6]。 输入电压与输出光亮度之间不是线性关系!需要校正
电压与亮度的关系(已归一化) 所需的Gamma校正曲线 两曲线相乘得到正确的线性关系
实时图形学中Gamma 校正重要的原因 跨平台兼容(SGI,Macintosh,PC) 颜色的真实性、一致性和插值 Dithering(抖动) 线和边的反走样质量 Alpha混合和合成 纹理贴图
左图为真实的面积覆盖,如果没有Gamma校正,边看起来像右图。 黑背景,四个象素被一个白多边形的边覆盖 左图为真实的面积覆盖,如果没有Gamma校正,边看起来像右图。
Gamma校正的反走样直线 部分Gamma校正的反走样直线 没有Gamma校正的反走样直线