0%

cg-notes

有关图形学的一点点笔记。不过因为为一般会用ipad记,所以这里的就当复习用吧....
不会太详细,毕竟是笔记。

数学

齐次坐标

https://blog.csdn.net/zhuiqiuzhuoyue583/article/details/95228010

变换

视图变换

模型变换 Model

上面提到的几种变换的组合,往世界里摆物体。
local space -> world space

视图变换 View

word space -> view space

这里用的都是右手系,但opengl是左手系。可能实际会有正负号的区别。

描述相机:位置,朝向(lookat/gaze) ,上方向
,且两者均为单位向量。

把相机移到约定俗成的

由于相机和物体的相对位置不变,画面不变,所以实际大概是直接规定相机在这然后移所有物体...

移动包括一个平移一个旋转。有
其中,
对于,先求逆(方便!):
由于这玩意的列向量都是单位向量,还是正交的,所以是正交矩阵,转置一下就是了。

投影变换 Projection

view space -> clip space

把所有可见坐标变换到(-1.0, 1.0)的范围内,然后裁剪掉这部分之外的内容。

正交投影 Orthographic projection

相机离的无限远,可见范围就变成一个立方体了。

规定可见的立方体的坐标l(left), r(right), b(bottom), t(top), f(far), n(near)。根据摄像机up=y, lookat=-z来定义。
然后把这个立方体变成(-1, 1)的标准立方体。

显然先移动再缩放一下就好了。有:

透视投影 Perspective projection

摄像机是某个点,从这里投出一个四棱锥。规定四棱锥平行于底面的两个平面为zNear和zFar,渲染这个Frustum里的东西。


把左边的frustum挤压成立方体,然后使用透视投影的方法。


图是拿notability手画的所以非常丑陋
由图,根据相似三角形,有。同理
所以有:

那一行?要用两个特殊值:zNear平面点不动,zFar平面点的z不变来解。往里一代:

最后

还有确定坐标的问题...。zFar(f)和zNear(n)是已知的,另外两个参数是摄像机的fov(一般是fovY)和宽高比aspect。
那么, 根据对称性,

由于摄像机是固定的,又有一些奇奇怪怪的对称性,所以可以化简下:

线性插值

双线性插值:

为插出5,先插m和n,再用m和n插出5。多维的同理。

重心坐标

对于三角形ABC内的任意点,都可以用表示。其中: - ,若不等于1则不在平面内。 - 。否则在三角形外。

把点和ABC分别连起来,围成三个小三角形。A正对的三角形面积记为,则 同理。(算面积用cross product)

重心坐标插值

三角形内一点

TBN坐标系

一个local的坐标系。三个轴是Tangent, Bitangent和Normal。前两者对应贴图的uv,normal当然是法线。

可以用三角形的两条边的向量算出TB。N则是三角形本身的法向量。

公式和推导过程见https://learnopengl-cn.github.io/05%20Advanced%20Lighting/04%20Normal%20Mapping/

Perlin noise

生成噪声的东西,公式看不懂...总之有。可以和纹理组合起来用。

光照

一些物理定义

https://zhuanlan.zhihu.com/p/389616851

漫反射 Diffuse

用于Lambert物体(粗糙的那种)。
Lambert物体符合Lambert cosine law:就是上面的那一项。

符合各项同性,光从各个方向来没有区别,只和法线夹角有关系。

表示物体反射某种颜色光的能力(其实就是颜色)。

虎书里用的代表RGB颜色,规定的每个分量都在[0,1]之内,这样最终结果也小于1。

公式里的max可以换成绝对值。这么搞叫two-sided lighting,相当于镜像再放置一个光源。

环境光 Ambient

据说直觉上是场景内所有颜色的平均值....?

如果要保证,可以让

镜面反射或者叫高光 Specular/Phong shading


(图片的字母不太一样,e是V,少了一个I的反射R)


Blinn Phong的话,是

是镜面反射系数(反射某种颜色光的能力,和差不多)。用来控制反射光颜色。

n越大反射光越集中。实际上是让缩小的更快一点。

Blinn Phong的效果更柔和一点。

Shading

Vertex-Based Diffuse Shading

算顶点的颜色,然后重心坐标插值出三角形的颜色。

Phong Shading

重心坐标插值出三角形中所有点的法向(本质是对原来光滑曲面的近似),然后用这个法向算颜色。

Texture

提供一个Texture function(可以是函数或者查表,就是图片),和一个平面上点对texture function的对应关系,就可以贴纹理了(

2D纹理

提供一个2D坐标,在此之外的砍掉整数部分。

需要把物体的xyz坐标map到uv上。好像不用对应的很紧密,只要像那个形状就可以往上贴(不过肯定会失真)。

平面投影


在平坦的表面上很好用,但和投影方向(一般是法线)垂直的地方就会出现那个面全部被map到texture的一个点上的情况...

球坐标

把xyz转到球坐标上,得到。由于,有

地球仪用的这种。

柱坐标

先转到柱坐标再归一化。和球差不多。

Cubemaps

球坐标在两极会变形,可以用一个立方体代替(不过有在边上不连续的缺点)。

具体是把球上的点投到包着球的正方体上。即可。正方体每个面有一个(u,v)。具体的坐标挺讲究。。。查书吧。

纹理坐标插值

三角形的每一个顶点存一个(u, v)。内部的某个点的uv通过插值得到。

这里的插值不能在做齐次除法(v/w)后的screen space算(重心坐标会变),需要先在screen space算出重心坐标,然后通过: 算出world space(MVP矩阵不会改变重心坐标所以在哪的都一样)的重心坐标。同理。

具体为什么....我猜是因为齐次除法把z搞没了少了一个维度(w在persp后其实是z)。嗯推公式也能推出来,总之不管了。

这玩意叫透视校正插值。

取纹理值的方法

插值出的uv不是整数。如果texture function是离散的,得有一个方法取值: - nearest neighbor:取最靠近的一个 - bilinear:拿周围四个双线性插值 - hermite:把bilinear用的换成 - bicubic:拿周围十六个点 - ...

MipMap

解决texture太大的问题(屏幕上的一个像素对应texture的多个像素)。

本质是范围查询。对屏幕上的某个点o,找邻近两点(上和右)a, b。取mipmap level 。D代表在第几层会取到一个像素。

D不是整数,所以用trilinear interpolation。在floor(D)和ceil(D)双线性插,结果再插一次。

会导致Overblur的问题。原因是每次缩放一半相当于只有宽高比为1的情况。用各项异性过滤(Anisotropic Filtering)可以解决宽高比不为1,但斜着就不行了。

纹理的应用

Environment map

天空盒,用一个球或者cubemap记录无限远处的环境光照,这样可以只通过方向查询env map上的点。

凹凸贴图 Bump map

用贴图记录表面上的相对高度,从而改变法线。
二维: 线 三维同理。求出du, dv,然后

求出的法线在TBN坐标系下。

法线贴图 Normal map

更好用的Bump map(以至于前者基本没人用)。

贴图记录法线而不是高度差,直接替换即可。也在TBN下。

位移贴图 Displacement map

真正的移动顶点的位置。需要和三角形的顶点一一对应(所以顶点得足够多)。


未完待续