интегрировать Oculus SDK Distortion в простой DirectX Engine

Некоторое время я работал над очень простым движком рендеринга DirectX11. Сегодня мне удалось настроить стереорендеринг (двойной рендеринг сцены в текстуры) для интеграции с Oculus Rift.

[В настоящее время] В настоящее время я в основном занимаюсь следующим:

  • У меня окно 1280х800
  • визуализировать всю сцену в RenderTargetViewLeft_ (1280 x 800)
  • отображать содержимое RenderTargetViewLeft_ как «EyeWindow» (как в учебнике) в левой части экрана (640 x 800)
  • визуализировать всю сцену в RenderTargetViewRight_ (1280 x 800)
  • отображать содержимое RenderTargetViewRight_ как «EyeWindow» (как в учебнике) в правой части экрана (640 x 800)

так что все это работает до сих пор, я получил сцену дважды, отрендеренную в отдельные текстуры, в конечном итоге на разделенном экране.

[Цикл рендеринга DirectX11]

bool GraphicsAPI::Render()
{
    bool result;

// [Left Eye] The first pass of our render is to a texture now. 
result = RenderToTexture(renderTextureLeft_);
if (!result)
{
    return false;
}

// Clear the buffers to begin the scene.
BeginScene(0.0f, 0.0f, 0.0f, 1.0f);

// Turn off the Z buffer to begin all 2D rendering.
TurnZBufferOff();

// Render The Eye Window orthogonal to the screen
RenderEyeWindow(eyeWindowLeft_, renderTextureLeft_);

// Turn the Z buffer back on now that all 2D rendering has completed.
TurnZBufferOn();


// [Right Eye]  ------------------------------------
result = RenderToTexture(renderTextureRight_);
if (!result)
{
    return false;
}

TurnZBufferOff();

RenderEyeWindow(eyeWindowRight_, renderTextureRight_);

TurnZBufferOn();

// [End] Present the rendered scene to the screen.
EndScene(); // calls Present

return true;
}

[Что я хочу сделать сейчас] Теперь я пытаюсь добиться бочкообразного искажения с помощью Oculus SDK. В настоящее время я не беспокоюсь о другой виртуальной камере для второго изображения, просто сейчас хочу добиться бочкообразного искажения.

Я прочитал руководство для разработчиков [1], а также попытался заглянуть в демонстрацию TinyRoom, но я не совсем понимаю, что сейчас необходимо для достижения искажения с помощью SDK в моем уже работающем движке DirectX.

В Руководстве для разработчиков Инициализация текстуры рендеринга показано, как создать текстуру для API. Я предполагаю, что это означает, что мне нужно настроить ВСЕ мои RendertargetViews с соответствующим размером API (Render Targets в настоящее время имеет размер 1280 x 800) - и даже изменить размер DepthStencilView и Backbuffer, я думаю.

Тогда цикл рендеринга будет выглядеть примерно так:

ovrHmd_BeginFrame(hmd, 0);
BeginScene(0.0f, 0.0f, 0.0f, 1.0f);
...
// Render Loop as the Code above
...
ovrHmd_EndFrame(hmd, headPose, EyeTextures);
// EndScene(); // calls Present, not needed on Oculus Rendering

Я чувствую, что чего-то не хватает, поэтому я уверен, что не все понял правильно.

[Обновление] Итак, мне удалось визуализировать сцену с бочкообразным искажением с помощью Oculus API. Хотя полигоны левого и правого изображения слишком далеко друг от друга, это может быть вызвано использованием моего размера текстуры по умолчанию 1280 x 800 для целей рендеринга. CameraStream также не отображается ортогонально экрану при перемещении HMD. Буду дальше тестировать ;)

[1] – Руководство для разработчиков Oculus: https://developer.oculus.com/documentation/


person Max    schedule 31.03.2015    source источник


Ответы (1)


Ключевым моментом поддержки 3D HMD, как правило, является рендеринг всей графической сцены дважды. Один раз с левой виртуальной камерой и один раз с правой виртуальной камерой - расстояние между глазами разное, но примерно около 65мм.

Чтобы сохранить Сцену, нужно отрендерить графическую Сцену в текстуры. Сначала я визуализировал свою сцену, используя левую виртуальную камеру, в RenderTextureLeft_, а затем я визуализировал точно такую ​​же сцену с помощью правой виртуальной камеры в RenderTextureRight_. Этот метод называется «рендеринг в текстуру». Это означает, что мы сохраняем изображение для дальнейшей постобработки в отдельную текстуру вместо того, чтобы отображать его непосредственно в резервном буфере для отображения на мониторе.

Хорошо, но как мы теперь можем сделать рендеринг на Oculus Rift? Важно сначала настроить экземпляр hmd и правильно его настроить. Это действительно хорошо объяснено здесь, в официальной документации [1]: https://developer.oculus.com/documentation/pcsdk/latest/concepts/dg-render/

После того, как обе RenderTextures (левый глаз, правый глаз) успешно преобразованы в текстуры и устройство Oculus настроено соответствующим образом, необходимо предоставить Oculus SDK обе визуализированные текстуры, чтобы распечатать их на мониторе HMD и выполнить искажение Barrel с помощью Oculus SDK (не искажение клиента, которое больше не поддерживается в более новых версиях SDK).

Здесь я показываю свой код DirectX, который снабжает Oculus sdk обеими моими текстурами рендеринга, а также выполняет искажение Barrel:

bool OculusHMD::RenderDistortion()
{
    ovrD3D11Texture eyeTexture[2]; // Gather data for eye textures 
    Sizei size;
    size.w = RIFT_RESOLUTION_WIDTH; 
    size.h = RIFT_RESOLUTION_HEIGHT;

    ovrRecti eyeRenderViewport[2];
    eyeRenderViewport[0].Pos = Vector2i(0, 0);
    eyeRenderViewport[0].Size = size;
    eyeRenderViewport[1].Pos = Vector2i(0, 0);
    eyeRenderViewport[1].Size = size;

    eyeTexture[0].D3D11.Header.API = ovrRenderAPI_D3D11;
    eyeTexture[0].D3D11.Header.TextureSize = size;
    eyeTexture[0].D3D11.Header.RenderViewport = eyeRenderViewport[0];
    eyeTexture[0].D3D11.pTexture = graphicsAPI_->renderTextureLeft_->renderTargetTexture_;
    eyeTexture[0].D3D11.pSRView = graphicsAPI_->renderTextureLeft_->GetShaderResourceView();

    eyeTexture[1].D3D11.Header.API = ovrRenderAPI_D3D11;
    eyeTexture[1].D3D11.Header.TextureSize = size;
    eyeTexture[1].D3D11.Header.RenderViewport = eyeRenderViewport[1];
    eyeTexture[1].D3D11.pTexture = graphicsAPI_->renderTextureRight_->renderTargetTexture_;
    eyeTexture[1].D3D11.pSRView = graphicsAPI_->renderTextureRight_->GetShaderResourceView();

    ovrHmd_EndFrame(hmd_, eyeRenderPose_, &eyeTexture[0].Texture);

    return true;
}

Представление Стереоизображения, включая Бочкообразное искажение как своего рода эффект постобработки, окончательно выполняется с помощью этой строки:

ovrHmd_EndFrame(hmd_, eyeRenderPose_, &eyeTexture[0].Texture);

Надеюсь, код поможет тому или другому лучше понять Pipeline.

person Max    schedule 11.03.2016