2011年10月25日

OptiXのSample6について

FFTもまだ色々できそうでしたが、OptiXに戻ってきました。

Sample6は、以下のような内容です。(by NVIDIA-OptiX-SDK-samples.html)

OBJメッシュファイルを読み込んでレンダリングします。シーンカメラでインタラクションできます。
機能:
・インタラクティブカメラ(回転、パン、ズーム)sutilのGLUTDisplayクラス使ってます。
・sutilのOBJLoaderクラスを使って外部モデルを読み込んでいます。
・プログレッシブなアンビエントオクルージョンシェーディングできます。

というわけで、sutilをいじってPMDファイルを読み込めるようにしてみました。
テクスチャとかはまだですが、頂点と法線は読み込めました。

実行結果

アンビエントオクルージョンシェーディングの結果です。隙間など閉鎖領域が黒くなるそうです。
プログレッシブなので段階的に変わっていきます。

OptiX_test_002.png

一度ノーマルシェーダ(SM_NORMAL)でキャッシュを作ってからSM_AOにしないと重くてグラボが停止してしまいました。SM_ONE_BOUNCE_DIFFUSEはキャッシュを作っても無理でした。グラボの性能不足でしょうか。

せっかくFFTを試したことですし次回は水面のレイトレーシングとかやってみたいですね。GPUでFFTとレイトレーシング両方は厳しそうですかね・・・。
web拍手 by FC2
posted by シンドラー at 21:44 | Comment(0) | TrackBack(0) | OptiX | このブログの読者になる | 更新情報をチェックする

2011年09月14日

OptiXのTutorial0について その2

昨日の続きでTutorial 0です。

Tutorial 0では、sutilのSampleSceneというクラスを継承して色々やっています。
sutilは恐らくOptiXを使いやすくするための補助ライブラリだと思いますので、これを使ってプログラムを作成していきたいと思います。

先日作成したテストプログラムで、SampleSceneを継承したTutorialクラスを作成します。

SDKのtutorial.cppを参照しながら、必要そうなヘッダやメンバをコピペしていきます。

ビルドすると"optixu_math_namespace.h"をWindowsで使うならNOMINMAXを定義してくださいというようなエラーがでましたので、チュートリアルのプロジェクトのプロパティを参考に、以下のプリプロセッサを追加しました。
C/C++→プリプロセッサ→プリプロセッサの定義
_USE_MATH_DEFINES,NOMINMAX,GLEW_BUILD,GLUT_FOUND,GLUT_NO_LIB_PRAGMA

SDK\tutorialフォルダのcommonStructs.hと*.cuをプロジェクトのフォルダにコピーします。

後は同様に色々コピペして書き換えを行えばコンパイルは通るようになります。

で、実行はできたのですが、.cuのファイルをコンパイルしていない気がしました。
確認してみると、SDKの.ptxを読み込んでいるだけで、自分で作成した.cuは全く使っていない状態でした。

OptiXのプログラムは、レイを飛ばすプログラムなどは.cuのファイルで書いて、それをコンパイルして.ptxというものに変換して、それを実行時に読込んでレイ生成プログラムなどを作っているようです。

この.cuを.ptxに変換する方法ですが、OptiXのSDKはCMakeを使用しているようでしたので、カスタムビルド規約を用いる方法を試してみました。

カスタムビルド規約を自分で作成するのは面倒ですので、CUDA VS Wizardを使用しています。
http://sourceforge.net/projects/cudavswizard/
もしかするとGPU Computing SDKをインストールしたときのRulesかもしれません。
色々適当に入れているので分からなくなってきました。(修正2011.9.27)

プロジェクトを右クリック→カスタムビルド規約→CUDA Build Rule v2.3.0にチェックを入れます。

これで.cuファイルもビルド時にビルドされるようになります。

次に.cuをビルドする時のプロパティを設定します。

プロジェクト→プロパティを開くと、CUDA Build Rule v2.3.0というものが追加されています。
GeneralのところのAdditional Include DirectriesにC/C++の追加のインクルードディレクトリの内容をコピペします。
NVCC Compilation TypeをGenerate .ptx file (-ptx)に変更します。これで.ptxファイルが生成されるようになります。
Compiler Output(obj/cubin)は出力ファイル名ですので、"data/$(InputName).ptx"とすると、dataフォルダにptxファイルが出力されます。
GPU Architectureですが、sm_11にすると大丈夫でした。(sm_13だと実行時にエラーがでました)

設定例

OptiX_test_000.png

これでコンパイルすれば.ptxファイルができていますので、プログラムからこの.ptxファイルを読み込むように修正すれば実行できるようになります。
(チュートリアルでは$(OptiX_HOME)\build\lib\ptxにある.ptxを読み込むようになっていたので、そこに作成したtutorial0.ptxをコピーして読み込むようにしました。)

毎回コピーするのも面倒ですので、プロパティ→ビルドイベント→ビルド後のイベント→コマンドラインで下記のようにビルドが終わった段階でSDKのフォルダにコピーするようにしました。(追記2011.9.27)

copy data\tutorial0.ptx "$(OPTIX_HOME)\build\lib\ptx\tutorial0.ptx"

実行結果

OptiX_test_001.png

以下ソース

OptiX_Test_t0.zip

web拍手 by FC2
posted by シンドラー at 18:07 | Comment(3) | TrackBack(0) | OptiX | このブログの読者になる | 更新情報をチェックする

2011年09月13日

OptiXのTutorial0について

以下インストールディレクトリのdocフォルダのOptiX_Quickstart_Guide_2.1.1.pdfの適当訳です。
間違ってたりわからないので飛ばしてたりするかもしれません。
OptiX_Programming_Guide_2.1.1.pdfとかもあります。

そういえばOptiXは一応ユーザ登録しないとダウンロードできないので、日本語訳とはいえチュートリアルをWebで公開したらまずいんでしょうか。
まずそうだったら教えてください。

p.1から

OptiX SDKは、どのようにいくつかの基本的なレイトレーシング効果を実装するのかについてのソースコードサンプルとチュートリアルを提供します。
チュートリアルは、シンプルなものから複雑なものまで11個のステージを含んでおり、それぞれのステージで新しいエフェクトを追加します。
このセクションでは、私たちはこれらのステージのそれぞれについて議論し、シェーディングと交差の両方のプログラムをお見せします。

このチュートリアルは、CUDA Cプログラミングメカニズムにフォーカスを当てており、オブジェクトのセットアップにどのようにホストAPIを使用するのかについては記述していません。
CUDA CとホストAPIの両方の完全なソースコードは、SDKに含まれています。
このチュートリアルは、OptiXを開始することだけを目的としており、ビジットプログラムやアクセラレーション構造は他のSDKサンプルで見つかります。
OptiXによるさらに進んだレンダリングテクニックや科学計算についてはここではカバーしていません。

1.1. Tutorial 0 - ノーマルシェーダ

OptiXの最も一般的なプログラムの種類は「最も近いヒットのプログラム」です。
OptiXが実行される時はいつも、レイとオブジェクト間の最も近い交差点を見つけます。
最も近いヒットのプログラムの基本的な目的は、交差した点の色を決定することです。
ユーザは、複数の最も近いヒットのプログラムを作成することができて、シーン内のそれぞれのオブジェクトにバインドすることができます。
そのため、違うオブジェクトは違う外観を持つかもしれません。
このチュートリアルでは、私たちはシーン内のそれぞれのオブジェクトにひとつの単純な最も近いヒットプログラムをバインドします。
このプログラムは「ノーマルシェーダ」です。このプログラムは、オブジェクトの法線をワールド空間とスケールに使っているので、それぞれのコンポーネントは0から1の間に収まります。
結果の(x,y,z)ベクトルは、色として直接補間され、レイに関連付けられたペイロードに預けられます。

(payloadって何ですかね。コンテナみたいなものなんでしょうか)

RT_PROGRAM void closest_hit_radiance0()
{
    prd_radiance.result = normalize(rtTransformNormal(
        RT_OBJECT_TO_WORLD,
        shading_normal))
        *0.5f+0.5f;
}

このプログラムは、shading_normalと名付けられた変数を参照しています。
箱と床のための交差プログラム(ここでは示していません、SDKのコードを参照してください)は、交差が見つかった時に、この変数を両方計算します。
この変数は、複数のプログラム間で共有されることになるため、次のような特別な方法で宣言する必要があります:

rtDeclareVariable(float3,
    shading_normal,
    attribute shading_normal, );

結果の色は、もうひとつのprd_radianceと呼ばれる変数に書き込まれます。
これは、それぞれのレイと関連付けられた、データを運ぶためのユーザが定義した構造体のインスタンスです。
このケースでは、私たちはresultと呼ばれる構造体の一部にfloat3型の色情報を書き込んでいます。
この構造体の他の二つの要素についての詳細な情報は、後でお見せします。

struct PerRayData_radiance
{
    float3 result;
    float importance;
    int depth;
};
rtDeclareVariable(PerRayData_radiance,
        prd_radiance, rtPayload, );

ここでは変数名にshading_normalとprd_radianceとつけているぐらいで特別なことは特にありません。
rtDeclareVariableマクロに渡されている「セマンティック名」と呼ばれる三番目の引数は、それらの変数を正しい場所にバインドするために使われます。
ここでは、セマンティック名としてrtPayloadを使用することで、OptiXは、このデータ構造体はそれぞれ個別のレイに関連付けられるべきだと知ることができます。
レイペイロードの一部である"result"は、下の別のプログラムのレイトレーサの出力にコピーされます。

最も近いヒットのプログラムに加えて、私たちは、「ミスプログラム」を指定する必要があります。
ミスプログラムは、レイがどのオブジェクトとも交差しなかった時に実行されます。
このケースでは、私たちは結果の色にユーザが指定した値「bg_color」をただセットします。

rtDeclareVariable(float3, bg_color, , );

RT_PROGRAM void miss()
{
    prd_radiance.result = bg_color;
}

「bg_color」の値はホストによって設定され、レイトレーサの異なる起動間で修正することができます。
これは、ホストとOptiXプログラム間でやり取りするための最も基本的なメカニズムです。
OptiXはこれらの変数のための継承モデルも提供していますが、このチュートリアルではそれらの詳細については議論しません。

レイ自身を作るために、私たちはピンホールカメラモデルを使用します。
「レイ生成プログラム」はレイの生成、シーンへの射出、そして結果色の「出力バッファ」へのコピーに関与します。
出力バッファは、その後ホストによる次の解析やOpenGLによるレンダリングに使われます。
OptiXは、出力バッファの任意の数に書き込むことができ、これらのバッファは任意の型を持つことができます。
このチュートリアルでは、ひとつの出力バッファは、2次元のRGBA8画像で、OpenGLのテクスチャとして効果的に転送できるように設計されています。

ヘルパ関数である「make_color」(ここでは示していません)は、浮動小数点型のRGBカラーをRGBA8整数型に、適切に必要に応じてスケーリングやクランプを行って変換します。

RT_PROGRAM void pinhole_camera() 
{
    size_t2 screen = output_buffer.size();

    float2 d = make_float2(launch_index) /
        make_float2(screen) * 2.f - 1.f;
    float3 ray_origin = eye;
    float3 ray_direction = normalize(d.x*U + d.y*V + W);

    optix::Ray ray(ray_origin, ray_direction,
        radiance_ray_type, scene_epsilon );
    PerRayData_radiance prd;
    prd.importance = 1.f;
    prd.depth = 0;

    rtTrace(top_object, ray, prd);

    output_buffer[launch_index] = make_color( prd.result );
}

このプログラムで最も重要な部分は、「rtTrace」を呼んでいるところです。
この関数には3つの引数があります:

  • 1. シーンを表現するオブジェクトの階層のルートです。この階層はホストが先にレイトレーサを起動することによって作成されます。

  • 2. ピンホールカメラの視錐台のシミュレーションを上のベクトル数学を使用して計算したレイです。

  • 3. それぞれのレイに関連付けられたデータ構造を持つローカル変数への参照。「prd_radiance」変数(上に示した)は、「rtPayload」セマンティックとして宣言されているので、このローカル変数は、全ての他のOptiXプログラムで「prd_radiance」としてバインドされています。

もしレイがオブジェクトに当たったのならば、最も近いヒットプログラムは、「result」メンバにノーマル色を設定し、もしどのオブジェクトにもヒットしなければ、ミスプログラムが背景色を「result」に設定します。
レイが完全にトレースされれば、コントロールはカメラプログラムに返され、私たちは出力バッファに色を預けます。

一つの最後の注意:OptiXは交差とシェーディングの両方の再帰をサポートしているので、ローカルスタックは状態を維持するために使用されます。
もしスタックが十分に大きくないと、オーバーフローを起こします。
もしこれが起これば、現在のレイ生成プログラムのための全ての処理は、アボートされ、「例外プログラム」が実行されます。
このチュートリアルでは、私たちは出力バッファに(ホストによって設定された)特殊な色を設定し、ユーザにこれが起こったことを知らせるだけです。

rtDeclareVariable(float3, bad_color, , );

RT_PROGRAM void exception()
{
output_buffer[launch_index] = make_color( bad_color );
}

チュートリアルプログラムを実行すると、上に示したような画像を得ることができます。
これらのそれぞれのプログラムは、OptiXによって1秒間に数百万回実行さて、インタラクティブに画像を生成します。
これから私たちは、これらの基本的なレンダリングを、よりリアリスティックで複雑な画像に作り変えていきます。

p.5まで

昨日のサンプルをチュートリアルを参考に書き換えようかと思いましたが、チュートリアルはサンプル用のクラスを継承してて全体像がわかりにくい気がしますね。
Sample2なども合わせて確認しながら試していきたいと思います。

web拍手 by FC2
posted by シンドラー at 19:19 | Comment(0) | TrackBack(0) | OptiX | このブログの読者になる | 更新情報をチェックする

2011年09月12日

OptiXのSample1について

OptiXの日本語情報ほとんど見当たりませんね。あまり需要ないんですかね。

OptiXのチュートリアルを少しやってみようと思います。今回はその準備です。
このPCが64ビットOSなので64ビットのやり方です。

0. 環境変数の設定

以下の環境変数を追加しました。
OPTIX_HOME
C:\Program Files\NVIDIA Corporation\OptiX SDK 2.1.1
以下の環境変数はCUDAインストール時に追加されているかもしれません。
CUDA_PATH
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.0\

1. プロジェクト作成

新規作成→プロジェクトでWin32 コンソールアプリケーションを作成
ビルド→構成マネージャでアクティブソリューションプラットフォームを新規作成→x64に

2. プロパティ設定

2.1. プロジェクト→プロパティ→C++→追加のインクルードディレクトリに以下を追加

$(OPTIX_HOME)\include;
$(OPTIX_HOME)\SDK\sutil;
$(OPTIX_HOME)\include\optixu;
$(OPTIX_HOME)\build;
$(CUDA_PATH)\include;

2.2. プロジェクト→プロパティ→リンカ→全般→追加のライブラリディレクトリ
$(OPTIX_HOME)\build\lib\Release;
$(OPTIX_HOME)\lib64;
$(CUDA_PATH)\lib\x64;
$(OPTIX_HOME)\SDK\support\freeglut\win64\Release;

2.3. プロジェクト→プロパティ→リンカ→追加の依存ファイル
glu32.lib opengl32.lib sutil.lib optix.1.lib cuda.lib optixu.1.lib freeglut.lib

3. メインプログラム作成

sample1.cの内容をmain関数にコピーしてコマンドラインからの入力辺りを修正/コメント追加

4. CUDA?部分のプログラム作成

プロジェクトを右クリック→追加→新しいフィルタでCUDA Filesというフィルタを作成
CUDA Filesを右クリック→追加→新しい項目でdraw_color.cuというファイルを作成
sample1のdraw_color.cuをコピペ

5. 実行するために作業ディレクトリにdllがある場所を設定

プロジェクト→プロパティ→デバッグ→作業ディレクトリ
$(OPTIX_HOME)\build\bin\Release

6. コンパイル/実行すると上記のフォルダに緑っぽいPPMファイルが生成されます。

GIMPをインストールしていたので一応見れましたが、PPMって良く使われるフォーマットなんでしょうか。
このSample1を元にチュートリアルを見ながら色々追加していきたいと思います。時間があれば。

今回のプロジェクトファイル一式。

OptiX_Test_v0.zip
web拍手 by FC2
posted by シンドラー at 18:55 | Comment(2) | TrackBack(0) | OptiX | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。