CG系ライブラリ特集

この記事はレイトレ合宿2アドベントカレンダーの二週目の記事です。

二週目ということもあり、遠慮なく、レイトレ入門的な感じでライブラリ紹介を書きたいと思います。



さて、今回のレイトレ合宿2では、なんと!ライブラリ制限無しです!!!

Q. ライブラリに制限はないの?OptiXとかも使っていいの?
A. 制限はありません。自由に使ってください。ただし依存するdllなどは不足なく全て同梱させてください。

キマシタワー


そこで、オープンソースのライセンスが緩いCG系ライブラリを紹介します!
予め断っておくと、Windowsでしか使ったことないので、各方面の方すみません。

また、今回紹介したライブラリのうちのいくつかは、ビルドが大変難しいです。
そこで、VS2012で、static libraryをビルドしましたので、公開しておきます。
ダウンロード及び使用に関しては、ライセンスを良くご確認の上、自己責任でご使用ください。
あと、テストで使用した後は、自分でビルドすることをお勧めします。


(Googleにログインしていると、アクセス権を求められる場合があります。一度ログアウトすると見れるはず)





GLFW
ライセンス:zlib/libpng license
種類:OpenGLウィンドウ作成
使いやすさ:
ビルド難易度:

前回のレイトレ合宿ではGLUTさえ禁止でしたが、今回はライブラリ制限無しです!
OpenGLでウィンドウを出したい場合は、GLUTではなく、複数ウィンドウや、GL4などに対応している、GLFWを使用しましょう
GLFWを使うと、GLUTのように、簡単にウィンドウを出してメインループでOpenGL描画することができます。
バージョン2系と3系で、APIがかなり異なりますが、特に理由なければ3系のほうが良いです。
これを使えばWinMainとか書かなくても戦えますね!

#include <stdlib.h>
#include <iostream>
#include <GL/glfw3.h>

static void key_callback(GLFWwindow * window, int key, int scancode, int action, int mods)
{
    std::cout << "key " << key << " action " << action << std::endl;
}

static void mouse_button_callback(GLFWwindow * window, int button, int action, int mods)
{
    std::cout << "mouse_button" << " button " << button << " action " << action << std::endl;
}

static void cursor_pos_callback(GLFWwindow * window, double x, double y)
{
    std::cout << "cursor_pos" << " x " << x << " y " << y << std::endl;
}

static void window_size_callback(GLFWwindow * window, int width, int height)
{
    std::cout << "window_size" << " w " << width << " h " << height << std::endl;
}

static void window_close_callback(GLFWwindow * window)
{
    std::cout << "window_close" << std::endl;
}

int main(int argc, char** argv)
{
    // glfw初期化.
    if (!glfwInit()) {
        exit( EXIT_FAILURE );
    }
    // ウインドウの作成.
    GLFWwindow* window = glfwCreateWindow(800, 600, "burger_advent", NULL, NULL);
    if (!window) {
        glfwTerminate();
        exit( EXIT_FAILURE );
    }
    // ウインドウをカレントコンテキストに設定.
    // この設定以降、OpenGL命令が使えます.
    glfwMakeContextCurrent(window);
    
    // glfwのコールバックの設定.
    glfwSetKeyCallback(window, key_callback);
    glfwSetMouseButtonCallback(window, mouse_button_callback);
    glfwSetCursorPosCallback(window, cursor_pos_callback);
    glfwSetWindowSizeCallback(window, window_size_callback );
    glfwSetWindowCloseCallback(window, window_close_callback );
    // vsync
    glfwSwapInterval(1);

    // 背景色.
    glClearColor(0.21f, 0.21f, 0.21f, 1.0f);

    // メインループ.
    for (;;) 
    {
        // 描画処理.
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

        glfwSwapBuffers(window);
        glfwPollEvents();
        if (glfwGetKey(window, GLFW_KEY_ESCAPE))
            break;
        if (glfwWindowShouldClose(window))
            break;
    }

    // 終了処理.
    window_close_callback(window);
    glfwDestroyWindow(window);
    glfwTerminate();
    exit( EXIT_SUCCESS );
    return 0;
}



ウィンドウでました!


stb
ライセンス:Public Domain
種類:画像読み書き、フォント、その他
使いやすさ:★★
ビルド難易度:

PublicDomainのヘッダオンリーライブラリです。
普通はlibpng/libjpegなどを使うと思いますが、なんとこのライブラリはヘッダ内でzip解凍みたいなこともやってて、pngが読めてしまいます!
jpgはプログレッシブ読めなかったり、pngもフォーマットによっては読めない場合があるので注意しましょう。
書き出しも出来るので、レイトレ結果の書き出しに使うとよいです。

ちなみに、このページの右上に作者が居ますが、いつか(このライブラリが原因でアプリが)落ちたりするんじゃいかとハラハラしますね…

#define STB_IMAGE_WRITE_IMPLEMENTATION
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stb_image.h>
#include <stb_image_write.h>

int main(int argc, char** argv)
{
    /// 画像の書き出しサンプル.
    const int w = 256;
    const int h = 256;
    std::vector<unsigned char> image_buffer(w * h * 4);
    for (int y = 0; y < h; ++y)
    {
        for (int x = 0; x < w; ++x)
        {
            int pos = (y*w+x) * 4;
            image_buffer[pos + 0] = x;
            image_buffer[pos + 1] = y;
            image_buffer[pos + 2] = 0xFF;
            image_buffer[pos + 3] = 0xFF;
        }
    }
    stbi_write_png("out.png", w, h, STBI_rgb_alpha, &(*image_buffer.begin()), 0);
    return 0;
}



画像書き出せました!



ilmbase

ライセンス:3-clause BSD license
種類:数学ライブラリ
使いやすさ:
ビルド難易度:★☆

VFXスタジオ ILM(インダストリアルライト&マジック)のライブラリで、主に数学ライブラリが含まれています。
前回のレイトレ合宿では、数学計算まで自作しないといけなかったので面倒でしたが、今回はもう再生産する必要はありません!
クオータニオンや行列計算はもちろん、行列の分解、カメラのFrustum、プレーンや三角形の交差判定まで含まれています。
最近ゲームで使用されているらしい、half float用の計算も行えます。

上のstbのサンプルを少し改造してレイトレしましょう。追加部分を太字にしています。
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stb_image.h>
#include <stb_image_write.h>

#include <Imath/ImathVec.h>
#include <Imath/ImathLine.h>
#include <Imath/ImathLineAlgo.h>

int main(int argc, char** argv)
{
    const int w = 256;
    const int h = 256;

    // 三角形.
    struct Triangle {
        Imath::V3d p0;
        Imath::V3d p1;
        Imath::V3d p2;
    } triangle;
    triangle.p0 = Imath::V3d(128, 50, -10);
    triangle.p1 = Imath::V3d(50, 200, -10);
    triangle.p2 = Imath::V3d(200, 200, -10);

    // 画像真ん中の後ろのほうをposとした適当なレイを作る.
    Imath::Line3d ray;
    ray.pos = Imath::V3d(w / 2.0, h / 2.0, 100);

    std::vector<unsigned char> image_buffer(w * h * 4);
    for (int y = 0; y < h; ++y)
    {
        for (int x = 0; x < w; ++x)
        {
            int pos = (y*w + x) * 4;
            image_buffer[pos + 0] = x;
            image_buffer[pos + 1] = y;
            image_buffer[pos + 2] = 0xFF;
            image_buffer[pos + 3] = 0xFF;

            // レイの方向.
            ray.dir = Imath::V3d(x, y, 0) - ray.pos;

            // 三角形とレイの交差判定.
            Imath::V3d hit_point;
            Imath::V3d barycentric;
            bool is_front = false;
            if (Imath::intersect(ray, triangle.p0, triangle.p1, triangle.p2, hit_point, barycentric, is_front))
            {
                if (is_front)
                {
                    // レイが三角形前面に当たった.
                    image_buffer[pos + 0] = static_cast<unsigned char>(barycentric.x * 0xFF);
                    image_buffer[pos + 1] = static_cast<unsigned char>(barycentric.y * 0xFF);
                    image_buffer[pos + 2] = static_cast<unsigned char>(barycentric.z * 0xFF);
                    image_buffer[pos + 3] = 0xFF;
                }
            }
        }
    }
    stbi_write_png("out.png", w, h, STBI_rgb_alpha, &(*image_buffer.begin()), 0);
    return 0;
}


レイトレで三角形をレンダリングできました!

ちなみに、三角形の色は重心座標( barycentric ) を可視化したものにしています。
次回のサンプルでは、barycentric という名前は大変長いので、uvwなどという適当な名前にすることにします。


tinyobjloader
ライセンス: 2-clause BSD license
種類: ジオメトリ、フォーマット
使いやすさ
ビルド難易度:★☆☆

アニメーションなしのジオメトリデータで、様々なソフトで読み込めるフォーマットといえば、Wavefront-OBJフォーマットです。
こちらはそのOBJ形式を手軽に読み込みできるライブラリです。
使い方は凄く簡単なのですが、結構読み込めない場合があるので、修正しながら使いましょう。
とりあえず176行目付近のコード↓はコメントアウトしましょう。これが有効だと読み込み時に同じようにキャッシュしながら読まないといけなくなります。
  if (it != vertexCache.end()) {
    // found cache
    return it->second;
  }

さて、それでは使ってみます。これも前回のコードに付け加えてレイトレしましょう。
コマンドライン引数でobjファイルを指定して、読み込みます。
折角だから法線も読み込んで、ライティングもしちゃいましょう!

今回はちょっと量が多いので、tinyobjloaderを使ってる部分だけ太字にしています。

#define STB_IMAGE_WRITE_IMPLEMENTATION
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stb_image.h>
#include <stb_image_write.h>

#include <Imath/ImathVec.h>
#include <Imath/ImathLine.h>
#include <Imath/ImathLineAlgo.h>

#include <tiny_obj_loader.h>

int main(int argc, char** argv)
{
    if (argc <= 1) { return 0; }

    const int w = 256;
    const int h = 256;

    // 画像真ん中の後ろのほうをposとした適当なレイを作る.
    Imath::Line3d ray;
    ray.pos = Imath::V3d(w / 2.0, h / 2.0, 100);
    
    // 三角形.
    struct Triangle {
        Imath::V3d p0;
        Imath::V3d p1;
        Imath::V3d p2;
        Imath::V3d n0;
        Imath::V3d n1;
        Imath::V3d n2;
    };

    // OBJファイルの読み込み
    std::vector<tinyobj::shape_t> shapes;
    std::string err = tinyobj::LoadObj(shapes, argv[1]);
    if (!err.empty()) {
        std::cerr << err << std::endl;
        exit(1);
    }

    // OBJファイルから三角形リストを読み込む.
    // カメラが適当なので、適当にスケールかけます.
    // 画像はy座標が下向きなので、モデルのy座標を反転します.
    const Imath::V3f scale(100.0, -100.0, 100.0);
    // 三角形リスト.
    std::vector<Triangle> triangles;
    for (size_t i = 0; i < shapes.size(); i++) 
    {
        const size_t face_count = shapes[i].mesh.indices.size() / 3;
        for (size_t f = 0; f < face_count; f++)
        {
            const int vi0 = shapes[i].mesh.indices[f*3+0];
            const int vi1 = shapes[i].mesh.indices[f*3+1];
            const int vi2 = shapes[i].mesh.indices[f*3+2];
            Triangle tri;
            // 頂点.
            {
                std::vector<float>& mp = shapes[i].mesh.positions;
                tri.p0 = Imath::V3d(mp[vi0 * 3 + 0], mp[vi0 * 3 + 1], mp[vi0 * 3 + 2]) * scale;
                tri.p1 = Imath::V3d(mp[vi1 * 3 + 0], mp[vi1 * 3 + 1], mp[vi1 * 3 + 2]) * scale;
                tri.p2 = Imath::V3d(mp[vi2 * 3 + 0], mp[vi2 * 3 + 1], mp[vi2 * 3 + 2]) * scale;
            }
            // 法線.
            if (!shapes[i].mesh.normals.empty())
            {
                std::vector<float>& mn = shapes[i].mesh.normals;
                tri.n0 = Imath::V3d(mn[vi0 * 3 + 0], mn[vi0 * 3 + 1], mn[vi0 * 3 + 2]);
                tri.n1 = Imath::V3d(mn[vi1 * 3 + 0], mn[vi1 * 3 + 1], mn[vi1 * 3 + 2]);
                tri.n2 = Imath::V3d(mn[vi2 * 3 + 0], mn[vi2 * 3 + 1], mn[vi2 * 3 + 2]);
            }
            triangles.push_back(tri);
        }
    }

    std::vector<unsigned char> image_buffer(w * h * 4);
    for (int y = 0; y < h; ++y)
    {
        for (int x = 0; x < w; ++x)
        {
            int pos = (y*w + x) * 4;
            image_buffer[pos + 0] = x;
            image_buffer[pos + 1] = y;
            image_buffer[pos + 2] = 0xFF;
            image_buffer[pos + 3] = 0xFF;

            // レイの方向.
            ray.dir = Imath::V3d(x, y, 0) - ray.pos;
            // レイが当たったかどうか.
            bool is_hit = false;
            // 一番近くの当たった点までの距離.
            double closest_distance = std::numeric_limits<double>::max();
            // 一番近くの当たった点の法線.
            Imath::V3d closest_normal;

            for (size_t t = 0; t < triangles.size(); ++t)
            {
                Triangle& triangle = triangles[t];

                // 三角形とレイの交差判定.
                Imath::V3d hit_point;
                Imath::V3d uvw;
                bool is_front = false;
                if (Imath::intersect(ray, triangle.p0, triangle.p1, triangle.p2, hit_point, uvw, is_front))
                {
                    if (is_front)
                    {
                        is_hit = true;
                        // 前当たったとこより近いかどうか記憶しておく.
                        const double distance = (hit_point - ray.pos).length();
                        if (closest_distance > distance)
                        {
                            closest_distance = distance;
                            closest_normal = (triangle.n0*uvw.x + triangle.n1*uvw.y + triangle.n2*uvw.z).normalized();
                        }
                    }
                }
            }

            if (is_hit)
            {
                // レイが三角形に当たった.
                Imath::V3d light(1, 1, 1);
                double nl = std::max(0.0, closest_normal.dot(light.normalized()));
                image_buffer[pos + 0] = static_cast<unsigned char>(nl * 0xFF);
                image_buffer[pos + 1] = static_cast<unsigned char>(nl * 0xFF);
                image_buffer[pos + 2] = static_cast<unsigned char>(nl * 0xFF);
                image_buffer[pos + 3] = 0xFF;
            }
        }
    }
    stbi_write_png("out.png", w, h, STBI_rgb_alpha, &(*image_buffer.begin()), 0);
    return 0;
}

元データ

サンプル実行結果

OBJファイルを読み込んでレイトレできました!

ここで、objは関係ないですが、レイが当たったところの法線を求めるのに、
3つの頂点法線に重心座標を掛けて足すところがポイントです。
closest_normal = (triangle.n0*uvw.x + triangle.n1*uvw.y + triangle.n2*uvw.z).normalized();
同じように頂点UVや頂点カラーに重心座標を掛けて足せば、それぞれの値を求めることが出来ます…!





さて、今までのサンプルは、こちら!

ちなみにビルドの通し方ですが、こんな勢いでライブラリ使いまくってるので、ライブラリはgithubに入れていません。
VC2012のソリューションとプロジェクトもアップしてるので、GoogleDriveから上記で紹介したものを拾ってきて
ソリューションファイルとどう階層に"lib"フォルダを作って、その中に解凍するとビルド通ると思います。

そして、ここまで書いて満足してしまったので、あとはサンプルコードがちょっとしか出てきません!!!
後は自力でがんばってください。
それでは、Happy Rendering !





OpenEXR

ライセンス:3-clause BSD license
種類:画像ライブラリ
使いやすさ:
ビルド難易度:★★
依存ライブラリ: ilmbase

VFXスタジオ ILM(インダストリアルライト&マジック)のHDR画像フォーマット、".exr"形式を扱えるライブラリです。
IBLを行う場合は、このフォーマットか、".hdr"形式の画像をしようすることが多いので、そういうのやる人は是非!
".exr"は複数の画像バッファを1ファイルに格納できる優秀なフォーマットで、最近では深度情報まで持った画像フォーマットDeepImageに対応しています。
Pixarなどは、テクスチャをほとんどexrで扱っているようです。
なお、ビルドには、上記のilmbaseが必要です。

OpenImageIO(OIIO)

ライセンス:3-clause BSD license
種類:画像ライブラリ
使いやすさ:
ビルド難易度:★★
依存ライブラリ: boost、ilmbase、openexr、libpng、libtiff、libjpeg、zlib

大量のフォーマットに対応したVFX向け画像ライブラリです。汎用画像だけでなく、Field3D(ボクセル)や、Ptex(3Dペイント用フォーマット)にも対応しています。
ミップマップなどもサポートしており、説明文だけ見ると非常に良いのですが、Windowsでのビルドが大変難しいです。
今回ビルドに成功しましたが、画像ロード時に若干リークしたりするので、修正する覚悟が必要です。
具体的にはlibpngを使用した基本的なpng読み込みでリークを確認しました。

対応フォーマット:
TIFF, JPEG/JFIF, OpenEXR, PNG, HDR/RGBE, ICO, BMP, Targa, JPEG-2000, RMan Zfile, FITS, DDS, Softimage PIC, PNM, 
DPX, Cineon, IFF, Field3D, Ptex, Photoshop PSD, Wavefront RLA, SGI, WebP, GIF, and a variety of "RAW" digital camera formats.

DevIL

ライセンス:LGPL
種類:画像ライブラリ
使いやすさ:★★★★☆
ビルド難易度:

大量のフォーマットに対応したOpenGL向け画像ライブラリです。
ライセンスがLGPLなので、静的リンクで使用すると、ほとんどの場合でソースコードの公開義務が発生します。
ソースを全く未変更でDLLとして使用するならソースは公開しなくてもOK。
結構前からほとんど更新されていなかったのですが、
最近フォークされてResIL (http://sourceforge.net/projects/resil/) というプロジェクトで改良されているようです。

対応フォーマット:

OpenShadingLanguage(OSL)

ライセンス:3-clause BSD license
種類:シェーディング言語、コンパイラ
使いやすさ:
ビルド難易度:
依存ライブラリ:OpenImageIOとその依存ライブラリ、LLVM+clang、flex-bison

RendermanShaingLanguageのような、オフラインレンダリング向けシェーディング言語の
コンパイラと、それを組み込むための仕組みが含まれています。
Blenderに搭載されているので、シェーディング言語自体は、気軽に試すことが出来ます。
しかし、使うに当たっては、OpenImageIOの作者と同じ人がメンテしているため、OSLのヘッダーの中でOIIOのヘッダーをインクルードしていたり、
boost waveを使用していますが、boost wave内で静的にリークしていたり、LLVMを使用していますが、これまたリークしてたりします。
またLLVMに依存するので、リンクライブラリ数が膨大になり、管理が大変です。

参考: 自作プログラムへの組み込みの先駆者がいました。素晴らしい…!→ http://osl.wikidot.com/

OpenSubdiv
ライセンス:Modified Apache 2.0 License
種類:ジオメトリ
使いやすさ:★★☆☆
ビルド難易度:★★☆☆

CG界のディズニーであるピクサーが、そろそろ特許切れるからか公開したSubdivisionのライブラリです。
特許の部分である、Semi-Sharp Crease をはじめとして、
なかなか作るのが難しいhalf-edgeのデータ構造が実装されていたり、
各種プラットフォームで使えて、しかも速いし、DCCツールが次々と対応して来ているため、
今後の標準になるのは間違い無さそうです。


Ptex
ライセンス:3-clause BSD license
種類:画像(?)フォーマット
使いやすさ:★☆☆
ビルド難易度:★

こちらもピクサーのライブラリです。普通テクスチャマッピングといえばUVマッピングですが、
頂点単位でUV座標を自動で割り当てて、独自形式の画像データに落とし込めば
UVフリーでテクスチャをマッピングすることができます。
さらに、通常このような手法を行った場合、カメラからの距離によっては汚くなったりするらしいですが、
それについても3Dテクスチャを使ってミップマップのようなことをやり、回避しているようです。
商用レンダラーでは、OpenSubdiv + Ptex にいち早く対応してきていますが、
Ptexを作れるソフトがまだ余りないので、もう少し対応ソフトが出てきてほしいところです。

Alembic
ライセンス:3-clause BSD license
種類:ジオメトリ、フォーマット
使いやすさ:★☆☆
ビルド難易度:★
依存ライブラリ: boost、ilmbase、hdf5、zlib
構成によって依存: szip、python、glew、glut

こちらはSonyPicturesImageWorksとLucasfilm Ltd.共同開発の、ジオメトリキャッシュフォーマットです。
複雑なリグを移植するのは不可能に近いため、アニメーションしているジオメトリを効率よくファイルに書き出してくれます。
物理演算などを行っていた場合でも全フレーム書き出してしまえば、どのソフトでも編集できるというわけです。
上記ピクサー社の2ライブラリと並んで、普及してほしいところです。
データは、メッシュに限らず、カメラやライト、パーティクルも扱える他、nurbsもいけます。
マテリアルも扱えるのですが、OBJファイルのように共通の設定はなく、対応しているアプリ(prmanかarnold?)の独自マテリアルを入れていくようです。
ただ、boostに依存しているほか、ヘッダ部分の依存も中々切り辛くて、扱いにくいのが難点…ビルドも難しいです。

参考: 基本的にSimpleAbcViewerで読めるものが正式なabcと信じて、
         アニメーションも扱っているのですが、キーフレームに相当する、
         TimeSampling周りの作法がバージョンごとに結構変わっててややこしいです。

FBXSDK
ライセンス: Autodesk独自 (無料で使えるけど、SDKの再配布不可、使用許諾の表示が必要、使ってるソフトのライセンス体系縛りあり)
種類: ジオメトリ、フォーマット
使いやすさ:★
ビルド難易度:---- (ビルド済み)

Autodeskに買収されたAlias社が作ったフォーマットである、FBX形式のファイルの読み書きが出来るライブラリです。
でも実は他の形式にも結構対応していて、OBJ、3ds、COLLADA(dae)の読み込みや、
各種モーションキャプチャデータを読み込めます。
さらに最新バージョンで上記Alembic形式の読み込みに対応しました。
読み込んだ後は全てFBXSDKのAPIでラップされているので、特別なヘッダを読み込む必要がないし、依存関係の管理が大変楽です。

ただし、ソースコードが非公開なので、うまく動かない場合や、APIドキュメントが古くて間違っていることがあります。
その場合はフォーラムか何かでAutodeskに問い合わせない限り直りません。
APIドキュメントのプラットフォーム要求が以前古いままの記載で、それによって問題に遭遇したことがあり、
ためしにドキュメントの下の報告ボタンからAutodeskに怒りのコメントを送ったところ、
次のバージョンで修正されていました。

参考:FBX2011~FBX2015までのスケルトン入りメッシュの読み込みコードは
      こんな感じです。

openNURBS
ライセンス:MIT
種類:ジオメトリ、フォーマット
使いやすさ:未使用のため不明(ただしコードかなり良さそう)
ビルド難易度:★

Rhinoceros開発元が作っている、openNURBSというフォーマットを書き出せるライブラリのようです。
フォーマットはどうでもいいんですが、ソース中のジオメトリの説明が物凄く詳細に書いてあって、
設計もしっかりしているように見えるし、参考になります。
なにより企業がやってるのにライセンスがゆるくて、
商用利用推奨、テクニカルサポートまであるようで、好感が持てます。

OpenVDB
ライセンス:Mozilla Public License Version 2.0
種類:シェーディング言語、コンパイラ
使いやすさ:不明
ビルド難易度:不明

DreamWorksが作ったボリュームデータ用ライブラリです。
ライセンスがMPL2ということで、若干注意が必要です。変更した部分は公開必須になります。
最近では全てのライブラリを吸収していく最強ソフト houdini に導入されて、徐々に使用例が増えてきました。

Field3D
ライセンス:3-clause BSD license
種類:ボクセルフォーマット
使いやすさ:未使用のため不明
ビルド難易度:★★★☆
依存ライブラリ: boost、ilmbase、hdf5

SonyPicturesImageWorks開発の、ボクセルフォーマットのライブラリです。
なかなかレアなライブラリなので、ボクセル扱うなら必須かもしれません。
ドキュメントもしっかりしているように見えましたが、ソースの更新頻度低めです。
ビルドはインクルードパスの指定にちょっとクセがあります。この会社のコード、全部こうなんですかね…。

参考:使い方は、Production Volume Rendering: Design and Implementation という書籍に載っています。
    この書籍では、boost.pythonやopenexrも使っているようです

OpenFX(OFX)
ライセンス:3-clause BSD license
種類:2Dフィルタープラグイン、ランタイム
使いやすさ:不明
ビルド難易度:不明

同名の3Dアプリがあり、紛らわしいですが、これはVFXの2Dポストエフェクト用プラグインの共通ライブラリです。
これに対応すれば、画像/動画に対する2Dフィルターなどのプラグインを、他のアプリと共通で使えるようになります。
AfterEffectsのプラグイン形式"aex"を意識していると思われます。
ちょっと古い感じのコードで(偏見)、導入例少な目ですが、オープンソースの対応アプリケーションが増えてきたので、
今後発展していく可能性があります。

Boost.Python
ライセンス:Boost Software License
種類:多言語連携
使いやすさ:★★☆
ビルド難易度:★★

boostライブラリの中でも、CG関係で最も特筆すべきは、Boost.Pythonです。
現在Mayaを初めとした、各種DCCツールが、続々とPythonスクリプトに対応してきていますが、
このライブラリを使用すると、C++とPythonを強力に連携させることができます。
たとえば、C++の既存コードをPython用DLLとして出力し、Pythonからimportして使えるようにしたり、Python用クラスをC++で書けます。
さらに、C++からPythonスクリプトを実行できたり、実行したPythonスクリプトの中でBoost.PythonバインドされたC++関数使用できたりします。
これを使えば、C++の資産を各種DCCツールから扱えるため、DCCソフト専用の書き捨てコードを量産する必要が少なくなります。
難点としては、マルチプラットフォーム対応をC++側で行わないといけない点です。

参考: boost pythonのドキュメントを日本訳してくださってる方が居ます。素晴らしい…! → http://alpha.sourceforge.jp/devel/
    テンプレートライブラリのため、書き方が結構特殊です。C++既存コードをPython用DLLとして出力する例(自作

Snappy
ライセンス:3-clause BSD license
種類:圧縮
使いやすさ:★★★☆☆
ビルド難易度:★

CG関係ないですが、お気に入りの高速圧縮ライブラリです。ZIPより少し圧縮率が悪いですが、大変高速に圧縮/解凍を行えるため、
snappyを通じてディスクにコピーしたほうが普通にOSの機能でコピーするより早いです。(CPUパワーは食います)



Comments