Skip to content

Commit 9ca4f6e

Browse files
committed
Simple solar system example (initial version)
1 parent 0355d2d commit 9ca4f6e

File tree

11 files changed

+332
-0
lines changed

11 files changed

+332
-0
lines changed

examples/system/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
# Planet System
3+
4+
https://www.solarsystemscope.com/textures/

examples/system/dependencies.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import os
2+
3+
from demosys.resources.meta import ProgramDescription, TextureDescription
4+
5+
6+
def local(path):
7+
"""
8+
Prepend the effect package name to a path so resources
9+
can still be loaded when copied into a new effect package.
10+
"""
11+
return os.path.join(__name__.split('.')[-2], path)
12+
13+
14+
effect_packages = []
15+
16+
resources = [
17+
TextureDescription(label='milkyway', path=local('MilkyWayPanorama4K.jpg')),
18+
ProgramDescription(label='milkyway', path=local('milkyway.glsl')),
19+
20+
TextureDescription(label='sun', path=local('2k_sun.jpg'), mipmap=True),
21+
ProgramDescription(label='sun', path=local('sun.glsl')),
22+
23+
TextureDescription(label='earth_day', path=local('2k_earth_daymap.jpg'), mipmap=True),
24+
TextureDescription(label='earth_night', path=local('2k_earth_nightmap.jpg'), mipmap=True),
25+
TextureDescription(label='earth_clouds', path=local('2k_earth_clouds.jpg'), mipmap=True),
26+
ProgramDescription(label='earth', path=local('earth.glsl')),
27+
]

examples/system/effects.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import moderngl
2+
from demosys import geometry
3+
from demosys.effects import effect
4+
from pyrr import matrix44, matrix33
5+
6+
7+
class SunSystemEffect(effect.Effect):
8+
runnable = True
9+
10+
def __init__(self):
11+
self.sky_sphere = geometry.sphere(100.0)
12+
self.sky_texture = self.get_texture('milkyway')
13+
self.sky_shader = self.get_program('milkyway')
14+
15+
self.sun_sphere = geometry.sphere(10.0)
16+
self.sun_shader = self.get_program('sun')
17+
self.sun_texture = self.get_texture('sun')
18+
19+
# Matrices
20+
self.projection_bytes = self.sys_camera.projection.tobytes()
21+
self.sun_matrix = matrix44.create_identity()
22+
23+
# Default shader parameters
24+
self.sky_shader['m_proj'].write(self.projection_bytes)
25+
self.sky_shader['texture0'].value = 0
26+
self.sky_texture.use(location=0)
27+
28+
# self.sun_shader['m_proj'].write(self.projection_bytes)
29+
# self.sun_shader['texture0'].value = 1
30+
31+
self.sun_pos = None
32+
self.earth = EarthEffect(parent=self)
33+
34+
def draw(self, time, frametime, target):
35+
# Enable depth testing and face fulling
36+
self.ctx.disable(moderngl.DEPTH_TEST | moderngl.CULL_FACE)
37+
cam_mat = self.sys_camera.view_matrix
38+
39+
# Skybox
40+
sky_matrix = matrix44.create_from_matrix33(matrix33.create_from_matrix44(cam_mat))
41+
self.sky_shader['m_mv'].write(sky_matrix.astype('f4').tobytes())
42+
self.sky_sphere.render(self.sky_shader)
43+
44+
self.ctx.enable(moderngl.DEPTH_TEST | moderngl.CULL_FACE)
45+
46+
# Sun position
47+
self.sun_pos = cam_mat[3][0:3].astype('f4')
48+
49+
# Sun
50+
self.sun_shader['m_mv'].write(self.sys_camera.view_matrix.astype('f4').tobytes())
51+
self.sun_shader['m_proj'].write(self.projection_bytes)
52+
self.sun_shader['time'].value = time
53+
self.sun_shader['texture0'].value = 1
54+
self.sun_texture.use(location=1)
55+
self.sun_sphere.render(self.sun_shader)
56+
57+
# Earth
58+
self.earth.draw(time, frametime, target)
59+
60+
61+
class EarthEffect(effect.Effect):
62+
63+
def __init__(self, parent=None):
64+
self.parent = parent
65+
self.program = self.get_program('earth')
66+
self.texture_day = self.get_texture('earth_day')
67+
self.texture_night = self.get_texture('earth_night')
68+
self.texture_clouds = self.get_texture('earth_clouds')
69+
self.sphere = geometry.sphere(2.0, sectors=128, rings=128)
70+
71+
def draw(self, time, frametime, target):
72+
matrix = matrix44.multiply(
73+
# Rotate earth around its own axis
74+
matrix44.multiply(
75+
matrix44.create_from_eulers([0.0, 0.0, -time / 5.0]),
76+
# Translate out from the sun and rotate around it
77+
matrix44.multiply(
78+
matrix44.create_from_translation([-40, 0, 0]),
79+
matrix44.create_from_eulers([0, 0, 0]) # time/100.0])
80+
),
81+
),
82+
self.sys_camera.view_matrix
83+
)
84+
85+
self.program['m_proj'].write(self.sys_camera.projection.tobytes())
86+
self.program['m_mv'].write(matrix.astype('f4').tobytes())
87+
self.program['m_proj'].write(self.sys_camera.projection.tobytes())
88+
self.program['sun_pos'].write(self.parent.sun_pos.tobytes())
89+
self.program['texture_day'].value = 1
90+
self.program['texture_night'].value = 2
91+
self.program['texture_clouds'].value = 3
92+
self.texture_day.use(location=1)
93+
self.texture_night.use(location=2)
94+
self.texture_clouds.use(location=3)
95+
self.sphere.render(self.program)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#version 330
2+
3+
#if defined VERTEX_SHADER
4+
5+
in vec3 in_position;
6+
in vec3 in_normal;
7+
in vec2 in_uv;
8+
9+
uniform mat4 m_proj;
10+
uniform mat4 m_mv;
11+
12+
out vec2 uv;
13+
out vec3 normal;
14+
out vec3 pos;
15+
16+
void main() {
17+
vec4 p = m_mv * vec4(in_position, 1.0);
18+
gl_Position = m_proj * p;
19+
normal = transpose(inverse(mat3(m_mv))) * in_normal;
20+
uv = in_uv;
21+
pos = p.xyz;
22+
}
23+
24+
#elif defined FRAGMENT_SHADER
25+
26+
out vec4 fragColor;
27+
28+
uniform sampler2D texture_day;
29+
uniform sampler2D texture_night;
30+
uniform sampler2D texture_clouds;
31+
uniform vec3 sun_pos;
32+
33+
in vec2 uv;
34+
in vec3 normal;
35+
in vec3 pos;
36+
37+
void main()
38+
{
39+
float v = dot(normalize(normal), normalize(sun_pos - pos));
40+
float m = smoothstep(0.0, 1.0, v * 3);
41+
vec4 c = mix(
42+
texture(texture_night, uv),
43+
texture(texture_day, uv),
44+
m
45+
);
46+
fragColor = c + texture(texture_clouds, uv) * m;
47+
}
48+
49+
#endif
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#version 330
2+
3+
#if defined VERTEX_SHADER
4+
5+
in vec3 in_position;
6+
in vec2 in_uv;
7+
8+
uniform mat4 m_proj;
9+
uniform mat4 m_mv;
10+
11+
out vec2 uv;
12+
13+
void main() {
14+
gl_Position = m_proj * m_mv * vec4(in_position, 1.0);
15+
uv = in_uv;
16+
}
17+
18+
#elif defined FRAGMENT_SHADER
19+
20+
out vec4 fragColor;
21+
uniform sampler2D texture0;
22+
in vec2 uv;
23+
24+
void main()
25+
{
26+
fragColor = texture(texture0, uv);
27+
}
28+
29+
#endif
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#version 330
2+
3+
#if defined VERTEX_SHADER
4+
5+
in vec3 in_position;
6+
in vec2 in_uv;
7+
8+
uniform mat4 m_proj;
9+
uniform mat4 m_mv;
10+
11+
out vec2 uv;
12+
out vec3 pos;
13+
14+
void main() {
15+
gl_Position = m_proj * m_mv * vec4(in_position, 1.0);
16+
pos = in_position.xyz;
17+
uv = in_uv;
18+
}
19+
20+
#elif defined FRAGMENT_SHADER
21+
// Simplex 4D Noise
22+
// by Ian McEwan, Ashima Arts
23+
//
24+
vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);}
25+
float permute(float x){return floor(mod(((x*34.0)+1.0)*x, 289.0));}
26+
vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;}
27+
float taylorInvSqrt(float r){return 1.79284291400159 - 0.85373472095314 * r;}
28+
29+
vec4 grad4(float j, vec4 ip){
30+
const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0);
31+
vec4 p,s;
32+
33+
p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0;
34+
p.w = 1.5 - dot(abs(p.xyz), ones.xyz);
35+
s = vec4(lessThan(p, vec4(0.0)));
36+
p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www;
37+
38+
return p;
39+
}
40+
41+
float snoise(vec4 v){
42+
const vec2 C = vec2( 0.138196601125010504, // (5 - sqrt(5))/20 G4
43+
0.309016994374947451); // (sqrt(5) - 1)/4 F4
44+
// First corner
45+
vec4 i = floor(v + dot(v, C.yyyy) );
46+
vec4 x0 = v - i + dot(i, C.xxxx);
47+
48+
// Other corners
49+
50+
// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
51+
vec4 i0;
52+
53+
vec3 isX = step( x0.yzw, x0.xxx );
54+
vec3 isYZ = step( x0.zww, x0.yyz );
55+
// i0.x = dot( isX, vec3( 1.0 ) );
56+
i0.x = isX.x + isX.y + isX.z;
57+
i0.yzw = 1.0 - isX;
58+
59+
// i0.y += dot( isYZ.xy, vec2( 1.0 ) );
60+
i0.y += isYZ.x + isYZ.y;
61+
i0.zw += 1.0 - isYZ.xy;
62+
63+
i0.z += isYZ.z;
64+
i0.w += 1.0 - isYZ.z;
65+
66+
// i0 now contains the unique values 0,1,2,3 in each channel
67+
vec4 i3 = clamp( i0, 0.0, 1.0 );
68+
vec4 i2 = clamp( i0-1.0, 0.0, 1.0 );
69+
vec4 i1 = clamp( i0-2.0, 0.0, 1.0 );
70+
71+
// x0 = x0 - 0.0 + 0.0 * C
72+
vec4 x1 = x0 - i1 + 1.0 * C.xxxx;
73+
vec4 x2 = x0 - i2 + 2.0 * C.xxxx;
74+
vec4 x3 = x0 - i3 + 3.0 * C.xxxx;
75+
vec4 x4 = x0 - 1.0 + 4.0 * C.xxxx;
76+
77+
// Permutations
78+
i = mod(i, 289.0);
79+
float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x);
80+
vec4 j1 = permute( permute( permute( permute (
81+
i.w + vec4(i1.w, i2.w, i3.w, 1.0 ))
82+
+ i.z + vec4(i1.z, i2.z, i3.z, 1.0 ))
83+
+ i.y + vec4(i1.y, i2.y, i3.y, 1.0 ))
84+
+ i.x + vec4(i1.x, i2.x, i3.x, 1.0 ));
85+
// Gradients
86+
// ( 7*7*6 points uniformly over a cube, mapped onto a 4-octahedron.)
87+
// 7*7*6 = 294, which is close to the ring size 17*17 = 289.
88+
89+
vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ;
90+
91+
vec4 p0 = grad4(j0, ip);
92+
vec4 p1 = grad4(j1.x, ip);
93+
vec4 p2 = grad4(j1.y, ip);
94+
vec4 p3 = grad4(j1.z, ip);
95+
vec4 p4 = grad4(j1.w, ip);
96+
97+
// Normalise gradients
98+
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
99+
p0 *= norm.x;
100+
p1 *= norm.y;
101+
p2 *= norm.z;
102+
p3 *= norm.w;
103+
p4 *= taylorInvSqrt(dot(p4,p4));
104+
105+
// Mix contributions from the five corners
106+
vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0);
107+
vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4) ), 0.0);
108+
m0 = m0 * m0;
109+
m1 = m1 * m1;
110+
return 49.0 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 )))
111+
+ dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ;
112+
113+
}
114+
115+
out vec4 fragColor;
116+
uniform sampler2D texture0;
117+
uniform float time;
118+
in vec2 uv;
119+
in vec3 pos;
120+
121+
void main()
122+
{
123+
float v = snoise(vec4(pos * 2.5, time / 4.0));
124+
fragColor = mix(texture(texture0, uv), vec4(v), 0.3);
125+
// fragColor = texture(texture0, uv);
126+
}
127+
128+
#endif
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)