Top > エフェクト-SSAO エフェクト-SSAO †Screen Space Ambient Occlusion。 以下のロジックはまだ綺麗に出来ていないので改善点はあります。 参考サイト †床井研究室 計算 †サンプル点の計算。 †今回はランダムサンプル。計算式は床井研究室さん参考。 // サンプルする最大数 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; } 描画パス †事前準備としては、Deferred Renderingを行い、2パス目の部分に計算を追加する。 // サンプリング最大数 #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); 参考 †・SSAO付きシェーディング シェーダコード †1パス目:deferred_shading.fx |