cocosd-x vr原理解析

一.先上渲染部分的代码

const float eyeOffset = 40.f;

    auto headRotation = _headTracker->getLocalRotation();

    headRotation = Mat4::IDENTITY;

    Mat4 leftTransform;

    

    Mat4::createTranslation(eyeOffset, 0, 0, &leftTransform);

    leftTransform *= headRotation;

 

    Mat4 rightTransform;

    Mat4::createTranslation(-eyeOffset, 0, 0, &rightTransform);

    rightTransform *= headRotation;

 

    _fb->applyFBO();

    auto defaultVP = Camera::getDefaultViewport();

    Camera::setDefaultViewport(_leftEye.viewport);

    scene->render(renderer, leftTransform, nullptr);

    Camera::setDefaultViewport(_rightEye.viewport);

    scene->render(renderer, rightTransform, nullptr);

    Camera::setDefaultViewport(defaultVP);

    _fb->restoreFBO();

 

    auto texture = _fb->getRenderTarget()->getTexture();

    GL::bindTexture2D(texture->getName());

    _glProgramState->apply(Mat4::IDENTITY);

 

    GLint origViewport[4];

    glGetIntegerv(GL_VIEWPORT, origViewport);

    glViewport(0, 0, _texSize.width, _texSize.height);

 

    renderDistortionMesh(_leftDistortionMesh, texture->getName());

    renderDistortionMesh(_rightDistortionMesh, texture->getName());

 

 

    glViewport(origViewport[0], origViewport[1], origViewport[2], origViewport[3]);

 

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

二.详解

1.原理:通过调整摄像头的x偏移模拟2个眼睛,渲染(拍摄)出2个不同角度的图片,讲2个图片渲染到一涨纹理。对该渲染的纹理进行网格处理畸变(桶型)后,再渲染到屏幕上。

2.参数解析

eyeOffset:两眼间距(更准确的说是 左右摄像头的x偏移).

最核心的是tDistortionMesh的生成。贴上关键代码

    const int rows = 40;//行

    const int cols = 40;//列

 

    GLfloat vertexData[rows * cols * 5];//顶点数组

 

    int vertexOffset = 0;

 

    const float vignetteSizeTanAngle = 0.05f;

 

    const float maxDistance = sqrtf(textureWidth * textureWidth + textureHeight * textureHeight) / 4;.//个人认为是cocos的一个bug  应该是   const float maxDistance = sqrtf(textureWidth/2 * textureWidth/2+ textureHeight * textureHeight) / 2才是半径

 

 

    for (int row = 0; row < rows; row++)

    {

        for (int col = 0; col < cols; col++)

        {

            const float uTexture = col / (cols-1.0f) * (viewportWidthTexture / textureWidth) + viewportXTexture / textureWidth;//u坐标

            const float vTexture = row / (rows-1.0f) * (viewportHeightTexture / textureHeight) + viewportYTexture / textureHeight;//v坐标

 

            const float xTexture = uTexture * textureWidth - xEyeOffsetTexture;

            const float yTexture = vTexture * textureHeight - yEyeOffsetTexture;

//很关键这里 xEyeOffsetTexture 和yEyeOffsetTexture 其实就是畸变中心位置

            const float rTexture = sqrtf(xTexture * xTexture + yTexture * yTexture) / maxDistance;

    //计算r

            const float textureToScreen = (rTexture > 0.0f) ? distortion->distortInverse(rTexture) / rTexture : 1.0f;

//畸变处理

            const float xScreen = xTexture * textureToScreen;//畸变处理后在纹理中的x位置(以中心点为坐标原点的坐标系)

            const float yScreen = yTexture * textureToScreen;//畸变处理后在纹理中的y位置置(以中心点为坐标原点的坐标系)

 

            const float uScreen = (xScreen + xEyeOffsetScreen) / screenWidth;//畸变处理后在纹理中的x位置(左下角为圆点的坐标系)

            const float vScreen = (yScreen + yEyeOffsetScreen) / screenHeight;//

畸变处理后在纹理中的y位置(以左下角为圆点的坐标系)

 

           

            // position x,y (vertices)

            // 0,1转换到-1,1的顶点坐标系

            vertexData[(vertexOffset + 0)] = 2.0f * uScreen - 1.0f;

            vertexData[(vertexOffset + 1)] = 2.0f * vScreen - 1.0f;

 

            // texture u,v

            vertexData[(vertexOffset + 2)] = uTexture;

            vertexData[(vertexOffset + 3)] = vTexture;

 

            // vignette

            vertexData[(vertexOffset + 4)] = vignette;

 

            vertexOffset += 5;

        }

    }

 

 

转载于:https://my.oschina.net/u/2617621/blog/855729

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值