23
7

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.

レイマーチングでHeight Map Distance Field

Posted at

概要

今回はレイマーチングでHeight Mapを使って凹凸のある平面を描いてみます。
実際にレンダリングした結果は以下みたいな感じになります。
mountain.jpg
アニメーションさせたやつ↓
output.gif
Shadertoyで実際に動くデモもあります。

見てもらうと分かりますが、とても「平面」には見えませんねw

が、距離関数自体は平面のものを使い、距離に多少細工をしてこの描画を行っています。

今回の実装については「こんな感じかなー」という想像で行いました。
ただShadertoyでは以下のようにコメントもらったので、基本的なアプローチは合っていると思います。

Most heightmap distance field formula will look like this yeah.

実装解説

距離関数

今回の実装の距離関数をまずコードで示します。

距離関数
// テクセル(高さ)の倍率
const float heightFactor = 3.0;

// 平面との距離関数
float distPlane(in vec3 p, vec4 n)
{
    return dot(p, n.xyz) * n.w;
}

// Height Mapを使った距離関数
float distFunc(in vec3 p)
{
    float d = distPlane(p, plane);
    vec4 tex = texture(iChannel0, mod(p.xz * 0.2, 1.0));
    tex *= heightFactor;
	return d - tex.x;
}

distFuncが距離関数です。
内部では平面との距離関数であるdistPlaneを呼び出し結果を少し細工しています。

細工は、

vec4 tex = texture(iChannel0, mod(p.xz * 0.2, 1.0));
return d - tex.x;

の部分ですね。(heightFactorは単にテクセルの値を増減させる目的で用意してます)

ちなみにこのtexture関数ですが、これはShadertoy上で定義されている関数です。
第一引数に渡しているiChannel0は、これもShadertoy上で用意されているテクスチャへの参照です。
今回の例では普通のテクスチャサンプリングと考えてもらって大丈夫です。

XZ平面上のテクスチャをサンプリング

さてここでやっていることですが、p.xzというパラメータを使っています。
これは平面に対しての距離関数を求めたあと、その時点でのレイの位置をUV座標として利用し、平面のテクスチャを(概念的に)サンプリングします。
そしてサンプリングしたテクセルの値(つまり高さ)を、求めておいた平面との距離から減算することで平面との距離を操作している、というわけです。

と、言葉にすると分かりづらいので図にすると以下のような感じになります。

raymarching-heightmap.png

元々は平らな平面から、HeightMapを使うことで擬似的に平面に凹凸を生み出している、というわけですね。
距離についての計算ができてしまえば、あとは通常のレイマーチングの仕組みに則って法線も求められるし、ライティングやシェーディングを行うことができる、というわけです。

ちなみに今回使っているテクスチャは以下の画像です。
tex.png

今回はHeightMapの実装を確かめることが目的だったのでShadertoyに用意されているテクスチャを使いましたが、実際には「フラクタルブラウン運動(Fractal Brownian Motion(FBM))」と呼ばれるパーリンノイズに似たノイズ関数を利用してランタイムで地面を生成してレンダリングしているのが一般的なようです。(Shadertoyの中で)

ちなみに、フラクタルブラウン運動についてはこちらの記事が実装込みで解説してくれています。(ただ、画像のリンクが切れてしまっていますが・・・)

以上がHeightMapを使った地形のレンダリングです。
それ以外のレイマーチングの実装は一般的な実装だと思うので解説は割愛します。

レイマーチング自体の仕組みなどについては以前、記事を書いたのでそちらを参照ください。

(vol.1とか言いながらvol.2書いてない・・・;)

その他参考記事

23
7
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
23
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?