光栅化学习笔记(一)
来源:互联网 发布:手机qq透明皮肤软件 编辑:程序博客网 时间:2024/04/28 18:42
此次笔记为scatchpixel网站的学习笔记,是按照原文的脉络整理的,因为并不是一字一句翻译的,所以没有设置成译文标签,而是将自己理解的还原一下,希望能用更接地气的方式把道理讲明白,如果有错误的地方希望指出。
光栅化之前由投影变换将一个将3d图元转换成2d图像,转换后的图像上的每个点都有一个颜色属性和一个深度属性。光栅化可以分为两个部分,第一个部分就是确定2d图像覆盖了窗口坐标系下哪些像素,第二部分就是确定每个像素的颜色和深度。
1变换顶点到光栅坐标空间
这里先复习下投影变换,具体推导可以看这篇。
p点为摄像机空间内一点,np为投影平面,N为近平面距离,F为远平面距离,p’为p点投影点。
假设P坐标为(cameraX,cameraY,cameraZ),
根据相似三角形很容易得到p’屏幕坐标
screenX=N*cameraX/cameraZ
screenY=N*cameraY/cameraZ
screenZ=-cameraZ
这里screenZ简单即为-z,表示原顶点的深度(cameraZ为负值,深度值取正值,所以取反) 。
然后将screenX,screenY’转换到NDC空间,
ndcX=2 * pScreen.x / (r - l) - (r + l) / (r - l);
ndcY=2 * pScreen.y / (t - b) - (t + b) / (t - b);
如果要判断2d图像覆盖了哪些像素,则应该将2d图像转换到像素所在的坐标系,即光栅坐标系,x范围是[0,width],y范围是[0,height],width,height为帧缓冲的宽高,由于存在图像重叠的情况,会有多个点对应同一个像素,所以需要保存原顶点的深度值,也就是-cameraZ。
所以得到
rasterX=(ndcX+1)/2 * width
rasterY=(ndcY+1)/2 * height
rasterZ=-cameraZ
2判断像素覆盖三角形
在光栅坐标空间,每个像素可以看成是一个整数坐标的点,要判断三角形覆盖了哪些像素,可以反向判断哪些像素在三角形内部即可。要判断一个点是否在三角形内部,用到了一个叫做边缘函数(edge function)的算法。
一条边将一个平面分割成左右两部分,边缘函数可以让我们根据计算结果判断一个点所处的位置:
如果结果为负值,则点在直线左边,
如果结果为正值,则点在直线右边,
如果结果为零,则点在直线上。(这里注意直线是有方向的)
下面给出边缘函数
E01(P)=(P.x−v0.x)∗(V1.y−V0.y)−(P.y−V0.y)∗(V1.x−V0.x) (从v0到v1点向量)
有了这个算法,我们只需对三角形的三条边都进行测试,如果结果都为正(三角形顺时针卷绕),则说明点在三角形内部。
上面给出的公式,仔细观察可以看出其实是求向量v0v1与向量v0p的叉积的z坐标,所以就不用刻意去背这个公式了,只要分别求v0v1与v0p,v1v2与v1p,v2v0与v2p的叉积的坐标即可。
ok,到此给出了像素覆盖三角形的最最最基本的判断方法。
3.计算每个覆盖三角形的像素的颜色
首先感性的来看,P点的颜色应该与三个顶点的颜色是线性相关的,它对于每个顶点的颜色在混合时有一个权重,所以只要求得这三个权重,就可以求出P点的颜色。
这里引入一个概念,质心坐标系,它可以用来定义三角形平面任意点的行为有:
P=λ0∗V0+λ1∗V1+λ2∗V2,
这里我们只需要关心三角形内部的顶点,对于三角形内部的顶点有
λ0+λ1+λ2=1, for P∈△V0,V1,V2.
所以对于颜色就有了:
CP=λ0∗CV0+λ1∗CV1+λ2∗CV2
对于边上的点,如点在v0v1上,则v2点的系数λ2=0,
CP=λ0∗CV0+λ1∗CV1, λ0+λ1=1,
对于三角形的顶点,如v0,有λ1=0,λ2=0 :
CP=λ0∗CV0,λ0=1。
然后给出λ0,λ1,λ2点求法--面积法。
这里只给结论,数学证明跳过。
v0点的权重λ0为与v0相对的三角形(红色)面积占总面的比例相等,λ1,λ2同理。所以只要求由p点划分的三个三角形的面积比例就可以得到三个权重值。三角形面积可以用叉积很容易求得。
λ0=Area(V1,V2,P) / Area(V0,V1,V2),
λ1=Area(V2,V0,P) / Area(V0,V1,V2),
λ2=Area(V0,V1,P) / Area(V0,V1,V2).
同理可以对光栅坐标中的深度值进行插值,求P点的深度值。后面会详细介绍。
光栅化的原则—Top-Left-Rule
当使用边缘函数对于像素点进行判断时,如果结果为0,则表示该像素点在三角形的边上,那么如果这条边是两个三角形的公用边,那么这个条边上的像素会被计算两次,产生右边图的效果。解决方案就是Top-Left-Rule:如果像素点在三角形的边上时,只有这条边是Top边或者Left边,才算做是在三角形内。
解释:以三角形顺时针卷绕为例:
Top边:两个端点y坐标相等,x方向由左向右
Left边:两个端点y坐标不能,x方向任意
第一篇告一段落,抛砖引玉一下,关于深度,法线,纹理坐标的计算,会在第二篇继续整理,欢迎关注。
- 光栅化学习笔记(一)
- Hadoop序列化学习笔记(一)
- android插件化学习笔记(一)
- W3C学院之XHTML结构化学习笔记(一)
- Android——插件化学习笔记(一)
- .Net 序列化学习笔记
- Java序列化学习笔记
- DotNet 序列化学习笔记
- java序列化学习笔记
- java 序列化学习笔记
- 流形正则化学习笔记
- Java序列化学习笔记
- Kryo序列化学习笔记
- 直方图均衡化学习笔记
- kvm虚拟化学习笔记(一)之kvm虚拟化环境安装
- c#序列化学习(一)
- boost之序列化学习(一)
- java对象序列化学习笔记
- 练习题
- 【计算机基础】如何判断大端小端
- Java基础知识总结(1)
- SPI_FLASH时序描述及驱动编程
- ngx_hash_combined_t,ngx_hash_keys_arrays_t
- 光栅化学习笔记(一)
- 如何在SpringMVC中获取request对象
- Spring MVC整理系列(01)————请求流程分析
- md5加密
- Java 快速排序
- maximum continuous drop
- java获取文件夹下所有文件的名称
- NYOJ116 士兵杀敌(二) 线段数、单点更新
- (OK)(OK) port mptcp on Android-x86-kernel-4.4.12 (SUCCESS)