視訊投影(二維視訊投影到三維模型上)

隨遇丿而安發表於2021-10-30

視訊投影分享

視訊投影

前置知識

GPU 將影像渲染到螢幕上

image-20211030114355325

物體與紋理

視訊投影:將視訊作為圖片式貼在模型上

視訊投影兩個關鍵元素,模型視訊材質

物體組成

在虛擬世界中,所有物體由三角面構成(也有用四角形的,主流是三角形)

一般模型都是一張皮,內部是空心的

簡單模型

msedge_hjPLBGhDMF

紋理對映

將一張圖片貼在模型上,模型就是一張皮,可以看成是地球儀表面平鋪為世界地圖,模型上每一個頂點對應紋理上的一個位置,頂點間用插值計算紋理顏色,紋理座標使用的是百分比

gFUL2HEAzV

將紋理圖片(2k畫素)貼在一個平面上

msedge_2evhu3Pn4c

將紋理座標和頂點座標一一對應,剩下部分利用插值計算

msedge_WWD6rYO4y5

隨著取樣點變少,影像失真程度越高,當取樣點變成畫素時,便可以將紋理影像完全貼在物體表面(自動過程),程式需要做的,將紋理影像的關鍵點座標與物體點座標對應上

msedge_bCWXJxwftG

在三維世界中,物體就是由自己所有的頂點以及每個頂點表示的顏色組成,顏色可以是自定義,也可以從圖片材質中獲取

3D 轉換

我們能看到一個三維物體,我們需要四種元素,第一:眼睛;第二:大腦,對眼睛接受的資料進行處理;第三:三維世界,我們身處於三維世界中,比如地球,那我們就能描述我們的位置;第四:物體,否則看到就是透明空氣了。

重新定義這四個概念,眼睛---相機,大腦---渲染器,三維世界---場景,物體---物體

看到場景物體的流程

1. 存在一個物體

物體本身具有頂點座標(原始座標資料:position),以及自己的移動(模型矩陣:modelMatrix

msedge_BB2k5cgwz3

茶壺建模完成後會有自己的頂點資料,以及每個頂點對應的顏色,茶壺可以自己進行旋轉、移動和縮放,這三類操作會產生模型矩陣,用於計算。將茶壺自己元素座標資訊與模型矩陣加入到程式中,就相當於將茶壺經過轉換,重置了茶壺上的每個頂點位置。

2. 存在一個相機,用於觀察物體

相機位置、相機朝向和相機向上方向用來唯一確定相機具體方位,由這三個資訊可組成檢視矩陣(viewMatrix

msedge_pABRWSTEKz

將檢視矩陣加入程式中,就相當於鎖定人眼了。

3. 根據相機引數的不同,得到不同的結構

比如:一個眼睛大,看得遠,一個眼睛小,看得近,一個近視眼,一個遠視眼。相機屬性構成了投影矩陣 (projectionMatrix)

msedge_NrCHrJpzw9

將投影矩陣加入到程式中,得到的就是從一個具體的人眼看到的三維世界

XOe1zeBfBH

4. 最終得到規範立方體(canonical view volume)

在立方體內的物體就是我們看到的物體,立方體外的都可以剔除掉,那些都是視野外的。於此同時,由於檢視矩陣和模型矩陣的加入,相機位於原點,看向 z 負軸。(規範立方體 (-1,-1,-1)到(1,1,1))

總結剛剛的過程,最終得到的物體座標為

// projMatrix 投影矩陣,viewMatrix 檢視矩陣,modelMatrix 模型矩陣
gl_position = projMatrix * viewMatrix * modelMatrix * position;

5. 由最終三維場景到二維影像

規範立方體得到了,z 座標 從 1 到 -1 ,z 座標代表這個物體深度。好似從前往後發射射線,碰到的第一個點就將其顏色賦值在平面上,最終形成二維圖片

圖片

視訊投影分析

關鍵:將視訊紋理與模型上對應的頂點一一對應起來

1. 建立與現實一致的虛擬世界

模型比例與現實保持一致;投影的相機所處位置,引數,朝向,向上方向保持一致

Snipaste_2021-10-30_16-36-44

2. 獲取視訊紋理,分析投影過程

目前整個場景有兩個相機,一個是主相機,就是上帝視角的這個相機;另一個是用作投影的相機,這裡就叫投影相機。

首先,先獲取到視訊作為紋理物件,可以直接將視訊看作一張圖片,這裡叫投影圖,投影圖就是投影相機拍出來的,因此,投影相機看到的二維影像就是投影圖

現在我們可以得到三個圖

  1. 上帝視角圖
  2. 投影相機視角圖
  3. 視訊中的投影圖

其中,投影相機視角圖 = 視訊投影圖 (等式 1),2 = 3

因此,現在我們求出投影相機與模型產生的交點,並且根據 “等式1” 找到這個點的顏色,並將顏色賦值上去,最終便得到視訊投影效果

投影相機看到的視角圖

投影相機

真實世界攝像機的視角圖

視訊圖

一一對應上,最終完成

3. 關鍵程式碼解析

  1. 頂點處理
// 獲取投影相機看到的標準立方體
c_Position = u_ProjectionMatrix * u_ViewMatrix * modelMatrix * vec4( position, 1.0 );

// 遍歷模型上的每個點
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
  1. 顏色處理
// 投影相機計算出的 c_Position 處於 (-1,-1,-1)到(1,1,1)標準立方體中,z 是深度,x,y需要轉換區間到 0-1(紋理座標)
vec4 c_Uv4 =  c_Position / c_Position.w;
c_Uv4.xyz = vec3( c_Uv4.xyz + 1.0) / 2.0;

// 根據投影相機看到的頂點找視訊圖的對應位置的畫素並賦值
gl_FragColor = texture2D(mapPicture, c_Uv4.xy);

相關文章