Gregory Igehy

Dancing at hemisphere coordinate

Glossy specular reflection by using Nonnormalized Phong specular reflection

  • 非正規化 Phong スペキュラ反射によるグロッシーなスペキュラ反射
  • 下図は Phong のシャイニネスを順に, 4.0, 32.0, 512.0 と, 粗い->滑らかへと変化させた場合

( 1 ピクセルあたりのサンプル数は 200 )
f:id:gregory-igehy:20150218153910j:plain
f:id:gregory-igehy:20150218153918j:plain
f:id:gregory-igehy:20150218154931j:plain

  • 非正規化 Phong スペキュラ反射の重点サンプリングは以下のようなコード
    // リフレクションのレイ
    Ray perfect_reflect_ray( x, r.d - n * 2 * n.dot( r.d ) );

    // cos_theta ^ c_roughness のときの半球サンプリング
    const double e = c_roughness;

    double r1      = erand48( Xi );
    double r2      = erand48( Xi );

    double phi     = 2 * M_PI * r1;
    double cos_phi = cos( phi );
    double sin_phi = sin( phi );

    double cos_theta = pow( 1.0 - r2, 1.0 / ( e + 1.0 ) );
    double sin_theta = sqrt( 1.0 - cos_theta * cos_theta );
    
    Vec w = perfect_reflect_ray.d;
    Vec u = ( ( fabs( w.x ) > 0.1 ? Vec( 0, 1 ) : Vec( 1 ) ) % w ).norm( );
    Vec v = w % u;
    Vec d = ( u * sin_theta * cos_phi + v * sin_theta * sin_phi + w * cos_theta ).norm( );

    // グロッシーなスペキュラ反射用のレイ
    Ray reflect_ray( x, d );
    const f64 is_valid = ( reflect_ray.d.dot( n ) >= 0.0 );

    // 法線より上のレイであるか ? の有効性の判定
    if ( is_valid )
    {
        return obj.e + f.mult( radiance( reflect_ray, depth, Xi ) );
    }
    else
    {
        return obj.e;
    }