«SSAO (Screen Space Ambient O.. 最新 フレームバッファオブジェクトの使い方あげいん»

床井研究室

※このブログは遅くとも 2027 年 3 月に管理者の定年退職により閉鎖します (移転先は管理者本人共々模索中)

■ 2010年12月03日 [OpenGL][GLSL] 似非 SSS (Subsurface Scagttering)

2010年12月08日 12:31更新

就職氷河期

M2 が二人売れ残ってます. 他の二人がさっさと決めてくれたので意外と調子いいなと思ってたんですが, 残る二人がなかなか決まりません. うち一人は早くから研究成果を出していた人なので悔しいです. それに就職活動が長引いたせいで, せっかく積み上げてきた成果がしなびてしまいそうです. なんとかならんかな.

似非 SSS (Subsurface Scattering)

先日 SSAO のサンプルを作っているときに久保尋之氏からメッセージを頂いたのをきっかけに, 久保氏のご研究をヒントに, もしかしたらこういう方法でも SSS (Subsurface Scattering, 表面下散乱) っぽい表現ができるかも, と考えてやってみました.

この方法は理論的な裏付けもサーベイもしてませんし, 速くもなければ品質が良い訳でもないのですが, SSAO のプログラムをわずかにいじるだけで実現できます. いじったのは下記のところです.

  • サンプル点の密度を均一にした.
  • サンプル点の散布範囲を大きくした.
  • 遮蔽されないサンプル点数と環境光の反射係数との関係を調整した.
  • 拡散反射係数・鏡面反射係数などのマテリアルを微調整した.
  • 光源強度・環境光強度を微調整した.
  • 背景・地面を描かないようにした.
  • 環境マッピング・屈折マッピングを取り除いた.

サンプルプログラムは SSAO のものとほとんど変わりませんが, 一応まとめました. SSAO との差分も用意しています.

サンプル点の散布方法

SSAO の場合はサンプル点を密度が距離の二乗に反比例するように散布していましたが, これを均一にしました. 密度が距離の二乗に反比例していると照射点に近い部分の影響が強くなりすぎて, 表面に近いところだけが明るくなってしまいます. 密度が均一ということは, 照射点の周囲の空間の体積を計測することになります. また, 透過光がオブジェクト全体に行き渡る? ように, サンプル点の散布範囲をオブジェクトのサイズに対して大きめに設定します.

/*
** 深度のサンプリングに使う点群
*/
#define MAXSAMPLES 256                        // サンプル点の最大数
#define SAMPLERADIUS 0.3f                     // サンプル点の散布半径
static GLfloat pointbuf[MAXSAMPLES][4];       // サンプル点の位置
static GLint point;                           // サンプル点の uniform 変数
 
...
 
/*
** 初期化
*/
static void init(void)
{
  
  ...
  
  /*
  ** 露出度を算出するのに使う球状の点群
  */
  // サンプル点の生成
  for (int i = 0; i < MAXSAMPLES; ++i) {
    float r = SAMPLERADIUS * pow((float)rand() / (float)RAND_MAX, 1.0f / 3.0f);
    float t = 6.2831853f * (float)rand() / ((float)RAND_MAX + 1.0f);
    float cp = 2.0f * (float)rand() / (float)RAND_MAX - 1.0f;
    float sp = sqrt(1.0f - cp * cp);
    float ct = cos(t), st = sin(t);
    
    pointbuf[i][0] = r * sp * ct;
    pointbuf[i][1] = r * sp * st;
    pointbuf[i][2] = r * cp;
    pointbuf[i][3] = 0.0f;
  }
}

環境光の反射係数

サンプル点とデプスバッファを比較して可視のものの数を求めるところは同じですが, この場合は照射点の周囲の空間の体積を求めます.これがサンプル点数の 2 分の 1 を超えたら, 超えた分に比例して環境光の反射係数を大きくします. これは自己発光強度を上げたことになります.

  // 遮蔽されないポイントの数から周辺のボリュームを求め,露出度に換算する
  float a = clamp(float(count) * SAMPLING_RATIO / float(SAMPLES), 1.0, SAMPLING_RATIO);
  
  // 環境光の反射光 (unit[1]) に露出度を適用
  vec4 color = diffspec + texture2D(unit[1], texcoord) * a;

そのほか

材質や光源は SSS っぽく見えるようにトライアンドエラーでアドホックに設定しています.

似非 SSS (Subsurface Scattering)
コメント(2) [コメントを投稿する]
BeepCap 2010年12月05日 23:23

企業側としても、就職難は望ましくなく、出来るだけ採用したいのですが、やはり厳しい時代なので、「なんでも出来る人材」を求めすぎる傾向にあります。 なんとも世知辛いです。

とこ 2010年12月06日 00:35

BeepCap さま,ありがとうございます.今読んだら「就職先くれ!」みたいな書き方になっているなと思いましたが,この状況でも決まる人は決まるので,やはり個人の問題もあると思います.たいてい,どこかに何かミスマッチがあります.わかっていても解消するのが難しかったりするのですが.ただ,学生のうちに本当にやっておかなければならないことに割く時間(と意欲)が削られるあたりに苛立ちを感じます.


編集 «SSAO (Screen Space Ambient O.. 最新 フレームバッファオブジェクトの使い方あげいん»