Я пишу приложение OpenGL ES 2.0, которое отображает 3D-остров. У меня уже есть код для создания купола неба вокруг острова. Это полушарие, состоящее из треугольников, над которыми лежал остров с точкой z вверх.
У купола есть очень простые движущиеся облака, созданные с использованием текстуры шума perlin, наложенной на себя и движущейся с разной скоростью.
Но в конечном итоге мне нужен купол, который также отображает:
- Солнце (которое проходит по небу) Луна (включая фазу)
- Звезды (ночью)
- Отдаленная земля как статическая текстура
- Различные цвета для имитации ночи, рассвета, сумерек, дня
Мне нужно сделать это достаточно эффективно, так как это закончится на Android, хотя на данный момент он работает в тестовом жгуте. Таким образом, солнце, луна и звезды, например, будут просто текстурами, хотя их точки могут быть построены с разумной точностью.
У меня уже есть код для создания купола и код для построения солнца против даты и времени. Так что в основном это шейдеры, которые мне нужны, и то, с чем они поставляются.
Есть ли какой-нибудь пример, демонстрирующий эти вещи? Я нашел много, которые делают базовые кубические карты или ограниченный материал, но не до уровня сложности, в которой я нуждаюсь. Очевидно, поскольку это OpenGL ES 2.0, это нужно делать в шейдерах.
Шейдер для моего существующего купола неба создает 2 слоя перлинского шума для имитации облаков. Текстура непрерывно обтекает, поэтому я могу вычислить смещение u на основе угла вершины купола в плоскость xy (путем подачи x и y в atan) и смещения v с использованием вершины купола z.
Вершинный шейдер демонстрирует, как я это делаю:
#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);
}
Я также использую время для смещения u бит каждого кадра, чтобы облака двигались. Это отлично работает, за исключением того, что atan переходит от -PI к PI, и внезапно значения texCoord0 и texCoord1 интерполяторы фрагментарного фрагмента разделены большим расстоянием, которое шунтирует интерполяцию.
Лучший способ описать это состоит в том, что если у меня есть 16 треугольников на моей базе, то интерполяция от 0/16 до 1/16 работает, от 1/16 до 2/16 работает и так далее. Но когда я добираюсь до 15/16 до 0/16, интерполятор идет назад, и большая вариация заставляет фрагмент-шейдер повторять текстуру снова и снова в небольшом пространстве, ведущем к полосам, как показано.
Я не вижу никакого способа иметь бесшовное представление на 360 градусов. Я думаю, что единственный способ, которым я это исправим, - это то, что я вращаю весь купол, чтобы шов всегда находился за камерой, но он все равно может показать, до вершины купола.
Рабочий пример с источником был бы большим, особенно если он решает эти проблемы.