2016年3月17日 星期四

頂點及索引

Vertex and Index

頂點 ->索引
v0 -> 0
v1 -> 1
v2 -> 2
v3 -> 3

index決定三角形構成方式
[0,1,2,2,3,0]
v0->v1->v2
v2->v3->v0
決定了兩個三角形構成,
也就是決定了兩個面

頂點代表多重意義,基本上是多種屬性的重疊
一般封裝的方式有兩種:

struct Vertex {
  Vector3 Position;
  Vector3 Normal;
  Vector3 Color;
}

Vector3[] Vertices;
Vector3[] normals;
Vector3[] colors;

Vertex Buffer

存放vertices的區域,稱為vertex buffer
在DX/OpenGL中,我們需要
1 申請vertex buffer
2 綁定buffer
3 上傳vertex資料
4 一個模型對應一個buffer

在unity中, 這些已經被封裝了

Gluint vertexbuffer;
glGenBuffer(1,&vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(g_vertex_buffer_data),g_vertex_buffer_data,GL_STATIC_DRAM);

Index Buffer

存放index資料的暫存區,稱為index buffer

不同的向量方向,構成的三角形不同

[0,1,2]構成 v0->v1, v1->v2兩個向量
[2,1,0]構成v2->v1,v1->v2兩個向量
兩者的法向量不同,所以是不同三角形


 三角形的正面及背面





Dx以情況A為正向,依據左手系統,法向量朝我方。

OpenGL以情況B為正向,依據右手系統,法向量朝我方。


索引的意義


1 每三個索引,決定一個三角形(面數)
2 索引順序不同,構成三角形不同
3 DX預設順時針為正向,OpenGL預設逆時針為正向
4 索引會決定三角形的正面、背面
5 索引可表示重複使用的頂點,可減少記憶體使用
6 索引是簡單整數,有些設備一個物件只支援65535個索引=21845個三角形

Unity物件頂點數限制65000個,也是從此而來。

物件頂點數超過65535個,可進行頂點資料及索引拆分,分成兩份資料。

7 合併緩衝區

用索引決定渲染

渲染整個模型,索引從0到最後
渲染某部分,更改索引起始位置及結束位置

合併緩衝區

就是把兩個物件的頂點緩衝區及索引緩衝區合併,當成一個物件處理。

假設三個物件的vertexBuffer及indexBuffer:
v0   v1  v2 => 0,1,2
m0 m1 m2 => 0,1,2
n0  n1   n2 => 0,1,2

合併後
[v0,v1,v2,m0,m1,m2,n0,n1,n2]
[0,1,2,(0+3),(1+3),(2+3),(0+6),(1+6),(2+6)]

0+3=4,表示是vertex的第四個=m0
1+4=5,表示是vertex的第五個=m2

這就是unity draw call batching的原理
合併緩衝區在物件是靜態時,效果最好,
如果非static卻一直合併緩衝區,就適得其反。
所以unity draw call batching 有分dynamic及static,
確保物件是static才使用static方法。

沒有留言:

張貼留言