3D アイランドをレンダリングする OpenGL ES 2.0 アプリを作成しています。島の周りにスカイ ドームを生成するコードは既にあります。これは三角形で構成された半球で、島の上に z 点が上にあるように配置されています。
ドームには、パーリン ノイズ テクスチャをオーバーレイしてさまざまな速度で移動することで作成された、非常に基本的な移動する雲がいくつかあります。
しかし、最終的にはドームもレンダリングする必要があります。
- 太陽 (空を横切って追跡) 月 (フェーズを含む)
- 星(夜)
- 静的テクスチャとしての遠い土地
- 夜、夜明け、夕暮れ、昼をシミュレートするさまざまな色
現時点ではテスト ハーネスで実行されていますが、最終的には Android で実行されるため、これを非常に効率的に行う必要があります。したがって、たとえば、太陽、月、星はテクスチャにすぎませんが、それらのポイントは妥当な精度でプロットされる場合があります。
ドームを生成するコードと、日付と時刻に対して太陽をプロットするコードは既にあります。ほとんどの場合、私が必要とするシェーダーと、それらに付属するものです。
これらのことを示す例はありますか? 基本的なキューブ マップや限定的な機能を備えたものはたくさんありますが、必要なレベルの高度なものはありません。明らかに、これは OpenGL ES 2.0 であるため、シェーダーで実行する必要があります。
既存のスカイ ドームのシェーダーは、2 層のパーリン ノイズをレンダリングして雲をシミュレートします。テクスチャは連続的にラップするため、xy 平面に対するドームの頂点の角度に基づいて u オフセットを計算し (x と y を atan に入力することにより)、ドームの頂点 z を使用して v オフセットを計算できます。
頂点シェーダーは、私がそれを行う方法を示しています。
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
attribute vec4 aVertex;
uniform mat4 uPMVMatrix;
uniform float uTime;
uniform float uSkyDomeRadius;
const float PI = 3.1415926535897932384626433832795;
varying vec2 texCoord0, texCoord1;
void main()
{
vec2 centre = vec2(600., 600.);
gl_Position = uPMVMatrix * aVertex;
float slow_time = uTime / 100.;
vec2 dome_point = aVertex.xy - centre;
float tex_u = atan(dome_point.x, dome_point.y);// / (.25 * PI);
float tex_v = aVertex.z / (uSkyDomeRadius * .5);
texCoord0 = vec2(tex_u / 2.0 + slow_time, tex_v / 2.0);
texCoord1 = vec2(tex_u + slow_time / 2.0, tex_v);
}
また、雲が動くように、フレームごとに ua bit をオフセットする時間を使用します。これは、atan が -PI から PI に移動し、フラグメント シェーダーが補間する texCoord0 と texCoord1 の値が突然、補間をホース処理する大きな距離で区切られていることを除いて、正常に機能します。
これを説明する最良の方法は、ベースに 16 個の三角形がある場合、0/16 から 1/16 への補間、1/16 から 2/16 への補間などであるということです。しかし、15/16 から 0/16 に到達すると、インターポレーターが逆方向に移動し、変動が大きいため、フラグ シェーダーが小さなスペースでテクスチャを何度も繰り返し、図のように縞模様になります。
シームレスな 360 度のビューを表示する方法がわかりません。これを修正する唯一の方法は、ドーム全体を回転させて継ぎ目が常にカメラの後ろになるようにすることだと思いますが、カメラがまっすぐ上を向いている場合はまだ表示される可能性があります。ドームの頂上。
ソースを使用した実際の例は、特にこの種の問題に対処する場合に最適です。