顯示具有 3d圖學 標籤的文章。 顯示所有文章
顯示具有 3d圖學 標籤的文章。 顯示所有文章

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方法。

顏色

顏色表示法


假設使用向量表示顏色,最小值為0,最大值為1。
三原色可表示為:

r=(1,0,0)
g=(0,1,0)
b=(0,0,1)

8位元表示法,最小值為0,最大值為255
r=(255,0,0)
g=(0,255,0)
b=(0,0,255)

[0,1]對應到[0,255],只要每個分量除255即可。



顏色運算

加法

r+g=(1,0,0)+(0,1,0)=(1,1,0)

減法

(1,1,0)-(0,1,0)=(1,0,0)

數乘

0.5*(1,1,1)=(0.5,0.5,0.5)

分量乘法

(r0,r1,r2)*(g0,g1,g2)=(r0*g0,r1*g1,r2*g2)

分量乘法應用
假設c0=(1,1,1) 太陽光
c1=(0.5,0.25,0.5)  材質反射率

c0*c1=(0.5,0.25,0.5)
就是太陽光照射材質後,反射出來的光

向量點積、向量叉積對顏色無意義


顏色分量要限縮在0-1之間,超過這個範圍就無意義