Painter's Algorithm:
像油画一样一层一层的上色
绘画顺序很大程度决定了遮挡关系,比较难以确定遮挡
以左->上->右的顺序,正确建立遮挡
若以右->上->左的顺序,无法正确建立遮挡
且画家算法无法处理复杂的遮挡关系
Z-Buffer深度缓存:
思想:动态记录屏幕上每个像素离我们最近的距离,如果有物体在该像素上的距离小于深度缓存,就刷新深度缓存并写入像素(维护最小值)
注意:相机看向的是z轴的负距离,则z值越大越近,越小越远
伪代码:
for (each triangle T)
for(each sample(x,y,z) in T)
if(z<zbuffer[x,y])
framebuffer[x,y]=rgb;//更新颜色
zbuffer[x,y]=z;//更新深度
else
;//什么也不做,这个像素已经被占用了
复杂度:O(n)
特点:无论什么样的顺序,结果相同
无法处理透明物体
到此可以写作业1了
Shading着色:
定义:对不同的物体应用用不同的材质进行着色
基础的着色模型Blinn-Phong:
限制:
是局部光照模型,无法处理阴影:
只考虑来自光源在一点上的直接光照,考虑诸如表面法线、光照方向、观众的方向和材料属性等因素。它不考虑光线是否真的到达了这个点,或者是否被其他物体挡住了。
在这个着色模型中漫反射被设置为常量
计算一个点的光照,需要的输入有:
观察者的方向向量v
着色点所在表面的法向量n
光线照射的方向向量L
着色点的表面参数(颜色,材质,反光度等)
漫反射Diffuse Reflection:
光线打到一点时会被均匀的反射到各个方向上去,这种反射被称为漫反射。
所以无论我们从哪个方向上看表面颜色是不变的,即与v无关。(是指在点光源下那一点发出的颜色、现实要复杂得多,比如多光源、阴影和路径上的水雾等东西)
物体接受光线能量的方式:
在极小的单位面上可以将光线看成是离散的,图中每一根光线都代表着一股能量,如果物体表面与光线垂直,那么可以接受到所有的光线能量,如果物体表面进行了旋转那么能收到的光线根数会变少,则物体的表面会变暗。
由此得到结论:物体表面的法线和光线的夹角决定了物体表面应该有多亮
即为琅勃余弦公式Lambert's Cosine Law:
E=𝐸0·cos𝜃
其中:E为表面接收到的辐射度(单位面积上的光通量)
𝐸0为入射光线的辐射度
θ为光线入射方向与表面法线之间的夹角
光衰减Light Falloff:
上图是一个点光源往四面八方发射光能量
假设光线在传播过程中不发生能量损失,那么同一瞬间里点发出的光在经过相同时间后,光线的终点可以围成一个球体。
点光源在每个瞬间里发出的能量是固定的,那么每个球壳上的能量大小也是固定的,由此球壳上每一点的能量大小只与球壳的面积有关,也就是只与离点光源的距离有关。
即距离越远,光照强度越弱。
按照途中所示,我们假设在半径为1的这个球壳上所蕴含的能量为k,而在这个球壳上的每一点的光的强度是I,那么在半径为r的球壳上,在这个球壳上的光线的强度就应该是 I/(r*r)。
漫反射强度计算(Lambertian(Diffuse)Shading)
给定一个点光源,光线得方向向量l,着色点表面得法向量n、观察者得方向向量v,光线得入射角度θ,计算得方法如下:
max函数的解释:当l和n的方向相反时,得到的结果时负数,此时光线穿过了物体,在不考虑折射的情况下,直接为0
Kd是一个系数,代表的是物体本身的颜色、材质
kd逐渐增大的效果
高光项Specular Term:
出现条件:物体表面比较光滑(反射接近镜面反射),观察方向与镜面反射方向接近时
Blinn-Phong模型对于高光项的处理方法:
判断是否接近的方法:法线向量与半程向量h(入射方向与视线方向组成的角的角平分线的单位向量)是否接近
为什么加入指数项p:p用于调整容忍度,控制高光分布的锐度和范围
cos的容忍度太高了,以至于我们在45度以上都能看到很好的高光,所以就降低高光的区域,正常用的是100-200,基本3°以外就看不到高光了
环境光照Ambient Term:
不直接来自光源的光线,而是由于经过反射或折射所来到渲染点的光线(非常复杂)
Blinn-Phong模型假设:
将环境光简化为一个全局常数或场景中定义的环境光颜色,即环境光是一个常数
简化忽略了环境光在空间中的变化,以及不同物体间的光照相互作用
深入研究需要研究全局光照
总结Blinn-Phong模型:
顶点法线:
求出与顶点相邻的所有三角形的法线方向,计算所有法线的平均或加权平均(即进行归一化处理)
权重的选择:
面积权重能更好的反映较大面的影响
顶点角度权重能考虑到曲面的局部曲率
逐像素法线插值:
使用重心插值(后续介绍)
着色频率Shadings Frequency:
着色频率是指在渲染中对着色器调用或执行的频率,即对每个像素或片段进行计算的次数
平面渲染Flat shading:
根据每个平面的法向量对平面进行统一着色
对光滑表面效果不佳
高洛得渲染Gouraud Shading:
先求出三角形三个顶点的法线方向,对每个顶点进行着色
再通过颜色插值填充三角形中每个颜色的的颜色
插值方法以后会讲
补色渲染Phong Shading:
求出三个顶点的法线方向,通过三角形内部插值得到三角形每个像素的法线方向,根据每个像素的法线对像素着色
对应着shader里的片元着色器
着色频率与顶点个数的关系:
在顶点个数相同的情况下,着色效果Phone Shading>Gouraud Shading>Flat Shading
但是代价也是会相应增加
随着顶点个数的增加,三种着色频率的着色效果差距越来越小。在顶点个数很多的情况下,平面渲染也可以有较好的着色效果。
图形管线Graphic Pipeline:
图形管线,又称实时渲染管线,可以理解为工作流
是对之前学的知识的梳理:
具体顺序:
【1】输入顶点数据(包含位置、颜色等,也包含他们之间的拓扑关系)
【2】将三维空间中的点投影到屏幕上(留有深度,实际上还有三维特征)
【3】将点形成三角形,并进行光栅化和采样
【4】进行着色
【5】导出
这些是简化的基本操作
着色Shader:
一段在 GPU 上运行的程序,用于对图形数据进行处理和计算。
着色器在图形管线的不同阶段被使用,用于定义图形的外观和效果。主要的着色器类型包括:
【1】顶点着色器(Vertex Shader):
作用:处理每个顶点的属性,如位置、法线、纹理坐标和颜色。
功能:
对顶点位置进行变换(如模型变换、视图变换、投影变换
计算光照模型中的顶点颜色。
生成或修改纹理坐标。
将需要的数据传递给后续阶段。
运行方式:对传入的每个顶点独立地进行处理。(注意独立)
【2】片元着色器(Fragment Shader)(也称为像素着色器):
作用:处理由光栅化阶段生成的每个片元,计算其最终颜色。
功能:
执行复杂的光照计算(如漫反射、镜面反射、环境光)。
进行纹理采样,从纹理中获取颜色或其他数据。
实现特殊效果(如阴影、反射、透明度、法线贴图)。
运行方式:对每个片元独立地进行处理。
【3】几何着色器(Geometry Shader)(可选):
作用:在顶点着色器和光栅化阶段之间,处理完整的图元(如三角形)。
功能:
可以生成新的顶点或图元。
改变图元的类型。
实现如实例化、粒子生成等效果。
【4】细分着色器(Tessellation Shader)(可选):
作用:细分输入的图元,增加网格的细节。
功能:
控制几何的细分程度。
生成更加精细的曲面。
【5】计算着色器(Compute Shader):
作用:不属于传统图形管线,用于通用计算任务。
功能:
执行并行计算,如物理模拟、图像处理。
不直接参与渲染过程。
网站:shadertoy
纹理映射Texture Mapping:
直观来看是将一张二维图贴到三维物体上,但包含的不仅仅是颜色,还有可以包含更多的信息(法线、高光等)
这张二维贴图被称为纹理
关键在于如何建立三维表面点和二维图形上点的一一映射,就要对三维物体表面进行uv分割
默认uv都是在0-1之内,不管长宽比
可以被使用多次