• 追加された行はこの色です。
  • 削除された行はこの色です。
*エフェクト-SSAO [#w0f74216]
Screen Space Ambient Occlusion。
スクリーンスペースで遮蔽計算を行う。

以下のロジックはまだ綺麗に出来ていないので改善点はあります。
----

#contents



** 参考サイト [#uc2f1cfa]
床井研究所
床井研究室
 http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20101122
 

** 計算 [#y3346a68]
***サンプル点の計算。 [#l4e131aa]
今回はランダムサンプル。計算式は床井研究室さん参考。
ここで計算した数値を、Uniformで2パス目のシェーダに渡す。

 // サンプルする最大数
 const int SampleMax = 100;
 // サンプルする半径
 const float SampleRadius = 0.1f;
 // 格納場所
 float sample_list[SampleMax][3];
 
 for (int i = 0 ; i < SampleMax ; ++i) {
   // 床井研究室
   //   http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20101122
   // crytek方式(半径Rでランダムサンプル)
   // v = [-1, 1]の乱数
   // u = [0, 1)の乱数
   // w = [0, 1]の乱数
   // R = 半径
   // r = w * R
   // x = r * sqrt(1 - v^2) * cos(2 * PI * u)
   // y = r * sqrt(1 - v^2) * sin(2 * PI * u)
   // z = r * v
   float v = static_cast<float>(rand()) / RAND_MAX * 2.0f - 1.0f;
   float u = static_cast<float>(rand()) / (RAND_MAX + 1);
   float w = static_cast<float>(rand()) / RAND_MAX;
   float r = w * SampleRadius;
   float t = 2.0f * M_PI * u;
   float sp = sqrtf(1.0f - v * v);
   float cn = cosf(t);
   float sn = sinf(t);
   sample_list[i][0] = r * sp * cn;
   sample_list[i][1] = r * sp * sn;
   sample_list[i][2] = r * v;
 }
 
 
***描画パス [#ab368829]
事前準備としては、[[Deferred Rendering>エフェクト-Deferred Rendering]]を行い、2パス目の部分に計算を追加する。
また、1パス目にはModelView行列と計算した座標を出力しておく。

 // サンプリング最大数
 #define SampleMax 100
 
 // サンプル点の補正係数
 #define SampleRatio 2.5
 
 float3 SamplingPoint[SampleMax]; // Uniform サンプリングするポイント
 float4x4 proj_matrix;            // Uniform 1パス目のモデルを描画したProjectionMatrix
 
 
 float4 normal = tex2D(normal_sampler, tex_coord0); // 1パス目の法線テクスチャ
 float4 position = tex2D(position_sampler, tex_coord0); // 1パス目の座標テクスチャ
 float4 depth = tex2D(depth_sampler, tex_coord0); // 1パス目の深度テクスチャ
 
 // occlusionの計算
 int count = 0;
 for (int i = 0 ; i < SampleMax ; ++i) {
   // サンプルする座標をずらす
   float4 pos = mul(position + float4(SamplingPoint[i], 0.0f), proj_matrix);
   
   pos /= pos.w;
   // テクスチャ座標に
   pos.xy = pos.xy * 0.5 + 0.5;
   pos.y = 1.0 - pos.y;
   
   // サンプルした方が、1パス目の深度より手前にあれば遮蔽されていない
   if (pos.z < tex2D(depth_sampler, pos.xy).z)  ++count;
 }
 
 // 補正を入れ、遮蔽されていない数を最大サンプルで割る
 float ao = min((count * SampleRatio) / float(SampleMax), 1.0);


** 参考 [#s0fa481f]
・深度
 &ref(ssao-depth.JPG,,40%);

・SSAO抽出結果
 &ref(ssao-ssao_lighting.JPG,,40%);


・通常シェーディング
 &ref(ssao-deferred_shading.JPG,,40%);

・SSAO付きシェーディング
 靴とかの辺りがチラッとだけ。
 もっときっちりやらないと見栄えが良くならないかも。
 &ref(ssao-ssao_shading.JPG,,40%);


** シェーダコード [#w9575bc5]
1パス目:&ref(deferred_shading.fx);
2パス目:&ref(ssao.fx);


    ホーム 一覧 単語検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS