上面两点下面一个三角形_三角形光栅化

ef2e08710bbd538929e4c5259ad8a303.png

Scanline triangle rasterizer

将三角形分成4类:
1、平顶三角形
2、平底三角形
3、右边为主
4、左边为主

76320ecf98d1db43a4c06c3c2e9a6568.png

1、平顶三角形

b2c02d99c2ff11d7bd3de515cdb766a8.png
void 

2、平底三角形

21aaa2d973f53c882b03fada0da7b9ed.png
void 

3、后两种三角形

5f24bbf7e593bedaccc3a79a43efdb48.png

求解

坐标

void 

Bounding Box + 判断点是否在三角形内

对三角形所在区域提取边界框
扫描边界框内的所有点
判断点是否在三角形内部
  • 最简单粗暴,通过叉积判断是否在三角形内部

81b8d3ca967c72fafc28dbd7664385f5.png

如果

同号,则点
在三角形
内部,否则外部

Barycentric Algorithm

思路属于 { bounding box + 判断点是否在三角形内部 }
三角形共顶点的两边对应的向量
构成平面空间的一组基底,平面上任意点
可以被这组基底表示

96db677e2691aaef65fb1772efadf585.png

解方程得到

,并且满足:

时,可以判断点

在三角形内部 方程解法:

所以:

需要注意

时,要判断叉积结果的
坐标是否为
以避免除
出错
说明:算法思路简单明了,但对于每个点都要计算一次叉积,不够快捷

Edge Equation

思路属于 { bounding box + 判断点是否在三角形内部 }

直线方程

51709a8d02b06340a383d8d445ea96bb.png

其中

可以视为一个与直线上任意一点
都垂直的向量。 所以该向量会指向直线的某一侧。
  • 思路概述
    对于一般直线方程来说,点在直线上,代入方程为0;点在直线一侧,代入方程,恒正或恒负
    如果直线上两点是已知的,那么直线两侧的正负情况与两点的顺序有关联。
    比如,如果直线AB左侧的点代入直线方程,结果为正,那么直线BA应是右侧的点代入方程为正。 
    可想而知,当三角形根据一致的顺序(正逆时针)排列顶点并按相同的算法获得三边直线方程时:

    三角形内部外部的点代入三边直线方程得到的正负符号是一致正或一致负的。

    据此,可以判断点是否在三角形内部 
  • 根据两点获取直线方程的方法
思路:
    齐次坐标下,二维坐标点扩充为三维向量,并且第三维是1.
    可以认为所有所有点都落在三维空间中 z=1 平面上.
    向量OA与向量OB的叉积将垂直于直线AB所在平面.
    直线上的点与该叉积的内积将始终为0.
    由此,可以获得该直线方程。 即,通过叉积直接获得直线方程的系数.

直线方程:

上式可以认为向量

垂直于
平面

当直线经过原点附近时,常数项

值接近于
,通过上式计算
值容易损失精度(接近的浮点数相减)

所以改用下式计算C值:

直线上的点使方程成立,直线一侧的点使方程恒正或恒负

对于两个点叉积计算系数得到的直线方程来说

时,向量
左侧恒正

另外,此处用

向量表示直线方程
  • 关于向量
    左侧的点使方程恒正的解释

55681e7603b24da77510ce4789e95f99.png
  • 判断点是否在三角形内
在右手系中
当根据逆时针方向获得三边直线方程时,三角形内的点代入三直线方程,结果都是正值
顺时针时,结果都是负值

edge-equation便于线性插值

  • 获得直线方程后,方便对三角形内部的点进行相关参数的线性插值

当相关参数对于点的坐标满足线性时,有如下方程成立:

此时只要求解了线性方程的系数,就可以根据点的坐标对三角形内部点的相关参数进行插值。

三个顶点的参数是已知的,所以有如下方程成立:

其中伴随矩阵刚好可以用直线方程表示,而且行列式也可以用直线方程中的系数

表示:

另外,有意思的是,三角形面积与上述行列式有如下关系:

关于该面积公式的解释:

  1. 该公式可以通过作图法证明,其中用到了“二维平面上的三角形面积等于两边叉积所得向量模的一半”这一性质
  2. 还可以通过行列式的几何意义解释该公式:

二维行列式可以认为是两个平面向量张成平行四边形的面积,三维行列式可以认为是三个空间向量张成六面体的体积。

对于空间向量

,起点都是原点,终点都落在
平面上,三个终点与一个公共起点围城了一个三棱锥,三棱锥体积是对应张成六面体体积的
,将三个终点围城的三角形视为三棱锥的底面,可知:

可以发现在计算行列式的过程中,顺便求解了三角形面积。 而这个面积不是普通的面积,这个面积是“有向面积”,通过行列式几何意义得到的面积或体积都是有向的。对于右手系来说,逆时针排列向量计算得到的面积、体积都是正的。 于是,根据计算得到的面积值的正负,可以判断三角形是正面还是反面。

    if(逆时针为正面){
        if(S>0)
            正面三角形
        else 
            反面三角形
    }
  • 最后,插值公式总结为:

对于边界点的处理

对于两个三角形公共边需要特殊处理一下
如果按照属于两个三角形来处理两次,当渲染透明物体时会导致 "double hitting"
如果不做处理会产生洞
通常约定,当公共边是三角形上面或左面的边时做处理,右面或下面的边则不做处理,以此来保证只处理一次
  • 该规则可以通过 edge-equation 给出数学形式

904970ad491e968acba44a034a38058d.png

对于

来说,边
的边界方程对应的向量是

对于

来说,边
的边界方程对应的向量是

公共边对相邻三角形分别计算的边界方程向量是正好相反的

所以同一条边对两个三角形得到的向量元素的正负属性是不同的

e0f877a3b99ad78be75f17693f47de78.png

图中

的两个端点与原点相连接围成一个平面,两个直线方程系数向量(即途中黄色和红色向量)与该平面垂直

所以从边界方程向量的几何意义上看,

要判断边在三角形左边,需要

要判断边在三角形上边,需要

因为认为三角形所有顶点都在
平面上,所以边界方程向量不可能同时满足
// 最后,边界判定方法如下:
    // 对于当前三角形,E是边界方程,(A,B,C)是边界方程对应向量
    bool tie = A!=0?A>0:B<0;
    if( E(x,y) >0 || (E(x,y)==0 && tie))
        pixel is covered;

增量

有了edge-equation,并不需要逐个点代入方程判断是否在三角形内
而是可以通过增量的形式快速获得结果

同理

批量处理

786f1776b531f01ea877fa625a35c8ed.png

可以对bounding box内的像素划分成block,依次判断block的四个角点,如果角点都在三角形内,则此block内部的点可以直接处理而不用再做判断。 通过划分block和增量的方法可以加速光栅化过程。

  • 存在的问题

如果三角形比较纤细,划分成block效果不明显

可以求出三角形形状的大致描述:

给出经验区间

    if(shape > 0.4 && shape<1.6)
        edge-equation方法
    else //比较纤细的三角形
        scanline方法
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值