CPT205 计算机图形 笔记
函数查阅:windows 开发文档
week1
介绍课程
什么是computer graphics:
‘Computer Graphics’ is concerned with all aspects of producing pictures or images using a computer. There are three closely related meanings, each representing a different perspective on the same thing.
- the images that you see on the computer screen
- the computer code that is used to create the images
- a mathematical model of the real-world (which is sometimes
called the virtual world)
什么是framebuffer:
A block of memory, dedicated to graphics output, that holds the contents of what will be displayed.
什么是pixel:
an element of the framebuffer.
The most basic addressable image element in a screen
什么是bit depth :
number of bits allocated per pixel in a buffer.
计算机图形学的硬件软件:
Graphics Hardware | Graphics Software |
---|---|
Input, Processing and Output Devices | T echniques (Algorithms, Procedures) |
Framebuffers | Programming Library / API (OpenGL, JOGL and so on) |
Pixels and Screen Resolution | High level Interactive Systems (Maya, Studio Max, Unity, AutoCAD and so on) |
Image quality issues:
• Screen resolution • Colour • Refresh rate • Brightness • Contrast • Sensitivity of display to viewing • angle
什么是opengl:
The OpenGL graphics system is a software interface to graphics hardware (GL stands for Graphics Library).
OpenGL is designed as a streamlined, hardware-independent interface to be implemented on many different hardware platforms.
week2
数学几何基本概念
week3
计算机绘制图像时的坐标轴只能是整数,所以要尽量拟合实际的线条
Digital Differential Algorithm
- 当斜线斜率小于一时,沿着x轴进行逐像素采样
- 当斜线斜率大于一时,沿着y轴逐像素采样,防止线条断开
The Bresenham line algorithm 布雷森汉姆直线算法
优点之一是可以使用整数型计算,而不是DDA方法使用的浮点类型
贴个代码实现的帖子
Bresenham算法
画圆
方法一:简单通过勾股计算描点,但这个是沿着x轴采样,在圆的左右两侧会出现断层。
解决方法是在切线斜率大于1的地方,再计算一遍沿着y轴采样的坐标。
方法二:采用极坐标画圆
原理:先用极坐标公式对圆进行大致描点(逐角度描点,一般步长设置为1/r),然后调用直线绘制两两点之间的直线去近似表现圆
tips:由于圆的对称Symmetry,通常计算四分之一或八分之一个圆的坐标即可
Antialiasing by area averaging抗锯齿
根据线条覆盖空间为每个像素设置不同权重的颜色填充
Polygon fill 填充多边形图案
详阅:区域填充算法和多边形填充
rasterization光栅化
方法一,洪水填充算法:
1)在内部选择一像素点
2)递归地访问并填充这个像素点周围的点,不访问边界像素
方法二,扫描线填充算法:
用水平或垂直的扫描线对多边形进行扫描,对于每次扫描
1)求扫描线与多边形的交点
2)筛选落在多边形内部的那些线段
3)填充落在多边形内部的线段
week4 利用矩阵及gl函数变化对象
这里引用OpenGL学习专栏里的一段话解释openGL里的变换:
我们生活在一个三维的世界——如果要观察一个物体,我们可以:
1、移动或者旋转它,当然了,如果它只是计算机里面的物体,我们还可以放大或缩小它。(模型变换Modelling Transformation)
2、从不同的位置去观察它。(视图变换Viewing Transformation)
3、如果把物体画下来,我们可以选择:是否需要一种“近大远小”的透视效果。另外,我们可能只希望看到物体的一部分,而不是全部(剪裁)。(投影变换Projection Transformation)
4、我们可能希望把整个看到的图形画下来,但它只占据纸张的一部分,而不是全部。(视口变换Viewport Transformation)
这些,都可以在OpenGL中实现.
5, 计算机图形需要表现在二维的电脑屏幕上(Device Transformation)
矩阵变换Transformations
三维变换是二维变换的扩展,这里只展示三维的矩阵变换
-
Rotation旋转:
旋转可以分步骤进行,但是当顺序发生变化时,旋转的角度需要改变
关于(x,y)旋转到(x’,y’)的推导
-
Translation平移:
改变常数项
如x向正方向移动5,tx=5
-
Scaling放缩:
改变比例项大小
如修改长宽高为原来的0.8,将三个1全改为0.8
-
Reflection翻转:
改变比例项为负值,如按照x-y平面反转,将z的比例项改为-1.
5. shearing倾斜:
物体沿着x轴倾斜
Tips:
回顾上面矩阵相乘图
- 物体平移只体现在常数项tx,ty,tz上,比例项变化不影响常数项,旋转不影响全局坐标下的平移
- 物体旋转时以物体自身原点为旋转中心,如果想相对一个固定点(x,y,x)旋转。
可先将物体移动(-x,-y,-z),然后相对物体原点旋转,然后再把物体移动(x,y,z)回到原来位置,平移影响旋转结果 - 当物体放缩时也以原点为中心,每个点相对于原点的距离都会变化,不影响平移。
- 变化矩阵Current transformation matrix(CTM) 采用栈的方式存储(先入后出,后入先出)
gl函数模型变换
函数:
//设置当前操作矩阵为模型视图矩阵
glMatrixMode(GL_MODELVIEW);
//设置当前矩阵为单位矩阵
glLoadIdentity();
//将栈顶矩阵设置为m
glLoadMatrixf(m);
//将栈顶矩阵右乘以m
glMultMatrixf(m);
//将当前操作矩阵入栈
glPushMatrix();
//从栈中出栈矩阵
glPopMatrix();
//以浮点数形式取出栈顶矩阵,存储为m
double m[16];
glGetFloatv(GL_MODELVIEW, m);
其他函数:
旋转样例:
Rotation about the z axis by 30 degrees with a fixed point of (1.0, 2.0, 3.0)
//模型视图变换
glMatrixMode(GL_MODELVIEW);
glPushMatrix(); //将当前矩阵的副本压入栈
glTranslatef(1.0, 2.0, 3.0); //操作栈顶矩阵
glRotatef(30.0, 0.0, 0.0, 1.0);
glTranslatef(-1.0, -2.0, -3.0);
//画图
drawsth();
glPopMatrix(); //移除栈顶矩阵,回到之前状态
由于gl采用栈和矩阵右乘存储变换矩阵,所以当程序执行画图并变换时,
依次执行的是
先移动(-1,-2,-3),旋转30度,移动(1,2,3)
详细可看链接
week5 Viewing and Projection
视图三要素:
- 一个或多个被观察物体 One or more objects
- 一个含有投影平面的观察者 A viewer with a projection surface
- 从被观察物体到投影平面的投影方式 Projectors that go from the object(s) to the projection surface
Classic projection
平面几何投影 planar geometric projections
- 平行投影 parallel
- 多视图正交 (multiview) orthographic
- 三向投影 axonometric
- 等角投影 isometric
- 正方投影 dimetric
- 三度投影 trimetric
- 斜轴投影 oblique
- 透视投影 perspective
- 一点透视
- 两点透视
- 三点透视
Computer viewing and projection
只为完成三件事:
- Positioning the camera放摄像机
-Setting the model-view matrix - Selecting a lens设置投影矩阵
-Setting the projection matrix - Clipping裁切视平面
-Setting the view volume
步骤:
- 在世界坐标系中设立摄像机的坐标 (view port, viewing position , camera position or viewiing origini )
- 控制摄像机瞄准的方向,垂直于这个方向的平面叫做视平面(viewing plane),再设定视野和深度裁切视平面后组成一个视景体(viewing volume)
- 将视景体观察到的图像映射到显示屏窗口上
从物体上的参考点(look-at point)指向摄像机的向量叫做(viewing direction)
接下来根据openGL函数来分析不同视景体:
opengl默认的坐标系是,水平方向向右为x轴正向,竖直向上为y轴正向,由屏幕指向外面为z轴正向。
参考
1.决定摄像机坐标
函数:gluLookAt(eye_x, eye_y, eye_z, look_x, look_y, look_z, up_x, up_y, up_z)
- eye_x,yz: 决定摄像机自身所在世界坐标系中的位置
- look_x,y,x: 决定摄像机镜头超向方向上的物体的世界坐标系位置
摄像机位置和朝向确定后会以摄像机自己为原点,生成摄像机坐标系,摄像机坐标系的z轴是由物体指向摄像机,摄像机坐标系的y轴指向世界坐标系的z轴。
Tips: 摄像机越过物体头顶时,摄像机坐标系的z轴反向,物体的右变成了摄像机视野里的左。 - up_x,y,z: 决定视景体在摄像机坐标系下的头顶方向,决定了画面的正上方是什么方向,如(0,0,1)表示摄像机坐标系的z轴朝上
2.视景体 View Volume / View Frustum
摄像机架好之后开始搭建视景体,视景体决定了相机看物体的方法(有没有透视,看多大的画面,看多深的深度)
2.1.平行视景体 Orthogonal / Parallel projection
函数: glOrtho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far)
各个参数决定相机能看多宽,多高,多远。视景体是个长方体
- left, right 指定视景体左右看多少距离
- bottim, top 指定视景体上下看多少距离
- near, far指定视景体近远看多少距离
这样会生成一个长发体,在这个长方体之外的物体不会被看见。
2.2.透视型视景体 Frustum perspective projection
各个参数决定相机看多宽,多高,多远。视景体是个平截头体
以下两个函数通过长度和角度两种方式定义平截头体
平截头体内的物体根据映射关系,被投影到近截平面上,在这个平截头体之外的物体不会被看见。
函数: glFrustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far)
- left, right, bottim, top 指定近截平面的宽度,高度
- near, far指定近截平面和远截平面到视点的距离
函数:gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
- fovy指定眼睛睁开的角度
- aspect指定视景体的宽高比
- zNear, zFar指定近截面和远截面到相机距离
摄像机坐标=视点=view point=view origiin=projection reference point
显示器区域=视口=viewport
3.将计算机视图投影到显示器上
近截平面Near Clipping Plane的像素与显示器窗口的像素数量不同
将裁剪平面映射到显示器窗口的某个区域(全屏或部分屏幕)该区域被称为视口viewport
函数:glViewport(GLint x,GLint y,GLsizei width,GLsizei height)
- x,y指定显示器窗口中视口的左下角坐标
- width,height指定视口的宽高
Tips:openGL中,切换矩阵类型后,先指定视景体,最后指定摄像机坐标。(因为openGL矩阵是右乘的,A x B x C=A x (B x C),计算过程是和添加过程反过来的。得到摄像机坐标后才能确定视景体在世界坐标的位置然后看东西)
glMatrixMode(GL_PROJECTION); //projection transformation
glLoadIdentity(); // clear the matrix
glOrtho / glFrustum / gluPerspective(); //视景体
gluLookAt(x_p, 0, z_p, 0, 0, 0, 0, 1, 0); //摄像机
week6 Parametric Curves and Surfaces
参数化曲线
为什么需要参数曲线:形容更贴切,两个变量比隐函数(implicit function)易于表现
参数化直线,三次曲线 cubic curve,圆:
A curve description should be used, which allows rapid computation, a polynomial can therefore be used
使用多项式描述曲线 -polynomial:
x(t) = a0 + a1t + a2t2 + a3t3, + … + antn
如果描述k个点,只需要n=k-1个参数a:
- k=2,表示直线(straight line
- k=3,表示抛物线(parabola
- k很大时,参数需要很多,高次多项式在直线末端剧烈振荡,不适用
high-degree polynomials (i.e. with a large n) oscillate wildly, particularly near the ends of the line, and are not suitable
对于需要描述许多点的情况,使用样条splines
使用样条描述曲线 -splines:
将点分成许多独立的部分(通常最少四个控制点),每部分使用低次多项式拟合,再平滑地拼接到一起
要求:
- continuity of the curve 曲线连续-无中断
- continuity of tangent 斜率连续-无明显角
- continuity of curvature 曲率连续-避免光影缺陷
分类:
- 插值曲线 interpolation curve-曲线必须经过数据点(data point),曲线由数据点控制(或者说控制点=数据点)
- 设计曲线 design curve-曲线表现数据点所呈现的大体趋势,曲线由控制点(control point)直接控制
local control局部控制:设计曲线在完成一部分曲线后,在调整其他部分时,应当保持这一部分不动,the adjustment should influence only a small / local part of the curve。
{Natural splines,Bezier curves}不需要局部控制,{B-Splines,NURBS}需要局部控制。
调整曲线
除了移动控制点的位置控制曲线,还可以固定控制点并改变其他参数控制曲线,如张力和偏差(tension and bias)
参数化曲面
种类:
- Revolved surface旋转曲面 - 二维曲线绕轴旋转
- Extruded surface挤压曲面 - 二维曲线垂直自身平面移动
- Swept surface扫描曲面 - 根据二维曲线,定义三维空间中的扫描方式
Tensor product surfaces张量积曲面
组合两条参数曲线
分类:
- 插值曲面 interpolation surfaces
- 设计曲面 design surfaces
由控制点的矩形阵列组合成控制网格(control grid),曲面将会被分解为曲面片(surface patches),通常最少片包含4 x 4=16个控制点,曲面片越多越曲面越精细。将曲面片拼接时需要考虑拼合处的连续性
曲面和曲线一样可以考移动点和控制张力等参数控制曲线
week8 3D Modelling
3D modelling techniques
• Wireframe
• Surface
• Solid
Wireframe线框图
模型被认为是由复数的点与线的集合构成的
曲面表达(参数表示Parametric representation):
x = x(t), y = y(t), z = z(t)
曲面表达(隐式表示Implicit representation):
s1(x,y,z) = 0, s2(x,y,z) = 0
由面的组合可以表示3d物体
缺点: 模型的模糊性和验证模型困难性,此外,没法提供表面和体积信息
the ambiguity of the model and the severe difficulty in validating the model, does not provide surface and volume-
related information
Surface modelling
由封闭环绕的曲线表示2d或3d的面
除了缺少与体积相关的信息外,曲面模型通常定义其相应对象的“几何属性geometric properties”。
Solid modelling
可以同时表现几何属性和物理属性
geometric properties | physical properties |
---|---|
points, curves, surfaces, volume, centre of shape | mass, centre of gravity and inertia |
有好多种方案,主要是CSG,B-Rep
CSG
由二叉树的形式表达:
the non-terminal nodes : the operators 非叶子节点是操作符
the terminal nodes : the primitives or transformation 叶子节点代表物体原语或变换
操作符包含:rigid motions(刚体运动,旋转等) and regular Boolean operations(正则布尔运算,取相交等)
正则布尔运算包含:并,减,交
如果物体只能被一个特定的数据集表示,则称这种表达是唯一的
实体物体的表示通常是明确的,但很少有唯一的。
CSG没法只用唯一集表达一个物体。
Boundary representation 边界表示(B-Rep)
B-Rep模型通过将实体的边界分割为有限个有界子集来表示实体。
它基本上是一种拓扑显式表示。几何和拓扑信息都存储在数据结构中。
几何图形关于边界图元(点、曲线和曲面 )的形状和大小
而拓扑topology保持了边界图元的连接性。
同一拓扑可能会表示不同的几何图形,所以需要拓扑和几何数据一起确定唯一的物体。
B-Rep可以被分为以下两种:
- manifold流形:一条边连结两个面,一个点至少被三个边交
- nonmanifold非流形:可能会有悬垂图元(dangling faces, edges and vertices), 可表现不真实物体
欧拉定理
V | E | F | R | H | S |
---|---|---|---|---|---|
vertices | edges | faces | rings (inner loops on faces) | passages/holes(genus) | shells(disjoint bodies) |
对于任意流形:
V - E + F - R + 2H = 2S
V - E + F = 2
圆柱体套用欧拉公式:
B-Rep的实现:
将拓扑表示为指针,图形表示为存储信息,即可在编程语言中实现
Baugmart’s winged edge data structure:
The edge has pointers to the vertices at its ends, and to the next edges.
The vertices have pointers to their coordinates (x, y, z)
Euler-operators欧拉算子:
These modify the face-edge-vertex pointer structure in such a way that the Euler formula is always kept true.
是一些数据操作,可以生成面,改变物体几何,使得欧拉公式保持为真
Lab:
什么是深度测试:
深度缓冲区(DepthBuffer)和颜色缓冲区(ColorBuffer)是对应的,颜色缓冲区是存储像素的颜色信息,而深度缓冲区存储像素的深度信息。在确定是否绘制一个物体表面的时候,首先要将表面对应的像素深度值与当前深度缓冲区中的值进行比较,如果大于深度缓冲区的值,则丢弃这部分。否则利用这个像素对应的深度值和颜色值分别更新深度缓冲区和颜色缓冲区,这个过程称为深度测试。
函数说明:
- void glEnable(GL_DEPTH_TEST):
- 用来开启更新深度缓冲区的功能,也就是,如果通过比较后深度值发生变化了,会进行更新深度缓冲区的操作。启动它,OpenGL就可以跟踪再Z轴上的像素,这样,它只会再那个像素前方没有东西时,才会绘画这个像素。
- void glColorMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha);
glColorMask指定是否可以写入帧缓冲区中的各个颜色分量。 例如,如果红色为GL_FALSE,则无论是否尝试绘制操作,都不会对任何颜色缓冲区中任何像素的红色分量进行任何更改。 - void glCullFace(GLenum mode); mode 指定应剔除多边形的哪一个面,不是GL_FRONT就是GL_BACK。
本函数可以禁用多边形正面或背面上的光照、阴影和颜色计算及操作,消除不必要的渲染计算是因为无论对象如何进行旋转或变换,都不会看到多边形的背面。用GL_CULL_FACE参数调用glEnable()和glDisable()可以启用或禁用剔除。 - void glDepthMask(GLboolean flag);
指定是否可以写入启用深度缓冲区。 如果flag为GL_FALSE,则禁用深度缓冲区写入。 否则,它可以启用。 初始状态为启用深度缓冲区写入。 - glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 0, 0);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
week9 线性模型和层次化模型
Local and world frames of reference局部和世界参照系:
现实世界中没有原点,所有原点都是设出来的局部原点local origin:
Local basis,Local transformation,Local/model frame of reference等操作都是相对于正在被处理的大世界的的局部原点而言。
什么是local frame(局部框架):通过旋转由局部原点定义的局部框架,可以旋转所有基于此的世界
什么是relative motion(相对运动):相对于局部原点的运动,(同时局部原点可能相对于更大的参考系而运动)
Linear modelling
从symbol(prototype)开始,作为一个实例instance,通过缩放定向和定位( scale, orient and position)来定义变换,以实现实例转变(instance transformation)
什么是symbol:例如盒子,球体,茶壶,三棱锥等
Copy和Instance的区别:copy创建一个与原型互不影响的克隆体,instance创建一个可影响原型的实例化对象。
代码实现:
Set up appropriate transformations from the model frame (frame of symbols) to the world frame
模型的存储:
存储在一张表中,以给每个Symbol标号,并记录相对局部原点缩放旋转平移操作,表内不记录物体的实际结构
缺点:
当遇到一个复杂的由多个部分组成的物体,没法确定部件之间的相对关系(因为该表每个标号代表的物件之间是毫不相关的)
Hierarchical models
考虑物件之间的相对关系后,易于讨论物件的摆放
对象被分组到一个层次化的树结构中 —》 **Direct Acyclic Graph (DAG)**有向无环图
Articulated model铰接模型是层次化模型的一种应用,选取中心点作为根,各个可移动部件作为节点。限制各个零部件之间的自由移动角度(degrees of freedom (DOFs) )以约束模型姿态
层次变换Hierarchical transformations :
树中的每个节点代表所有在这个节点之下的节点的局部世界,对父节点进行变换,会影响其所有子节点。
每个节点存储一个局部变换矩阵,维护相对于其父节点的变换。
为了计算某一节点的世界空间矩阵,需要根据根节点至该节点的路径上的局部变换矩阵进行推导
使用深度优先遍历计算所有节点的世界空间矩阵,进入子树时glPushMatrix(),退出时glPopMatrix()
一些例子:
例子A:列举了一个机械操作臂的例子
- 机械臂和底座是绑定的
- 机械臂可以在基座上滑动平移
- 机械手和底座/机械臂是绑定的
- 此外机械手可以以机械臂为支撑点滑动平移。
基于此,实现的opengl绘图函数
因为东西太少,是度为1的树所以不必push和pop matrix
树结构在实现中,每个节点需要存储{指向该节点模型的绘图函数,对于父节点的变换矩阵,指向子节点的指针}
例子B:举了一个机器人的例子,通过深度优先遍历每个部分,使用矩阵栈存储矩阵队列,采用出入栈代替一系列矩阵乘逆操作
week10
光影和材质(MC党狂喜
Lighting sources
- Point light 点光源:
点光源的光线从光源位置向周围发散产生 - Directional light 平行光:
也被称作定向光或无限距离光(directional light/ infinitely distant light),可理解为超远距离的点光源,光线从光源位置向物体近乎平行产生 - Spot lights 射灯:
只会照射一定角度范围的灯,光线从光源位置在一定张角范围内产生(directional limits)。
surface lighting effects
表面照明效果surface lighting effects:光经过物体的反射,会产生方向,颜色上的变化。
The effect is a general background non-directed illumination. Each object is displayed using an intensity intrinsic to it, i.e. a world of non-reflective, self-luminous object.
Consequently each object appears as a monochromatic silhouette, unless its constituent parts are given different shades when the object is created.
一般来说,光线在物体表面没有反射,物体自身向摄像机发射光线
- Ambient light 环境光:
环境光分量(ambient component)指光经过环境中的各种表面反射,最终摄入摄像机的部分
The light has been scattered so much by the environment that it is impossible to determine its direction - it seems to come from all directions.环境光的光线过于分散以至于没法区分方向,看起来来自四面八方
户外的spot light的环境光分量十分少,大部分光线反射到远处而不是摄像机里。 - Diffuse reflectance 漫反射:
光线由点光源向所有方向散射,根据材料漫反射系数,角度,光强度进行漫反射。 - Specular reflectance 镜面反射:
摄像机处在反射出角路径上时,镜面反射强度达到最大值。如果是完美镜面,则只有在该路径上才能看到反射光
Attenuation 光的衰减:
平行光应当无衰减,点光源和位置光源应当按照距离进行衰减光强
什么是Lighting model 照明模型:
用于计算对象表面上某个位置的颜色,使用指定曲面的各种光学特性(例如透明度、颜色反射系数和纹理参数)计算曲面的照明效果。
对于曲面,可以高精度采样或低精度采样然后插值。
曲面渲染方法(surface rendering method)使用来自照明模型的颜色计算来确定场景中所有投影位置的像素颜色。
Phong model:
是一个简化,计算快捷的照明模型,维护以下系数:
表示物体:
漫反射Diffuse Lighting,镜面反射Specular Lighting,环境光Ambient Lighting。
光源,摄像机,面法线,完美反射系数
表示点光源:
Idr, Idg, Idb, Isr, Isg, Isb, Iar, Iag, Iab
表示材料特性:
- 9 absorption coefficients:
kdr, kdg, kdb, ksr, ksg, ksb, kar, kag, kab - Shininess coefficient α
计算三种光源到材质的结果:
I = kd Id l · n + ks Is (v · r )α + ka Ia
对于每个材质的采样点,叠加所有光源到该店的计算结果
OpenGL中光照可设置的种类
OpenGL中物体材质种类设置
Polygonal Shading多边形着色
又分为 顶点着色(Flat (constant) shading),平滑着色(Smooth (interpolative) shading),高洛德着色(Gouraud shading)
他们的区别可以看这:各种着色
材质 Material
控制三个量:环境光,漫反射,镜面反射
颜色通常由环境光,漫反射控制
表面的高光通常由镜面反射控制
光源和材质间的RGB
if a light has components (RL, GL, BL), and a material has corresponding components (RM, GM, BM); then, ignoring all other reflectivity effects, the light that arrives at the eye is given by (RLRM, GLGM, BL*BM).
Similarly, if two lights, (R1, G1, B1) and (R2, G2, B2) are sent to the eye, these components are added up, giving (R1+R2, G1+G2, B1+B2). 大于1的算作1
week11 Texure Mapping
什么是纹理贴图,纹理投影:
The method for incorporating object detail into a scene is called texture mapping or pattern mapping.
有时候需要将一个矩形纹理映射到非矩形区域中,投影在屏幕上的纹理也会因为各种变换而扭曲。
纹理贴图的种类:
- 纹理贴图 Texture Mapping 关于物体本身看起来外观
- 环境贴图 Environment Mapping 关于物体所处环境
- 凹凸贴图 Bump Mapping 关于物体本身的表面法向量
纹理类型:
- 图像image:2d图像
- 程序procedural:程序生成纹理
纹理中包含:
四个RGBA分量,三个RGB分量,阴影的强度值,对颜色表的索引,或单个亮度值
纹理数组中的单个值被称为texel
Magnification and minification放大和缩小:
放大:一个texel映射到多个pixel
缩小:一个pixel被多个texel覆盖
边界的越界需要对齐进行平均以拟合真实效果。
什么时候纹理映射:
在rendering pipeline渲染管道的末尾。减少通过裁切的多边形,比较高效
投影中涉及到的坐标系:
- Parametric co-ordinates
may be used to model curves and surfaces 识别建模曲面 - Texture co-ordinates
used to identify points in the image to be mapped 识别被映射的贴图的点 - Object or world co-ordinates
conceptually, where the mapping takes place 计算机世界中映射发生的位置 - Window co-ordinates
where the final image is finally produced 图像窗口中最终图像的坐标
材质投影的方法:
一般会想材质投影是建立三个各个维度上从二维贴图到三维曲面的映射函数,但这样很难找到一个完美的函数如x=x(s,t)来拟合。不妨反向投影backward mapping,渲染三维曲面时去找二维贴图上的点,s=s(x,y,z),不过这个函数也很难找。
- Cylindrical mapping
先将材质投影到一个简单的中间面上(simple intermediate surface),构造投影方程:
- Spherical mapping,用于环境投影
- Box mapping,适用于二维投影和环境投影
Second mapping 二次投影
从中间物体投影到真实物体
采样方式:
-
Aliaseing混叠:
纹理的点采样可能会导致锯齿。
-
Area averaging面积采样:
可减少锯齿,但是会慢一点。把一个面积的纹理投影到曲面上,
opengl使用纹理
opengl纹理和几何渲染是分开的,最后在fragment processor处合并
三个步骤:
- Specify the texture
• read or generate image
• assign to texture
• enable texturing - Assign texture coordinates to vertices
Proper mapping function is left to application - Specify texture parameters
• mode
• filtering
• wrapping
Texture co-ordinate
纹理坐标的值通常在0到1之间,使用s, t, r, q表示
Texture wrapping:我们可以指定范围 [0,1] 之外的纹理坐标,并让它们在纹理贴图中clamp或repeat。
Mipmapping
在不同距离观察纹理,如果纹理大小不变的话会产生鬼影artefact
因此为,纹理贴图提前生成不同大小的pre-filtered图像,根据渲染时的距离选择不同的纹理进行映射
week12 Clipping
Clipping 裁切– Remove objects or parts of objects that are outside the clipping window.
Rasterization光栅化 (scan conversion) – Convert high level object descriptions to pixel colours in the framebuffer.
为什么需要裁切:
光栅化耗费资源,创建的碎片越多,耗费资源越多。如果只光栅化实际可查看的内容,可以节省计算。
Rasterization meta algorithms - 光栅化时剔除不可见面 (下一章内容)
讨论不透明物体的渲染:
- 对于每个显示器上的像素,确定投影到像素上的哪个对象最靠近摄影机,然后计算该像素的着色。
- 对于每个对象,确定它覆盖哪些像素并对这些像素进行着色–需要跟踪对象深度
裁剪窗口Clipping window与视口viewport的区别:
裁剪窗口选择渲染空间中的显示范围,视口指示显示器窗口内查看图像的位置。
2D point clipping
考虑点与裁切区域的包含与否
2D line clipping
可以先考虑两个是否都在裁切区域内,如果有一个点不在或都不在,就应该考虑线中间某部分在裁切区域内–计算与裁切区域的两个交点
爆算,联立方程得解,需要多个变量,要4步:
Cohen-Sutherland 2D line clipping:比爆算好
为每个端点创建一个输出代码,其中包含该点相对于剪裁窗口的位置信息,使用两个端点的out codes来确定线相对于剪裁窗口的配置,如有必要,计算新的端点。
分情况讨论:
- 两个端点都在裁切区域内-直接画
- 两个端点都在裁切区域外且在同一侧–忽略这些裁切区域外的点
- 一个在外,一个在内
需要计算一个交点 - 两个都在外(线的部分可能在内)
需要计算一个交点
算法中的out code的定义:
将平面切成9个区域,每个区域有自己的out code,【<x】【>x】【<y】【>y】
考虑五种情况:
- AB,outcode(A)=outcode(B)=0000 接受全部线段
- CD, outcode © = 0000, outcode(D) ≠ 0000
计算交点,outcode中1的位置决定与哪条边相交,如果D点中有两个1,则需要计算两次交 - EF, outcode(E) AND cotcode(F) ≠ 0. 拒绝线段
- GH and IJ,这两种情况的out code相同,不全是0,取和结果也是0. 需要计算交点的outcode,重新执行算法
算法还可以用于三维裁切,这种情况需要6bit状态码。
Liang-Barsky (Parametric line formulation)
如果有线的向量形式表现,可以求解两个方向上的交点的先后顺序考虑截断或拒绝线段。
p(α) = (1-α)p1+ αp2, 0≤α≤1
or two scale expressions
x(α) = (1-α)x1+ αx2
y(α) = (1-α)y1+ αy2
Plane-line intersections
p(α) = (1-α)p1+ αp2, 0≤α≤1
n⋅(p(α) – p0) = 0
Normalised form归一化
是预裁剪的一部分,不过归一化后,将对右平行六面体裁切
多面体裁切
对于多面体的裁切,有两种:
- One strategy is to replace non-convex (concave) polygons with a set of triangular polygons (a tessellation).
- clipping as black box,依次考虑多面体中线的两个端点,判断是否裁剪。
pipieline clipping
可以分别依次考虑窗口顶部裁切,底部裁切,右侧裁切,左侧裁切,每个方向设立一个裁切器
Bounding box
对于复杂的多面形,可以设立一个边界框,来大概判断接受拒绝还是继续讨论
week13 Hidden-surface removal
去除不可见的面与上周讲的裁切相似,都是在渲染管道前期尽可能去掉没用的区域,分为两种方法:Object-space methods and Image-space methods
Object-space methods
检测处在其他对象之前的对象,利于静态场景,较难抉择
Determine which object are in front of others. Resize does not require recalculation; works for static scenes; may be difficult to determine.
在多边形对象之间成对测试,复杂度O(n2)
1.Painter’s algorithm:
通过按照深度值对多边形排序,按从后到前的顺序渲染每个多边形,使位于其他物体之后的多边形只需简单绘制。
首先需要按照深度值排序,复杂度O(nlogn)。
按照各个各个多边形到COP(Centre Of Projection)的距离,对齐排序。
- 一个维度重叠overlap,其他维度不重叠的物体可以被独立绘制
- 多个维度重叠
- 循环重叠cyclic overlap
- 插入penetration
2.Back-face culling
背面剔除把多边形的位置和方向与观察方向v进行比较,消除了背离摄影机的多边形(保留右手定则指向摄像头的多边形)。如果整个多边形朝向面背向于摄像机,则整个多边形面被删除
单个物体检测过程:叉乘多边形上两非平行线,得向量n,n与视角向量v之间夹角如果在-90到90度之间,则称可见。如果对象坐标已经是相对摄像机坐标,则只需接下来比较z轴
多个物体检测过程:对于每个多边形Pi,找到法向量n,视角向量v,如果v·n<0,则消去该多边形
Image-space methods
检测每个像素位置的可见对象,可用于动态场景
Determine which object is visible at each pixel. Resize requires recalculation; Works for dynamic scenes.
对于每个宽m高n像素后的k个多边形,找到距离摄像机最近的多边形所持的像素属性并绘制。复杂度O(nmk)
1.Z-buffer algorithm
设置一个二维数组内存,记录每个像素点的深度信息。深度将以0-1表示,从近裁剪平面到远裁剪平面
最初,z-buffer被初始化为非常远的裁切平面。
随后,对于每个多边形,我们知道其覆盖的像素属性,对于每个像素,计算其z-value深度,与z-buffer上相应的值比较。如果z-value小于已有值,则将这个新的像素属性覆盖现在的帧缓冲区里的像素,同时更新z-buffer这个位置的值。
2.Scan-line algorithm
深度信息的变化公式a∆x + b∆y + c∆z = 0
如果将沿着x轴扫描:
物体在扫描线上没有重合,不需要深度信息。如果有多个物体在扫描线的位置重合,则需要深度信息。减少资源访问。
3.Binary Spatial Partition (BSP) tree
bsp二叉空间分割树,是painter‘s algorithm的底层支持
尽可能减少物体以:
- reduce burden on pipeline
- reduce traffic on bus
使用BSP数据结构,可以基于物体面元也可以基于分割轴
bsp的介绍
过程:
- Choose polygon (arbitrary)
- Split the cell using the plane on which the polygon lies, may chop polygons into two
- Continue until each cell contains only one polygon fragment
- Splitting planes could be chosen in other ways, but there is no efficient optimal algorithm for building BSP trees
通常左侧节点代表包含viewer一侧区域,右侧反之。
不难观察树左下角的节点一定在其右侧节点之前,也就是背对viewer一侧的区域内的物体永远不会覆盖掉正对viewer一侧区域内物体
bsp的使用
空间划分后绘制多面体的顺序(这里分割线成节点了:
At each node (for back to front rendering):
- Recurse down the side of the sub-tree that does not contain the viewpoint
Test viewpoint against the split plane to decide the polygon - Draw the polygon in the splitting plane
Paint over whatever has already been drawn - Recurse down the side of the tree containing the viewpoint