0

ここにある高さマップ シェーダーの例を、8 ではなく 32 ビットの精度で動作するものに転用しようとしています。進行中のコードは github にあります: https://github.com/bgourlie/three_heightmap

高さマップは .NET で生成されています。高さは 0f...200f の範囲内で、次のメソッドを使用して 32 ビットのカラー値 (Unity のColor struct ) に変換されます。

private static Color DepthToColor(float height)
{
    var depthBytes = BitConverter.GetBytes(height);
    int enc = BitConverter.ToInt32(depthBytes, 0);
    return new Color((enc >> 24 & 255)/255f, (enc >> 16 & 255)/255f, (enc >> 8 & 255)/255f,
            (enc & 255)/255f);
}

カラー データは png としてエンコードされ、結果は次のようになります。

ここに画像の説明を入力

頂点シェーダーはこの画像データを取得し、RBGA 値を元の高さの値に変換します (こちらの質問で回答された手法を使用します)。

uniform sampler2D bumpTexture; // defined in heightmap.js
varying float vAmount;
varying vec2 vUV;

void main()
{
  vUV = uv;
  vec4 bumpData = texture2D( bumpTexture, uv );
  vAmount = dot(bumpData, vec4(1.0, 255.0, 65025.0, 16581375.0));
  // Uncomment to see a "flatter" version
  //vAmount = dot(bumpData, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/160581375.0));

  // move the position along the normal
  vec3 newPosition = position + normal * vAmount;
  gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
}

結果は間違いなくめちゃくちゃです:

ここに画像の説明を入力

この行を変更することで、よりフラットにすることができます。

vAmount = dot(bumpData, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));

これにより、より平坦な画像が得られます。少なくとも、生成された地形の輪郭がきれいに表示されますが、ほぼ完全に平坦な平面が表示されます (目立たない変化ではありますが、わずかな変化があります)。

ここに画像の説明を入力

私はいくつか間違ったことをしていると思いますが、何がわからないだけです。元のフロートを正しくエンコードしているかどうかはわかりません。頂点シェーダーで正しくデコードしているかどうかはわかりません (取得している値は確かに 0 ~ 200 の範囲外です)。また、一般的に 3D グラフィックスの経験もあまりありません。したがって、私が間違っていること、または一般的にこれを達成する方法についての指針をいただければ幸いです。

ここでも、自己完結型の進行中のコードがここにあります: https://github.com/bgourlie/three_heightmap

4

2 に答える 2

1

ワイド整数を RGBA ベクトルのコンポーネントにエンコードする場合は、フィルタリングをオフにして、値間で補間が発生しないようにすることが不可欠です。また、OpenGL は内部的に別の形式に変換する場合がありますが、それはサンプルの深さを減らすだけです。

于 2015-02-22T20:59:17.847 に答える