Compare commits

..

No commits in common. "8db60a0c01c736ecb8a185f4dfa782fbf3dcb49e" and "1abfdfadf843dc510b549d3568e1c795a5c2db81" have entirely different histories.

3 changed files with 90 additions and 103 deletions

View File

@ -15,29 +15,33 @@
from engine import mat4, mat4_projection, mat4_lookat, resolve_input, set_input_mat4 from engine import mat4, mat4_projection, mat4_lookat, resolve_input, set_input_mat4
class _Inputs:
__slots__ = 'projection', 'view'
def __init__(self, shader, projection, view):
self.projection = resolve_input(shader, projection)
self.view = resolve_input(shader, view)
class Camera: class Camera:
__slots__ = 'projection', 'view' __slots__ = '_projection_input', '_projection', '_view_input', '_view'
def __init__(self): def __init__(self):
self.projection = mat4() self._projection_input = None
self.view = mat4() self._projection = mat4()
self._view_input = None
self._view = mat4()
@property
def projection(self):
return self._projection
@property
def view(self):
return self._view
def set_projection(self, half_fov, ratio, near_z, far_z): def set_projection(self, half_fov, ratio, near_z, far_z):
mat4_projection(self.projection, half_fov, ratio, near_z, far_z) mat4_projection(self._projection, half_fov, ratio, near_z, far_z)
def set_view(self, origin, lookat): def set_view(self, origin, lookat):
mat4_lookat(self.view, origin, lookat) mat4_lookat(self._view, origin, lookat)
def resolve_inputs(self, shader, projection = b'u_projection', view = b'u_view'): def resolve_inputs(self, shader, projection_input = b'u_projection', view_input = b'u_view'):
return _Inputs(shader, projection, view) self._projection_input = resolve_input(shader, projection_input)
self._view_input = resolve_input(shader, view_input)
def update_inputs(self, inputs): def update_inputs(self):
set_input_mat4(inputs.projection, self.projection) set_input_mat4(self._projection_input, self._projection)
set_input_mat4(inputs.view, self.view) set_input_mat4(self._view_input, self._view)

View File

@ -14,7 +14,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from math import radians, cos from math import radians, cos
from engine import vec3, vec3_up, mat4_mul_vec3, resolve_input, set_input_vec3
from engine import *
from game.math import vec3_add, vec3_sub, vec3_scale, vec3_mul, vec3_dot from game.math import vec3_add, vec3_sub, vec3_scale, vec3_mul, vec3_dot
def _angles(start, end): def _angles(start, end):
@ -28,10 +30,6 @@ def _floats(a, b):
def _colors(a, b): def _colors(a, b):
return (a, vec3_sub(b, a)) return (a, vec3_sub(b, a))
_light_power = (
(_angles(180.0, 0.0), _floats(1.0, 1.0)),
)
_light_color = ( _light_color = (
(_angles(180.0, 0.0), _colors((1.0, 1.0, 1.0), (1.0, 1.0, 1.0))), (_angles(180.0, 0.0), _colors((1.0, 1.0, 1.0), (1.0, 1.0, 1.0))),
) )
@ -48,6 +46,11 @@ _sun_color = (
(_angles(180.0, 0.0), _colors((8.0, 8.0, 4.0), (8.0, 8.0, 4.0))), (_angles(180.0, 0.0), _colors((8.0, 8.0, 4.0), (8.0, 8.0, 4.0))),
) )
_light_power = (
(_angles(180.0, 90.0), _floats(0.0, 0.0)),
(_angles( 90.0, 0.0), _floats(0.0, 1.0))
)
def _resolve(ranges, c): def _resolve(ranges, c):
for (cmin, cmax, crng), ab in ranges: for (cmin, cmax, crng), ab in ranges:
if c >= cmin and c <= cmax: if c >= cmin and c <= cmax:
@ -62,41 +65,24 @@ def _resolve_color(ranges, c):
w, (a, b) = _resolve(ranges, c) w, (a, b) = _resolve(ranges, c)
return vec3_add(a, vec3_scale(b, w)) return vec3_add(a, vec3_scale(b, w))
class _Inputs: def resolve_inputs(shader):
__slots__ = 'light_direction', 'light_color', 'horizon_color', 'sky_color', 'sun_color' light_direction = resolve_input(shader, b'u_light_direction')
light_color = resolve_input(shader, b'u_light_color')
horizon_color = resolve_input(shader, b'u_horizon_color')
sky_color = resolve_input(shader, b'u_sky_color')
sun_color = resolve_input(shader, b'u_sun_color')
return (light_direction, light_color, horizon_color, sky_color, sun_color)
def __init__(self, shader): def from_sun(view, sun_direction, sun_power):
self.light_direction = resolve_input(shader, b'u_light_direction')
self.light_color = resolve_input(shader, b'u_light_color')
self.horizon_color = resolve_input(shader, b'u_horizon_color')
self.sky_color = resolve_input(shader, b'u_sky_color')
self.sun_color = resolve_input(shader, b'u_sun_color')
class Environment:
__slots__ = 'light_direction', 'light_color', 'horizon_color', 'sky_color', 'sun_color'
def __init__(self):
self.light_direction = vec3()
self.light_color = vec3()
self.horizon_color = vec3()
self.sky_color = vec3()
self.sun_color = vec3()
def from_sun(self, view, sun_direction, sun_power):
c = vec3_dot(sun_direction, vec3_up) c = vec3_dot(sun_direction, vec3_up)
light_power = _resolve_float(_light_power, c) * sun_power light_power = _resolve_float(_light_power, c) * sun_power
mat4_mul_vec3(self.light_direction, view, sun_direction, 0.0) light_color = vec3_scale(_resolve_color(_light_color, c), sun_power) # vec3_scale(_resolve_color(_light_color, c), light_power)
self.light_color = vec3(vec3_scale(_resolve_color(_light_color, c), light_power)) horizon_color = vec3_mul(_resolve_color(_horizon_color, c), light_color)
self.horizon_color = vec3(vec3_scale(_resolve_color(_horizon_color, c), light_power)) sky_color = vec3_mul(_resolve_color(_sky_color, c), light_color)
self.sky_color = vec3(vec3_scale(_resolve_color(_sky_color, c), light_power)) sun_color = _resolve_color(_sun_color, c)
self.sun_color = vec3(_resolve_color(_sun_color, c)) light_direction = vec3()
mat4_mul_vec3(light_direction, view, sun_direction, 0.0)
return (light_direction, vec3(light_color), vec3(horizon_color), vec3(sky_color), vec3(sun_color))
def resolve_inputs(self, shader): def update_inputs(inputs, values):
return _Inputs(shader) list(map(set_input_vec3, inputs, values))
def update_inputs(self, inputs):
set_input_vec3(inputs.light_direction, self.light_direction)
set_input_vec3(inputs.light_color, self.light_color)
set_input_vec3(inputs.horizon_color, self.horizon_color)
set_input_vec3(inputs.sky_color, self.sky_color)
set_input_vec3(inputs.sun_color, self.sun_color)

View File

@ -18,25 +18,8 @@ from math import pi, tau, dist
from engine import * from engine import *
from game import math from game import (
from game import generator math, resources, shader, camera, batch, triangles, generator, environment, sea)
from game import shader
from game import resources
from game import batch
from game import triangles
from game import sea
from game.camera import Camera
from game.environment import Environment
proj_hfov = pi * 0.25
proj_ratio = 16.0 / 9.0
proj_near_z = 8.0
proj_far_z = 3000.0
sun_direction = math.vec3_normalize((1.0, 0.0, 1.0))
sun_power = 1.0
camera_origin = (0.0, -1200.0, 500.0)
camera_lookat = (0.0, 500.0, -500.0)
def main(): def main():
print("Generating terrain...") print("Generating terrain...")
@ -125,23 +108,36 @@ def main():
cube_id = cube.spawn(tests_batch, cube_translation, cube_orientation) cube_id = cube.spawn(tests_batch, cube_translation, cube_orientation)
clouds_id = clouds.spawn(tests_batch, (0.0, 0.0, 32.0), clouds_orientation) clouds_id = clouds.spawn(tests_batch, (0.0, 0.0, 32.0), clouds_orientation)
proj_hfov = pi * 0.25
proj_ratio = 16.0 / 9.0
proj_near_z = 8.0
proj_far_z = 3000.0
terrain_environment_inputs = environment.resolve_inputs(terrain_shader)
terrain_camera = camera.Camera()
terrain_camera.set_projection(proj_hfov, proj_ratio, proj_near_z, proj_far_z)
terrain_camera.resolve_inputs(terrain_shader)
tests_environment_inputs = environment.resolve_inputs(tests_shader)
tests_camera = camera.Camera()
tests_camera.set_projection(proj_hfov, proj_ratio, proj_near_z, proj_far_z)
tests_camera.resolve_inputs(tests_shader)
sky_environment_inputs = environment.resolve_inputs(sky_shader)
sea_phase = resolve_input(sky_shader, b'u_sea_phase') sea_phase = resolve_input(sky_shader, b'u_sea_phase')
sea_polar_textures = sea.load_polar_textures(('data/sea_bump1.png', 'data/sea_bump2.png')) sea_polar_textures = sea.load_polar_textures(('data/sea_bump1.png', 'data/sea_bump2.png'))
sea_polar_sampler = resolve_input(sky_shader, b'u_sea_polar_sampler') sea_polar_sampler = resolve_input(sky_shader, b'u_sea_polar_sampler')
sea_detail_texture = sea.load_detail_texture('data/sea_bump.png') sea_detail_texture = sea.load_detail_texture('data/sea_bump.png')
sea_detail_sampler = resolve_input(sky_shader, b'u_sea_detail_sampler') sea_detail_sampler = resolve_input(sky_shader, b'u_sea_detail_sampler')
sky_triangles = create_triangles(triangles.sky_triangles(64, proj_far_z - 0.1, proj_ratio)) sky_triangles = create_triangles(triangles.sky_triangles(64, proj_far_z - 0.1, proj_ratio))
sky_camera = camera.Camera()
sky_camera.set_projection(proj_hfov, proj_ratio, proj_near_z, proj_far_z)
sky_camera.resolve_inputs(sky_shader)
camera = Camera() sun_direction = vec3(math.vec3_normalize((1.0, 0.0, 1.0)))
camera.set_projection(proj_hfov, proj_ratio, proj_near_z, proj_far_z) sun_power = 1.0
terrain_camera_inputs = camera.resolve_inputs(terrain_shader) origin = vec3((0.0, -1200.0, 500.0))
tests_camera_inputs = camera.resolve_inputs(tests_shader) lookat = vec3((0.0, 500.0, -500.0))
sky_camera_inputs = camera.resolve_inputs(sky_shader)
environment = Environment()
terrain_environment_inputs = environment.resolve_inputs(terrain_shader)
tests_environment_inputs = environment.resolve_inputs(tests_shader)
sky_environment_inputs = environment.resolve_inputs(sky_shader)
up = vec3(vec3_up) up = vec3(vec3_up)
_rotation = mat3() _rotation = mat3()
@ -169,6 +165,15 @@ def main():
begin_frame() begin_frame()
frame_begin = time.thread_time() frame_begin = time.thread_time()
mat3_rotation(_rotation, up, (current_time * 0.05) % tau)
mat3_mul_vec3(_origin, _rotation, origin)
mat3_mul_vec3(_lookat, _rotation, lookat)
terrain_camera.set_view(_origin, _lookat)
tests_camera.set_view(_origin, _lookat)
sky_camera.set_view(vec3(math.vec3_scale(_origin, 0.001)), vec3(math.vec3_scale(_lookat, 0.001)))
environment_values = environment.from_sun(terrain_camera.view, sun_direction, sun_power)
mat3_rotation(_rotation, up, (current_time * 0.21) % tau) mat3_rotation(_rotation, up, (current_time * 0.21) % tau)
mat3_mul_vec3(_blob_translation, _rotation, blob_translation) mat3_mul_vec3(_blob_translation, _rotation, blob_translation)
tests_batch.set_param(0, blob_id, _blob_translation) tests_batch.set_param(0, blob_id, _blob_translation)
@ -182,15 +187,9 @@ def main():
mat3_mul_vec3(_clouds_orientation, _rotation, clouds_orientation) mat3_mul_vec3(_clouds_orientation, _rotation, clouds_orientation)
tests_batch.set_param(1, clouds_id, _clouds_orientation) tests_batch.set_param(1, clouds_id, _clouds_orientation)
mat3_rotation(_rotation, up, (current_time * 0.05) % tau)
mat3_mul_vec3(_origin, _rotation, vec3(camera_origin))
mat3_mul_vec3(_lookat, _rotation, vec3(camera_lookat))
camera.set_view(_origin, _lookat)
environment.from_sun(camera.view, vec3(sun_direction), sun_power)
select_shader(terrain_shader) select_shader(terrain_shader)
camera.update_inputs(terrain_camera_inputs) terrain_camera.update_inputs()
environment.update_inputs(terrain_environment_inputs) environment.update_inputs(terrain_environment_inputs, environment_values)
select_texture(tiles_texture, tiles_sampler) select_texture(tiles_texture, tiles_sampler)
select_texture(heightmap, terrain_heightmap_sampler) select_texture(heightmap, terrain_heightmap_sampler)
select_texture(normalmap, terrain_normalmap_sampler) select_texture(normalmap, terrain_normalmap_sampler)
@ -205,8 +204,8 @@ def main():
unselect_shader(terrain_shader) unselect_shader(terrain_shader)
select_shader(tests_shader) select_shader(tests_shader)
camera.update_inputs(tests_camera_inputs) tests_camera.update_inputs()
environment.update_inputs(tests_environment_inputs) environment.update_inputs(tests_environment_inputs, environment_values)
select_texture(tests_texture, tests_sampler) select_texture(tests_texture, tests_sampler)
select_texture(heightmap, tests_heightmap_sampler) select_texture(heightmap, tests_heightmap_sampler)
select_texture(normalmap, tests_normalmap_sampler) select_texture(normalmap, tests_normalmap_sampler)
@ -218,11 +217,9 @@ def main():
unselect_texture(heightmap) unselect_texture(heightmap)
unselect_shader(tests_shader) unselect_shader(tests_shader)
camera.set_view(vec3(math.vec3_scale(_origin, 0.001)), vec3(math.vec3_scale(_lookat, 0.001)))
select_shader(sky_shader) select_shader(sky_shader)
camera.update_inputs(sky_camera_inputs) sky_camera.update_inputs()
environment.update_inputs(sky_environment_inputs) environment.update_inputs(sky_environment_inputs, environment_values)
set_input_float(sea_phase, (current_time * 0.023) % 1.0) set_input_float(sea_phase, (current_time * 0.023) % 1.0)
select_texture(sea_polar_textures, sea_polar_sampler) select_texture(sea_polar_textures, sea_polar_sampler)
select_texture(sea_detail_texture, sea_detail_sampler) select_texture(sea_detail_texture, sea_detail_sampler)
@ -258,8 +255,8 @@ def main():
", avg =", round((frame_avg / perf_count) * 1000.0, 2), "ms") ", avg =", round((frame_avg / perf_count) * 1000.0, 2), "ms")
# seed 666 # seed 666
# camera_origin = vec3((0.0, -1200.0, 500.0)) # origin = vec3((0.0, -1200.0, 500.0))
# camera_lookat = vec3((0.0, 500.0, -500.0)) # lookat = vec3((0.0, 500.0, -500.0))
# for x in range(10000) # for x in range(10000)
# current_time = 0 # current_time = 0
# Draw * 9999 : min = 0.2 , max = 2.16 , avg = 0.26 ms # Draw * 9999 : min = 0.2 , max = 2.16 , avg = 0.26 ms