From 8a33228dff29be13743cc75d3cf5a9232e27c51a Mon Sep 17 00:00:00 2001 From: Roz K Date: Tue, 29 Nov 2022 03:19:57 +0100 Subject: [PATCH] Bump engine submodule and move projection/view code to game. --- engine | 2 +- game/camera.py | 43 ++++++++++++++++++++++++++++++++++ game/environment.py | 12 +++++----- game/game.py | 40 +++++++++++++++++++------------ game/shaders/sky_opengles.frag | 12 +++++----- 5 files changed, 81 insertions(+), 28 deletions(-) create mode 100644 game/camera.py diff --git a/engine b/engine index 1855778..1e56cc1 160000 --- a/engine +++ b/engine @@ -1 +1 @@ -Subproject commit 1855778fa7439c308b8a79282163c52f5f93f0c6 +Subproject commit 1e56cc1c28d4f9977b55f47566c3c8050f25670c diff --git a/game/camera.py b/game/camera.py new file mode 100644 index 0000000..5e3d61d --- /dev/null +++ b/game/camera.py @@ -0,0 +1,43 @@ +# Copyright (C) 2022 RozK +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from engine import mat4, mat4_projection, mat4_lookat, resolve_input, set_input_mat4 + +class Camera: + __slots__ = '_projection_input', '_projection', '_view_input', '_view' + + def __init__(self, projection_input = b'u_projection', view_input = b'u_view'): + self._projection_input = resolve_input(projection_input) + self._projection = mat4() + self._view_input = resolve_input(view_input) + 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): + mat4_projection(self._projection, half_fov, ratio, near_z, far_z) + + def set_view(self, origin, lookat): + mat4_lookat(self._view, origin, lookat) + + def update_inputs(self): + set_input_mat4(self._projection_input, self._projection) + set_input_mat4(self._view_input, self._view) diff --git a/game/environment.py b/game/environment.py index 0c97019..348fd48 100644 --- a/game/environment.py +++ b/game/environment.py @@ -73,16 +73,16 @@ def resolve_inputs(): sun_color = resolve_input(b'u_sun_color') return (light_direction, light_color, horizon_color, sky_color, sun_color) -def from_sun(sun_direction, sun_power): +def from_sun(view, sun_direction, sun_power): c = vec3_dot(sun_direction, vec3_up) light_power = _resolve_float(_light_power, c) * sun_power light_color = vec3_scale(_resolve_color(_light_color, c), sun_power) # vec3_scale(_resolve_color(_light_color, c), light_power) horizon_color = vec3_mul(_resolve_color(_horizon_color, c), light_color) sky_color = vec3_mul(_resolve_color(_sky_color, c), light_color) sun_color = _resolve_color(_sun_color, c) - return (vec3(sun_direction), vec3(light_color), vec3(horizon_color), vec3(sky_color), vec3(sun_color)) + 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)) -_modes = (INPUT_VIEW_ORIENTATION, INPUT_IDENTITY, INPUT_IDENTITY, INPUT_IDENTITY, INPUT_IDENTITY) - -def set_inputs(inputs, values): - list(map(set_input_vec3, inputs, values, _modes)) +def update_inputs(inputs, values): + list(map(set_input_vec3, inputs, values)) diff --git a/game/game.py b/game/game.py index 2f95ae2..276c091 100644 --- a/game/game.py +++ b/game/game.py @@ -18,7 +18,7 @@ from math import pi, tau, dist from engine import * -from game import math, resources, batch, triangles, generator, environment, sea +from game import math, resources, camera, batch, triangles, generator, environment, sea def main(): print("Generating terrain...") @@ -63,7 +63,6 @@ def main(): select_vertices(tests_vertices) tests_batch = batch.Batch(3, BATCH_TRANSLATION_FORMAT_FLOAT, BATCH_ORIENTATION_FORMAT_FLOAT) unselect_vertices(tests_vertices) - unselect_shader(terrain_shader) #TODO: generator & for real print("Building tiles...") @@ -109,6 +108,9 @@ def main(): proj_ratio = 16.0 / 9.0 proj_near_z = 8.0 proj_far_z = 3000.0 + terrain_camera = camera.Camera() + terrain_camera.set_projection(proj_hfov, proj_ratio, proj_near_z, proj_far_z) + unselect_shader(terrain_shader) select_shader(sky_shader) sky_environment_inputs = environment.resolve_inputs() @@ -116,18 +118,18 @@ def main(): sea_polar_textures = sea.load_polar_textures(('data/sea_bump1.png', 'data/sea_bump2.png')) sea_detail_texture = sea.load_detail_texture('data/sea_bump.png') 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) unselect_shader(sky_shader) - sun_direction = vec3(math.vec3_normalize((1.0, 0.0, 1.0))) + sun_direction = vec3(math.vec3_normalize((1.0, 0.0, 0.0))) sun_power = 1.0 - camera = vec3((0.0, -1200.0, 500.0)) + origin = vec3((0.0, -1200.0, 500.0)) lookat = vec3((0.0, 500.0, -500.0)) - start_time = time.monotonic() - current_time = 0.0 up = vec3(vec3_up) _rotation = mat3() - _camera = vec3() + _origin = vec3() _lookat = vec3() _blob_translation = vec3() _cube_translation = vec3() @@ -135,6 +137,8 @@ def main(): _clouds_orientation = vec3() print("Running...") + start_time = time.monotonic() + current_time = 0.0 frame_min = 10000.0 frame_max = 0.0 frame_avg = 0.0 @@ -150,10 +154,8 @@ def main(): frame_begin = time.thread_time() mat3_rotation(_rotation, up, (current_time * 0.05) % tau) - mat3_mul_vec3(_camera, _rotation, camera) + mat3_mul_vec3(_origin, _rotation, origin) mat3_mul_vec3(_lookat, _rotation, lookat) - set_view(_camera, _lookat) - set_projection(proj_hfov, proj_ratio, proj_near_z, proj_far_z) mat3_rotation(_rotation, up, (current_time * 0.21) % tau) mat3_mul_vec3(_blob_translation, _rotation, blob_translation) @@ -168,13 +170,15 @@ def main(): mat3_mul_vec3(_clouds_orientation, _rotation, clouds_orientation) tests_batch.set_orientation(clouds_id, _clouds_orientation) - environment_values = environment.from_sun(sun_direction, sun_power) - select_shader(terrain_shader) select_texture(heightmap) select_texture(normalmap) - environment.set_inputs(terrain_environment_inputs, environment_values) + terrain_camera.set_view(_origin, _lookat) + terrain_camera.update_inputs() + environment_values = environment.from_sun( + terrain_camera.view, sun_direction, sun_power) + environment.update_inputs(terrain_environment_inputs, environment_values) select_texture(tiles_texture) select_vertices(tiles_vertices) @@ -195,7 +199,13 @@ def main(): unselect_shader(terrain_shader) select_shader(sky_shader) - environment.set_inputs(sky_environment_inputs, environment_values) + sky_camera.set_view( + vec3(math.vec3_scale(_origin, 0.001)), + vec3(math.vec3_scale(_lookat, 0.001))) + sky_camera.update_inputs() + environment_values = environment.from_sun( + sky_camera.view, sun_direction, sun_power) + environment.update_inputs(sky_environment_inputs, environment_values) set_input_float(sea_phase, (current_time * 0.023) % 1.0) select_texture(sea_polar_textures) select_texture(sea_detail_texture) @@ -230,7 +240,7 @@ def main(): ", avg =", round((frame_avg / perf_count) * 1000.0, 2), "ms") # seed 666 - # camera = vec3((0.0, -1200.0, 500.0)) + # origin = vec3((0.0, -1200.0, 500.0)) # lookat = vec3((0.0, 500.0, -500.0)) # for x in range(10000) # current_time = 0 diff --git a/game/shaders/sky_opengles.frag b/game/shaders/sky_opengles.frag index 61b1243..7dc3b1f 100644 --- a/game/shaders/sky_opengles.frag +++ b/game/shaders/sky_opengles.frag @@ -18,7 +18,7 @@ precision highp float; in vec3 v_position; -uniform mat4 u_view_km; // world space -> view space, unit = km +uniform mat4 u_view; // world space -> view space, unit = km uniform vec3 u_light_direction; // view space (-direction_x, -direction_y, -direction_z) uniform vec3 u_light_color; uniform vec3 u_horizon_color; @@ -26,10 +26,10 @@ uniform vec3 u_sky_color; uniform vec3 u_sun_color; uniform float u_sea_phase; -#define u_right u_view_km[0].xyz -#define u_forward u_view_km[1].xyz -#define u_up u_view_km[2].xyz -#define u_origin u_view_km[3].xyz +#define u_right u_view[0].xyz +#define u_forward u_view[1].xyz +#define u_up u_view[2].xyz +#define u_origin u_view[3].xyz uniform highp sampler2DArray u_sea_polar_sampler; uniform highp sampler2D u_sea_detail_sampler; @@ -79,7 +79,7 @@ void main(void) { t = (u_sea_phase + dot(sea_position, u_forward)) * c_detail_scale; vec3 sea_detail = normalize(c_normal_shift + texture(u_sea_detail_sampler, vec2(s, t)).xyz * c_normal_scale); //TODO: better blending, with earth normal - vec4 normal = u_view_km * vec4(normalize(sea_polar1 + sea_polar2 + sea_detail), 0.0); + vec4 normal = u_view * vec4(normalize(sea_polar1 + sea_polar2 + sea_detail), 0.0); float d = max(0.0, dot(normal.xyz, u_light_direction)); s = pow(max(0.0, dot(normal.xyz, normalize(u_light_direction - direction))), 500.0) * step(0.0, d); o_color = vec4(