着色1中我们主要知晓了漫反射的定义和实现
今天需要学的内容如下
纹理映射和重心坐标也包括在其中
在上一节课中我们已经知道了漫反射独立于视觉射线,和看的位置没有关系
镜面反射
那么高光是怎么一回事呢,高光项一般出现在比较光滑的表面上,光线的反射都接近于镜面反射,高光只有在视线方向和镜面反射方向足够接近的时候,才会出现高光,在phong模型中,我们发现如果视线方向个镜面反射方向相接近的话,说明半程向量和法线向量非常接近,半程向量要得到也比较容易,两个向量相加然后归一即可
怎样衡量两个向量是否接近呢,根据点乘即可,接近1说明比较接近,这个就类似于漫反射,只是考虑的是半程向量和法线向量是否接近,Ks这里一般就设置为白色,blinn-phong模型简化掉了这个位置上的能量吸收的多少,也就是说少了一个n和l的点乘,这里主要只关注是否能看见高光,使用半程向量明显要比反射向量好算,除了这些不同外,在夹角的余弦上我们还有一个指数,夹角的余弦可以展现两个向量之间是否接近,但是它的容忍量太大了,使用指数可以明显解决高光范围太大的问题,这个指数一般用100到200
我们可以通过下面的例子直观的看到区别
随着p,也就是指数的增加,高光越来越小
环境光照
假设来自环境的光永远都是相同的,认为其不依赖于任何东西,这样做可以得到一个近似的环境光,和观测方向和光源都没关系,这是一个常数,其实这就是一个颜色,保证没有任何一个地方是完全黑的,如果要完全实现,需要运用到全局光照的知识
最后一个完整的光照就是这三个光照(环境光,漫反射,高光)全部相加起来,得到的blinn-phong模型
着色频率
着色频率通过下面的图就可以直观的理解
每一个平面上只着色一次,第一个每一个三角形(基本图元),第二个是每一个顶点,第三个是像素
flat shading
求出每一个三角形的法线,取三角形两条边叉乘就行了,然后根据这个法线和光源求出shading的结果,一个三角形中没有颜色的变化
shade each vertex(Gouraud shading)
求出每一个顶点的法线,根据法线然后每一个顶点做着色,然后三角形内部做插值
shade each pixel(Phong shading)
求每一个像素的法线
对比三种算法
如果本身几何结构上面片足够多,就不需要使用太复杂的着色频率
顶点的法线怎么算,任何一个顶点都和不同的面,三角形有所关联,那么我们只需要将相邻面的法线求一个平均就好了,如果根据面积来加权,求出来的法线会更好
每一个像素的法线要如何定义呢
注意每一个法线向量都是单位向量,需要已知每一个顶点的法线向量然后通过重心坐标来实现
渲染管线(实时渲染管线)
我如何完整的将一个三维场景展现在屏幕上,有一个完整的过程,这个在现代的显卡上都是写好的
MVP
光栅化
深度缓存
着色,这一块是现代计算机图形学主要在做的事,如何着色
材质纹理贴图
Shader Program
一般来说shader就是我们要写的需要在GPU上运行的代码,来决定像素如何被着色,只用写一个像素,每一个像素都会这么执行
我们一般有顶点着色器和片段(像素)着色器,下面这个是OpenGL的片段着色器
这个像素着色器需要告诉如何算出像素的颜色并输出出去,这个着色器有一个纹理,一个光照方向,uv和法线(这个是每一个像素的法线),我们可以得到漫反射系数,并利用漫反射公式求出光照强度,乘以余弦(光照射线和法线的点乘),限制值在0和1之间,再将其返回到颜色这个固定变量上
下面是一个方便用的网站
下面是虚幻引擎做的实时渲染
纹理映射
所谓的纹理映射,就是能够定义一个物体任意一个点上面的属性,也就是漫反射系数等属性
任何一个三维物体的表面要如何去定义,都是用二维图去定义的。所谓纹理就是一张图,将这张图蒙在物体上的过程就叫做纹理映射
任意一个三角形的顶点都可以在纹理上找到,这个都是美工来完成的,这个一般我们认为是已知的
如果是自动的方法,那就是参数化
在纹理上需要定义一个坐标系,这个一般是用uv来显示的,将物体上的点映射到uv上,为了方便处理,uv都在0到1之内
纹理可以用在任何一个物体上,不同的位置可以通过相同的纹理重复多次,纹理设计的好就是无缝衔接
如何知道三角形内部的uv,在已知到每一个顶点的前提下,也就是在三角形内部作插值