ノイズの多いエッジ、フラグメントシェーダーによる面間のエッジの平滑化


8

以下のスクリーンショットのように、六角形のジオメトリで生成された地形があります。

ここに画像の説明を入力してください

次にバイオームを生成しますが、ご覧のとおり、それらの境界は本当に醜く、まっすぐです。その六角形の原点を隠すには、バイオーム間の境界を滑らかにする必要があります。これは、実際の波状面を含むワイヤーフレームでの外観です。

ここに画像の説明を入力してください

私が目指しているのは次のようなものです:

ここに画像の説明を入力してください

各頂点にはバイオームタイプを保持する属性があります。2つのバイオーム間のエッジの頂点に特別な属性を追加することもできますが、これをシェーダーコードで明らかにする方法がわからないようです。明らかにノイズです。ここに含まれていますが、複数のバイオームの複数の顔と境界全体で連続させるにはどうすればよいですか?

THREE.jsを使用してWebGLでレンダリングしています


MSAAを試しましたか?
Milo Lu

@ミロ質問を読んでみましたか?
バリント

バイオーム情報をシェーダーにどのように送信しますか?
バリント

@BálintBiome現在、頂点属性を介して色を渡しています。単純な色ではなく、実際のテクスチャから実際に色をサンプリングする場合は、バイオームタイプを整数として渡します。
user1617735 2017年

頂点属性は希望どおりに使用できません。テクスチャに切り替えると、これはずっと簡単になります。あなたは近くのバイオーム取得することができますので、テクスチャとしてバイオーム情報をアップロード
バリント

回答:


9

ここでの他の答えは、テクスチャの使用を提案しています。テクスチャを使わないテクニックを紹介します。

六角形の境界を面白くしたいとします。描画しているものの中央に移動すると、興味深い境界線を作成するのが簡単になります。タイルを直接描画する代わりに、タイルの「デュアル」を描画します。この手法は「コーナータイル」と呼ばれますここここここ)。六角形の双対は三角形なので、六角形の代わりにこれらの三角形を描画します。

六角形の三角形双対

六角形の間の境界はレンダリングされた三角形の真ん中にあるので、それらを使ってもっと面白いことができるようになります。ボーナス:六角形ごとに三角形を2つ描画するだけで済みます(現在の場合は24)。

これらの三角形のそれぞれの内部で、フラグメントシェーダーに六角形を描画させます。重心座標でそれを行うことができます。三角形の各頂点に(1,0,0)、(0,1,0)、(0,0,1)を置きます。三角形の内部では、それらの座標が補間されます。フラグメントシェーダーは(a、b、c)を受け取り、最大の値を確認できます。これにより、この時点で3つの六角形のどれを描画するかがわかります。

float max_n = max(barycentric.r, max(barycentric.g, barycentric.b)); if (max_n == barycentric.r) { color = v_color0; } else if (max_n == barycentric.g) { color = v_color1; } else if (max_n == barycentric.b) { color = v_color2; }

それは直線のためです。

ノイズの多いエッジが必要な場合は、重心座標にノイズを追加できます。

ノイズの多いエッジを持つ六角形

ノイズの振幅波長/周波数で遊んで、いくつかのクールな効果を得ることができます:

ノイズの多いエッジを持つ六角形

ノイズに注意し、三角形の境界を越えて一貫していることを確認する必要があります。これを行う1つの方法は、16進数のIDを渡して、それを重心座標に追加された3つのノイズ値のそれぞれのシード値として使用することです。

ここでインタラクティブなデモを行いました。(デモでは、実際のプロジェクトでこれを機能させる場合に必要な16進数IDやその他のいくつかを実装しませんでした。これは簡単で素早いデモです)


これが一流の品質の回答資料です。ハットチップ
クエンティン

正解です。微妙な修正:六角形を含む通常のポリゴンは自己デュアルです。ただし、三角形と六角形のテッセレーションは、答えが示すように、互いに双対です。
エリックフォス

0

私はいくつかの画像アルゴリズムで「解ける」と確信していますが、もしそれが私なら、おそらくテクスチャでそれを解決するでしょう。六角形のテクスチャを作成し、それらすべてをテクスチャアトラスに配置します。次に、六角形ごとにその隣を調べて、適用するテクスチャを決定します。

テクスチャには、地形のタイプごとのバージョンと、トランジションのタイプごとのバージョンが必要です。

これは、タイルベースのシステムが地形を作成する数に似ています。2Dゲームの例を示します。

別の可能性は、さまざまなタイプの地形(水、雪、土、草)のテクスチャを用意し、六角形の各頂点に混合量を追加して、それらの混合方法を決定することです。

この記事では、地形テクスチャを混合するアイデアを示します。私はそれらの実装に従うことを提案していませんが、それはアイデアを示しています。


まあ、私の場合、テクスチャを準備するのは簡単ではありません。六角形は均一ではないため、マップ全体で形状とサイズが異なります。残念ながら、それは私が惑星を所有するために払わなければならない代金であり、フラットマップだけではありません。また、記事は非常に面白く見えます、ありがとう。私の場合、地形を上からレンダリングしていますが、おそらく、たとえば、1本の木が見えず、森全体の突起が1つのグリムの塊のように見える高度からです。
user1617735 2017

0

まず、バイオームをテクスチャにレンダリングします。三角形をtexcoordsにマッピングします。これは、メルカトル図法を使用して行うことができます。次に、フラグメントシェーダーで、次のようにします。

// frequency and magnitude of the noise in texels.
uniform float frequency;
uniform float magnitude;

// This function should just look like random smooth noise in x,y
// This one isn't great, but you can experiment.
vec2 noise(vec3 vertexPos) {
    return vec2(sin(vertexPos.x * frequency + vertexPos.y * frequency) * magnitude, 
                cos(vertexPos.y * frequency * 2 + vertexPos.z * frequency) * magnitude);
}

// Sample the texture and preturb it with noise based on the world
// position of the fragment.
vec4 frag(vec2 texCoord, vec3 fragmentPos) {
   return texture(mySampler, texCoord + noise(fragmentPos));
}

ここで、noiseテクスチャ座標オフセット騒々しいを返すモデル空間における頂点の3D位置上の(たとえば、正弦波を用いて)、いくつかの擬似ランダム関数です。を使用GL_NEARESTしてテクスチャをサンプリングし、境界をシャープにします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.