ArrayCamera银还,陣列相機,其本質(zhì)應(yīng)該是shift camera原理(成像平面投射偏離)的應(yīng)用瘫里。WebGL中的ArrayCamera設(shè)計意圖是為VR場景高效渲染提供支持肿轨,但是目前實際上只是提供了多子視口(sub view port)的渲染支持。
webgl_array_camera例子
webgl_array_camera例子只是實現(xiàn)了類似九宮格效果的多視口(viewport)畫面渲染恃逻。其實現(xiàn)方式是通過在unit square [0..1]區(qū)間按照比例定義每個子視口的參數(shù)雏搂,同時還有子視口對應(yīng)的投射矩陣參數(shù)。在渲染時寇损,對每個子視口參數(shù)根據(jù)實際的窗口尺寸進行對應(yīng)的glViewport調(diào)用凸郑,然后根據(jù)對應(yīng)的投射矩陣渲染場景到對應(yīng)的視口。
在OpenGL ES上的C++渲染實現(xiàn)
webgl的arraycamera渲染例子實現(xiàn)起來比較簡單矛市。首先定義相機接口芙沥,包含子視口參數(shù),投射矩陣參數(shù)。其次在渲染前實現(xiàn)對相機列表中每個視口和投射矩陣的應(yīng)用而昨。
iOS版本實現(xiàn)源碼可以從github上獲取救氯。
1. 定義PerspectiveCamera接口
//sub view port參數(shù),使用比例設(shè)置
struct SubViewPort
{
float x;
float y;
float width;
float height;
SubViewPort(float x,float y,float width,float height):x(x),y(y),width(width),height(height){};
};
class PerspectiveCamera{
public:
Matrix4 projMat;
float aspect;
float fov;
float near;
float far;
SubViewPort subview;
public:
PerspectiveCamera(float aspect=1.0,float fov=50.0,float near=-0.1,float far=-10000.0):aspect(aspect),fov(fov),near(near),far(far),subview(SubViewPort(0.,0.,0.,0.)){
updatePorjectonMatrix();
};
~PerspectiveCamera(){};
void updatePorjectonMatrix(){
//make a right handed projection matrix
projMat = Matrix4::makeProjection(fov,aspect,near, far);
}
};
2. 設(shè)置子視口參數(shù)和對應(yīng)的投射矩陣
每個子視口和對應(yīng)的投射矩陣實現(xiàn)為一個PerspectiveCamera實例歌憨,所有的PerspectiveCamera實例存儲在一個容器中着憨。
//6*6陣列相機
vector<PerspectiveCamera> arrayCamera;
int amount = 6;
float size = (float)1/amount;
for ( int y = 0; y < amount; y ++ ) {
for ( int x = 0; x < amount; x ++ ) {
PerspectiveCamera subcamera;
subcamera.subview = SubViewPort((float)x/amount,(float)y/amount,size,size);
arrayCamera.push_back(subcamera);
}
}
...
//設(shè)置每個投射矩陣參數(shù)
float aspect = g_windowWidth / static_cast <double> (g_windowHeight);
for(auto &camera : arrayCamera){
//注意:camera必須為reference,否則參數(shù)無法存儲到arrayCamera的實例中
camera.aspect = aspect;
camera.far = g_frustFar;
camera.near = g_frustNear;
camera.fov = g_frustFovY;
//生成投射矩陣
camera.updatePorjectonMatrix();
}
3. 渲染時應(yīng)用多個子視口
在渲染時务嫡,每個子視口被設(shè)置到window的一個特定區(qū)域享扔,每個視口都可以實現(xiàn)獨立的場景渲染。
for(auto &camera:arrayCamera){
//由于每個子視口以比例方式設(shè)置植袍,應(yīng)用時要根據(jù)窗口尺寸進行適當?shù)目s放。
SubViewPort svPort = camera.subview;
int x = svPort.x * g_windowWidth;
int y = svPort.y * g_windowHeight;
int width = svPort.width * g_windowWidth;
int height = svPort.height * g_windowHeight;
glViewport(x, y, width, height);
//背景渲染
planeModel->setPerspectiveCamera(make_shared<PerspectiveCamera>(camera));
planeModel->Render();
//teapot渲染
teapotModel->setPerspectiveCamera(make_shared<PerspectiveCamera>(camera));
teapotModel->Render();
}
4. 渲染效果
arraycamera_example_20200329.jpg