Piszę aplikację OpenGL ES 2.0, która renderuje wyspę 3D. Mam już kod do generowania kopuły nieba wokół wyspy. Jest to półkula złożona z trójkątów, które nad wyspą mają punkt z w górę.Jak renderować przekonujący skydome?
Kopuła ma kilka bardzo prostych ruchomych chmur utworzonych przy użyciu tekstur szumów perlli nałożonych na siebie i poruszających się z różnymi prędkościami.
Ale w końcu muszę kopułę również render:
- Sun (która śledzi po niebie) Księżyc (w tym faza)
- Gwiazdki (w nocy)
- dalekiego kraju jako statyczny tekstury
- Różne kolory symulować noc, świt, zmierzch, dzień
muszę to zrobić dość sprawnie, ponieważ będzie to skończyć o n Android chociaż na razie działa w uprzęży testowej. Słońce, księżyc i gwiazdy będą na przykład teksturami, chociaż ich punkty mogą być nanoszone z odpowiednią dokładnością.
Mam już kod do generowania kopuły i kod do wykreślenia słońca z datą i godziną. Tak więc w większości są to shadery, których potrzebuję i do czego są dostarczane.
Czy istnieje przykład demonstrujący te rzeczy? Znalazłem mnóstwo, które robią podstawowe mapy sześcianu, lub ograniczone rzeczy, ale nic do poziomu wyrafinowania, którego potrzebuję. Oczywiście, ponieważ jest to OpenGL ES 2.0, trzeba to zrobić w shaderów.
Moduł cieniujący dla istniejącej kopuły nieba renderuje 2 warstwy szumu perlinowego w celu symulacji chmur. Tekstura owija się w sposób ciągły, dzięki czemu mogę obliczyć przesunięcie u oparte na kącie wierzchołka kopuły na płaszczyznę xy (przez podanie x i y na atan) i przesunięcie v przy użyciu wierzchołka kopuły z.
Wierzchołek shader pokazuje, jak to zrobić:
#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żywam również czas, aby zrównoważyć u nieco każdą klatkę więc chmury poruszać. Działa to dobrze, chyba że atan przechodzi od -PI do PI i nagle wartości texCoord0 i texCoord1 interpolacji fragmentów cieniowania są oddzielone dużą odległością, która wsuwa interpolację.
Najlepszym sposobem, aby to opisać, jest to, że jeśli mam 16 trójkątów u podstawy, to interpolacja od 0/16 do 1/16 prac, 1/16 do 2/16 prac i tak dalej. Ale kiedy dojdę do 15/16 do 0/16 interpolator cofa się, a duża zmienność powoduje, że shader fragmentów powtarza teksturę w kółko na małej przestrzeni prowadzącej do pasków, jak pokazano.
Nie widzę żadnych sposobem na bezproblemowe widok 360 stopni myślę, że jedynym sposobem Zrobię to, jeśli obrócić całą kopułę tak szew jest zawsze za kamerą, ale może nadal pokaż, czy kamera wskazuje prosto do górnej części kopuły.
Przykład pracy ze źródłem byłby świetny, zwłaszcza jeśli rozwiązuje tego typu problemy.
głupie pytanie, ale może być tex_x> PI lub
BevynQ
tex_x zawsze będzie między PI a PI bo atan zwraca te wartości. Mam 16 trójkątów u podstawy kopuły więc każda podstawa trójkąta przepisuje łuk 2pi/16 lub PI/8. So v0 może być 3/16-ty dookoła i v1 4/16 i tak tex_x interpoluje prawidłowo. Problem pojawia się, jeśli v0 to 15/16, a v1 to 0/16, a interpolacja jest całkowicie skręcona. Nie mogę wymyślić, jak to naprawić, więc spekuluję, że będę musiał obrócić kopułę, aby szew był zawsze za kamerą i zrównoważyć wszystko, co wykonam w równoważnej ilości. – locka
Uaktualniłem to pytanie, aby wyjaśnić to i zmieniłem nazwę tex_x i tex_y jako tex_u i tex_v – locka