USD Hydra 解読

`USD` のシーンとレンダラをつなぐ Hydra Framework を自前のアプリに乗せる方法を調べる。
usd ソースの testenv と extras に動くサンプルがある。

実験

* https://github.com/ousttrue/usd_cpp_samples

参考

* http://graphics.pixar.com/usd/files/Siggraph2019_Hydra.pdf
* [USD 入門編１：ライブラリ概要](https://qiita.com/takahito-tejima/items/9261bb6dbe63fd72c377)

* https://developer.nvidia.com/usd#tutorials
* [Hydraとは？](https://snippets.cacher.io/snippet/cb15c5a82078da9f9470)
* [USD Hydra解析](https://memo.vec4d.xyz/home/usd-hydra%E8%A7%A3%E6%9E%90)

code

* https://github.com/VictorYudin/switch

## hydra 概要

* http://graphics.pixar.com/usd/files/Siggraph2019_Hydra.pdf

を読む。

> high performance rendering engine that used OpenGL to image USD stages as fast a possible

👇

> transports live scene graph data to renderers

シーン(複数可)をRendererに送るフレームワーク。

```
SceneDelegate  app       RenderDelegate
                |
presto--------+ v +----> renderMan
USD-Scene --> hydra --> hdStorm
                  +----> embree
```

ゲーム向けじゃなくて、ツール向けという感じか？。60FPS とかを志向するんでなくて、巨大なシーンをなるべく速くという感じで、既存のレンダリングエンジンには無かったタイプ。

usd の名前付けで `imaging` とあるのが `hydra` 関連ぽい。

* pxr/imaing
* pxr/usdImaging

### sample

pdf の tiny sample とだいたい同じ。
APIの簡単な説明。絵は出ない。

`extras/imaging/examples/hdTiny`

* inherit HdSceneDelegate
* inherit HdRenderDelegate

### sample

pdf の tiny sample とだいたい同じ。
APIの簡単な説明。絵は出ない。

* https://github.com/Danielsirota/tinyUSDHyrda
* inherit HdSceneDelegate
* inherit HdRenderDelegate

## HdSceneDelegate

独自のシーンをレンダラーに送る場合に継承する。
`usd` をレンダラーに送るならば、 `UsdImagingDelegate` を使う。

|SceneDelegate|memo|
|:--|:--|
|UsdImagingDelegate|https://graphics.pixar.com/usd/docs/api/class_usd_imaging_delegate.html PrimAdapter で拡張できる|
|HdNukeSceneDelegate|https://github.com/nrusch/nuke-to-hydra/blob/b316396b5e84b74ac3b827d8ae3d86e959f140ad/src/hdNuke/sceneDelegate.h|
|MtohDefaultLightDelegate|https://github.com/Autodesk/maya-usd/blob/09306b91082663486436322361fe2d736b2a7533/lib/mayaUsd/render/mayaToHydra/defaultLightDelegate.h|

## HdRenderDelegate

|RenderDelegate||
|:--|:--|
|HdStRenderDelegate|https://graphics.pixar.com/usd/docs/api/hd_st_page_front.html|
|hdEmbree|https://graphics.pixar.com/usd/docs/api/hd_embree_page_front.html|
|hdOspray|https://github.com/ospray/hdospray|
|cycles|https://github.com/tangent-opensource/hdcycles|
|RadeonProRenderUSD|https://github.com/GPUOpen-LibrariesAndSDKs/RadeonProRenderUSD|

## HdRenderIndex

SceneDelegate と RenderDelegate を結びつける。
以下のように `SceneDelegate => RenderIndex => RenderDelegate` という関係で初期化する。

```c++
    // RenderDelegate から RenderIndex を作って
    _renderIndex.reset(
        pxr::HdRenderIndex::New(
            _renderDelegate.Get(), {&_hgiDriver}));
   // RenderIndex から SceneDelegate を作る
    _sceneDelegate = std::make_unique<pxr::UsdImagingDelegate>(
        _renderIndex.get(), _sceneDelegateId);  
```

## HdStRenderDelegate

USD 標準の OpenGL による RenderDelegate。

`HdStRenderDelegate` を動かすためには、 `OpenGL` 環境のセットアップと `SceneDelegate` の必須項目の実装の両方が必用。

### HGI

* OpenGL 対応の RenderDelegate のサポート
  * HGI https://graphics.pixar.com/usd/docs/api/class_hgi.html#details

```c++
pxr::GlfGlewInit();
pxr::GlfRegisterDefaultDebugOutputMessageCallback();
pxr::GlfContextCaps::InitInstance();
std::cout << glGetString(GL_VENDOR) << "\n";
std::cout << glGetString(GL_RENDERER) << "\n";
std::cout << glGetString(GL_VERSION) << "\n";

// Hgi and HdDriver should be constructed before HdEngine to ensure they
// are destructed last. Hgi may be used during engine/delegate destruction.
_hgi = pxr::Hgi::CreatePlatformDefaultHgi();
_driver.reset(new pxr::HdDriver{pxr::HgiTokens->renderDriver, pxr::VtValue(_hgi.get())});
// RenderIndex which stores a flat list of the scene to render
_renderIndex = pxr::HdRenderIndex::New(&_renderDelegate, {_driver.get()});

// XXX: Setup a VAO, the current drawing engine will not yet do this.
glGenVertexArrays(1, &_vao);
```

### SceneDelegate の 最低限

### sample

* https://github.com/dboogert/USD/tree/tutorials/extras/usd/tutorials/IETutorials 
* usd-20.08 だと APIが変わってしまっているので動かす方法調査中
* inherit HdSceneDelegate
* use HdStRenderDelegate


## UsdImagingGLEngine

`pxr/usdImaging/usdImagingGL/engine.cpp`

高レベルインタフェース。
これを読めば、tiny sample の次に進めそう。

* HdEngine
* HdxTaskController
* use UsdImagingDelegate
* use RenderDelegate plugin

### sample

`pxr\usdImaging\usddImagingGL\testenv\testUsdImagingGLBasicDrawing.cpp`
UsdImagingGLEngine の使い方がわかる。 `hydra` はラップされている。