3

高さマップからフラグメントシェーダーで法線マップをベイク処理しています。高さマップは見栄えがよく、滑らかに見えます。ただし、法線マップを生成すると、非常に奇妙な結果が得られます。

これが問題を示す2つのレンダリングされた画像です。1つはすべての照明計算を含み、もう1つはメッシュの上に法線マップ画像を適用しています。 Normapマップ

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

法線マップをベイクする方法は、フラグメントシェーダーで隣接するピクセルをサンプリングすることです。

メッシュは32x32で、法線マップと高さマップは64x64です。隣接するピクセルをサンプリングするフラグメントシェーダーコードは次のとおりです。

float NORMAL_OFF = (1.0 / 64.0);
vec3 off = vec3(-NORMAL_OFF, 0, NORMAL_OFF);

// s11 = Current
float s11 = texture2D(uSampler, texturePos).x;

// s01 = Left
float s01 = texture2D(uSampler, vec2(texturePos.xy + off.xy)).x;

// s21 = Right
float s21 = texture2D(uSampler, vec2(texturePos.xy + off.zy)).x;

// s10 = Below
float s10 = texture2D(uSampler, vec2(texturePos.xy + off.yx)).x;

// s12 = Above
float s12 = texture2D(uSampler, vec2(texturePos.xy + off.yz)).x;

vec3 va = normalize( vec3(off.z, 0.0, s21 - s11) );
vec3 vb = normalize( vec3(0.0, off.z, s12 - s11) );

vec3 normal = normalize( cross(va, vb) );

texturePosは、頂点シェーダーでvertexPosition.x / 128として計算されます(頂点間の距離が4ピクセルであるため、128です。したがって、32 * 4 = 128)。

なぜ私の結果はとても奇妙なのですか?

4

1 に答える 1

4

高さマップのサンプリング深度の解像度が少なすぎるため、これらの困難な手順が発生します。おそらく、高さマップは8ビットであり、最大256の高さレベルが得られます。これで、高さマップが256よりも平面の解像度が高い場合、横方向の解像度は滑らかな高さフィールドを表すには不十分です。

解決策:高さマップには、より高いサンプリング解像度を使用してください。16ビットが一般的な選択肢です。

ただし、シェーダーとベイキングコードは問題ありませんが、操作するのに十分な解像度の入力データを取得できません。

于 2013-03-02T19:38:17.453 に答える