初日の出

新年といえば初日の出を観に行った人もいると思われるが、初日の出のイメージといえば やはり水平線から出る太陽だ。 このとき、海面に反射して映る太陽は水平線からまっすぐとした線状となる。

これについてhirax.net::「海面に写る太陽」の不思議にて、 解説されている。そのページによると原因として以下のように3点挙げられている。

「海面が波立っていること」「太陽に対する(微小)海面の向き」「海面でのフレネル反射率」が原因だということがわかってきた。

これらは古典的な幾何光学で説明されていて、海面の法線と反射だけをうまく設定してやれば コンピュータ上で再現できそうなことに気づいた。

CG実験

そこで、水面と照明からなる簡単なCGをつくってみた。レンダラーはPOV-Ray 3.7.0.beta.41を使用した。ソースコードは下に示してある。

画面中央に光源(太陽)があるようにするため、カメラは太陽方向を向く設定にした。そして、光源はカメラの場所から十分離れた白色点光源で実現した。写真で水面に映る太陽の部分は飽和しており、このような写真を得るために光の強さはかなり強くした。それが光源の色の設定を使用してWhite*10と設定している箇所である。また、光源形状として球(sphere)を指定して太陽の形状を模した。

水面は真っ平らな無限平面(plane)で実現した。水面の傾きを実現するためには法線ベクトルを設定する方法を使った。それが#if Wavelet#endで囲った部分である。その他肝心のフレネル反射をするようにも設定した(fresnel onの箇所)。

#include "colors.inc"

global_settings {
    charset utf8
}

#declare Wavelet=no;
#declare SunPlace=<0,20000,100000>;

camera {
    location <0, 0.5, 0>
    look_at SunPlace
}

// 光源(太陽の代わり)
light_source {
    SunPlace White*10
    looks_like {
        sphere {
            SunPlace,10000
            pigment {
                color White
            }
            finish {
                diffuse 1.0
            }
        }
    }
}

sky_sphere {
    pigment {
        color rgb <0.7, 0.8, 1.0>
    }
}

// 水面
plane {
    y, 0

    pigment {
        rgbf <0.0, 0.0, 1, 0>
    }

    texture {
#if (Wavelet)
        normal {
            bozo
            scale <0.05, 0.25, 0.05>
        }
#end
        finish {
            diffuse 1.0
            ambient 0.0

            reflection {
                0.9
                fresnel on
            }
        }
    }
    interior { ior 1.33 }
}

結果

以下がPOV-Rayにレンダリングをさせて得られた画像である。水面の法線ベクトルが実際の水面をうまく再現できていないらしくやや不自然なところもあるが、理論通り線状に太陽が映っていることがわかる。

次に、ソースコードを#declare Wavelet=no;と変更し、水面のさざなみをなくした環境下での画像が以下である。教科書通りの上下逆さまの鏡面反射になった。

まとめ

以上より水平線から上がった太陽の反射像を工夫すればPOV-Rayで再現できることがわかった。加えて、水面の極小な傾きよって太陽の反射像が線状になることを確認できた。

なお、最初の写真はtoyohara氏による2009年の初日の出の写真。