68
61

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

WebGLAdvent Calendar 2016

Day 20

レイマーチングで潜れる雲を作る

Last updated at Posted at 2016-12-19

この記事は,WebGL Advent Calendar 2016 20日目の記事です。

doxasさんやgam0022さんのレイマーチングの作品を見て面白そうだったので挑戦してみようと思います。

#目的
ところでこの記事を見ている方はエースコンバットというゲームをご存知でしょうか。
超遠距離のオブジェクトや、雲や煙のような形が定まっていない物ばかりが描画されるゲームです。
Youtubeリンク

プログラミングを学び始めた頃は、こういったものがどうやったら表示出来るのか全くわかりませんでしたが、今なら少し再現できそうです。
そこで、今回はその第一歩としてレイマーチングの力を借りて、リアルな雲を描画してみたいと思います。

#方法
「よし、レイマーチングでボリュームレンダリングをしよう!」と思っても、よく考えたらなにをしたら良いのかわかりません。
というかボリュームレンダリングって何?

https://ja.wikipedia.org/wiki/ボリュームレンダリング

コンピュータグラフィックスにおいて、ボリュームレンダリングとは、3次元的な広がりのあるデータを直接2次元画面に表示することである。半透明な物体や発光体などを光学的に正しくレンダリングしたり(レイキャスティング)、CTなどで3次元的に撮影された画像を目的に沿って見やすく提示したりする(最大値投影処理など。)

説明が全然わからない。

Wikipediaについてた画像

レイキャスティングによるボリュームレンダリングをする方法の模式図。

なるほど。
とりあえず一定距離ずつレイを飛ばしてその地点の色の情報を取得して合成していく雰囲気だと思います。

#作成
考え方は想像出来たのでSharder Toy上で作ってみました。
Sharder Toyリンク
https://www.shadertoy.com/view/ll3SWl

    vec4 sum = vec4(0, 0, 0, 0);
    for (float depth = 0.0; depth < 100000.0; depth += 100.0)
    {
        vec3 ray = campos + fragAt * depth;
        if (cloudrange.x < ray.y && ray.y < cloudrange.y)
        {
            float alpha = smoothstep(0.5, 1.0, fbm(ray * 0.00025));
            vec3 cloudColor = mix(vec3(1.1, 1.05, 1.0), vec3(0.3, 0.3, 0.2), alpha);
            alpha = (1.0 - sum.a) * alpha;
            sum += vec4(cloudColor * alpha, alpha);
        }
    }

雲を描画している部分がここです。

簡単に解説すると

  1. カメラの位置からfragAtの方向に100.0ずつベクトルを伸ばし、伸ばした座標に依存するfbmを取得
  2. 取得した値を元に透明度と雲の色(濃さ)を計算
  3. 雲の色を「余っている透明度」に対してその雲の透明度分、合成

「余っている透明度」の部分がすこしわかりづらいですが
例えば1ループ目で透明度50%の雲が発生したら
alpha = (1.0 - 0.0) * 0.5
なのでalphaは0.5になります。

2ループ目でもう一度透明度50%の雲が発生したら
alpha = (1.0 - 0.5) * 0.5
なので0.75になります。

このように画面奥の雲の色は、それより手前でついた雲の色より影響されにくくなります。

#参考
fbmというのはフラクタルブラウン運動というパーリンノイズの仲間みたいなものです。
http://qiita.com/y_li/items/290754b9c3ba18e9fb2b

潜れる雲を作るにあたって非常に参考になった作品です。
この作品自体はカメラを雲の中に移動させると破綻してしまうんですが、wikipediaの参考画像と合わせてボリュームレンダリングについて理解出来るようになりました。
https://www.shadertoy.com/view/4sXGRM


ところでボリュームレンダリングでこれあってるんでしょうか。
「君のやってるそれ全然違うものだよ」とかありましたらご指摘ください。

68
61
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
68
61

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?