首页 > 代码库 > 扫描线算法和重心坐标计算方法
扫描线算法和重心坐标计算方法
2017-01-0420:17:10
scan-line algorithm
sweep algorithm
- 求三角形的重心坐标
重心坐标的意义
三角形所在平面的任意点都能表示为顶点的加权平均值,这个权就叫做重心坐标。
表示为I,J,K, I+J+K=1
求重心坐标的快速算法,将图元用扫描线分割成垂直和水平的等分,然后生成一张“扫描边表”,通过这张表可以快速计算出同行的重心坐标。
例如:把v4, v5 存下来,计算v6的时候用上。
(Interpolcation qualifier ) 修饰fragment shader input, 指定插值算法。
smooth (default) perspective interpolation
noperspective linear interpolcation
flat no interpolcation
- 1. 点插值
点插值不需要计算重心坐标,但是可以通过访问glPointCoord [0,1.0] 获得纹理坐标。点纹理坐标的起点可以编程设置为UPPER_LEFT或者LOWER_LEFT.
点光栅化时(做扫描线算法)的时候,插值修饰符(iterpolation qualifier) 对点渲染没有作用,它也不会做混合操作。
启用MULTISAMPLE的时候,可以指定glPointParameteriv(GL_POINT_FADE_THRESHOLD_SIZE ), 单独对alpha通道做fade操作,最终的alpha值为 alpha = alpha * fade_factor.
(derived_size = gl_PointSize)
- 2. 线段插值
P是窗口坐标,t是 点d在线段ab上的重心坐标 ( ? 这样说对吗)
得到像素的值f,w 为clip coordinate的w分量,如果w为1. 公式就是
f = fa * I + fb * J (I=1-t, J=t)
- 三角形插值
计算像素值的公式:
fabc为 顶点的值,w齐次坐标的w分量。
计算像素z值的公式:
如果w=1, 或者忽略掉w值 (noperspective),公式就变成了和计算z值一样的。
以上都是opengl 的概念,搞明白了,就可以在fragment shader 里面订制插值算法了。
- 4. AMD GCN GPU 插值
GCNGPU 光栅化的时候只生成重心坐标I,J,存在v0, v1 两个寄存器(真节省,别浪费v2,它就是1-I-J)
这样对于三角形的smooth 插值:
D = P0 + P10*I + P20*J
( P0, P10, P20 是顶点的值)
分两步走
v_interp_f1_f32 v2, v0, attr0.x //D=P0 + P10*v0
v_interp_f2_f32 v2, v1, attr0.x //D=D+P20*v1
flat 插值一步完成:
v_interp_mov_f32 v3, v0, attrib0.xyz
attribute值需要存放在LDS中, 排列格式
(? K 哪去了,P0 已经被处理过了吗
Refer:
AMD_GCN3_Instruction_Set_Architecture.pdf
Opengl specification 4.5
扫描线算法和重心坐标计算方法