diff --git a/src/ecs/systems/astronomy-system.cpp b/src/ecs/systems/astronomy-system.cpp index 1e506bb..26a8a3c 100644 --- a/src/ecs/systems/astronomy-system.cpp +++ b/src/ecs/systems/astronomy-system.cpp @@ -81,7 +81,7 @@ void astronomy_system::update(double t, double dt) math::quaternion sun_elevation_rotation = math::angle_axis(static_cast(spherical.y), float3{-1, 0, 0}); math::quaternion sun_az_el_rotation = math::normalize(sun_azimuth_rotation * sun_elevation_rotation); - sun_az_el_rotation = math::angle_axis((float)universal_time * math::two_pi, float3{1, 0, 0}); + //sun_az_el_rotation = math::angle_axis((float)universal_time * math::two_pi, float3{1, 0, 0}); // //sun_light->look_at({0, 0, 0}, {0, -1, 0}, {0, 0, 1}); diff --git a/src/ecs/systems/weather-system.cpp b/src/ecs/systems/weather-system.cpp index cf37ae8..6447f48 100644 --- a/src/ecs/systems/weather-system.cpp +++ b/src/ecs/systems/weather-system.cpp @@ -61,7 +61,6 @@ void weather_system::set_shadow_map_pass(::shadow_map_pass* pass) void weather_system::set_material_pass(::material_pass* pass) { material_pass = pass; - material_pass->set_shadow_strength(0.5f); } void weather_system::set_universal_time(double time) diff --git a/src/game/states/play-state.cpp b/src/game/states/play-state.cpp index 83b96a7..bcb2d12 100644 --- a/src/game/states/play-state.cpp +++ b/src/game/states/play-state.cpp @@ -150,6 +150,8 @@ void play_state_enter(game_context* ctx) sun->set_color(sun_color); sun->set_intensity(750.0f); sun->set_light_texture(resource_manager->load("forest-gobo.tex")); + sun->set_light_texture_scale({500, 500}); + sun->set_light_texture_opacity(0.9f); sun->look_at({2, 1, 0}, {0, 0, 0}, {0, 0, 1}); sun->update_tweens(); ctx->overworld_scene->add_object(sun); @@ -205,12 +207,12 @@ void play_state_enter(game_context* ctx) scene::model_instance* lens_model_instance = ctx->render_system->get_model_instance(ctx->lens_entity); if (lens_model_instance) { - lens_model_instance->set_culling_mask(&ctx->no_cull); + //lens_model_instance->set_culling_mask(&ctx->no_cull); } // Create lens light cone and set its parent to lens auto lens_light_cone = lens_light_cone_archetype->create(ecs_registry); - //ecs::command::bind_transform(ecs_registry, lens_light_cone, ctx->lens_entity); + ecs::command::bind_transform(ecs_registry, lens_light_cone, ctx->lens_entity); ecs::command::parent(ecs_registry, lens_light_cone, ctx->lens_entity); // Hide inactive tools diff --git a/src/renderer/passes/material-pass.cpp b/src/renderer/passes/material-pass.cpp index 7b3e407..c8fe468 100644 --- a/src/renderer/passes/material-pass.cpp +++ b/src/renderer/passes/material-pass.cpp @@ -59,8 +59,7 @@ material_pass::material_pass(gl::rasterizer* rasterizer, const gl::framebuffer* mouse_position({0.0f, 0.0f}), focal_point_tween(nullptr), shadow_map_pass(nullptr), - shadow_map(nullptr), - shadow_strength(1.0f) + shadow_map(nullptr) { max_ambient_light_count = MATERIAL_PASS_MAX_AMBIENT_LIGHT_COUNT; max_point_light_count = MATERIAL_PASS_MAX_POINT_LIGHT_COUNT; @@ -73,8 +72,10 @@ material_pass::material_pass(gl::rasterizer* rasterizer, const gl::framebuffer* point_light_attenuations = new float3[max_point_light_count]; directional_light_colors = new float3[max_directional_light_count]; directional_light_directions = new float3[max_directional_light_count]; - directional_light_matrices = new float4x4[max_directional_light_count]; directional_light_textures = new const gl::texture_2d*[max_directional_light_count]; + directional_light_texture_matrices = new float4x4[max_directional_light_count]; + directional_light_texture_opacities = new float[max_directional_light_count]; + spotlight_colors = new float3[max_spotlight_count]; spotlight_positions = new float3[max_spotlight_count]; spotlight_directions = new float3[max_spotlight_count]; @@ -90,8 +91,9 @@ material_pass::~material_pass() delete[] point_light_attenuations; delete[] directional_light_colors; delete[] directional_light_directions; - delete[] directional_light_matrices; delete[] directional_light_textures; + delete[] directional_light_texture_matrices; + delete[] directional_light_texture_opacities; delete[] spotlight_colors; delete[] spotlight_positions; delete[] spotlight_directions; @@ -121,6 +123,7 @@ void material_pass::render(render_context* context) const float2 resolution = {static_cast(std::get<0>(viewport)), static_cast(std::get<1>(viewport))}; float time = (time_tween) ? time_tween->interpolate(context->alpha) : 0.0f; + const float3& camera_position = context->camera_transform.translation; float3 focal_point = (focal_point_tween) ? focal_point_tween->interpolate(context->alpha) : float3{0, 0, 0}; float4x4 view = context->camera->get_view_tween().interpolate(context->alpha); float4x4 projection = context->camera->get_projection_tween().interpolate(context->alpha); @@ -128,6 +131,7 @@ void material_pass::render(render_context* context) const float4x4 model_view_projection; float4x4 model; float4x4 model_view; + float3x3 normal_model; float3x3 normal_model_view; float2 clip_depth; clip_depth[0] = context->camera->get_clip_near_tween().interpolate(context->alpha); @@ -175,10 +179,8 @@ void material_pass::render(render_context* context) const { point_light_colors[point_light_count] = light->get_scaled_color_tween().interpolate(context->alpha); - // Transform position into view-space float3 position = light->get_transform_tween().interpolate(context->alpha).translation; - float3 view_space_position = math::resize<3>(view * float4{position.x, position.y, position.z, 1.0f}); - point_light_positions[point_light_count] = view_space_position; + point_light_positions[point_light_count] = position; point_light_attenuations[point_light_count] = static_cast(light)->get_attenuation_tween().interpolate(context->alpha); ++point_light_count; @@ -195,28 +197,30 @@ void material_pass::render(render_context* context) const directional_light_colors[directional_light_count] = light->get_scaled_color_tween().interpolate(context->alpha); - // Transform direction into view-space float3 direction = static_cast(light)->get_direction_tween().interpolate(context->alpha); - float3 view_space_direction = math::normalize(math::resize<3>(view * math::resize<4>(-direction))); - directional_light_directions[directional_light_count] = view_space_direction; - - // Calculate a view-projection matrix from the directional light's transform - math::transform light_transform = light->get_transform_tween().interpolate(context->alpha); - float3 forward = light_transform.rotation * global_forward; - float3 up = light_transform.rotation * global_up; - - float4x4 light_view = math::look_at(light_transform.translation, light_transform.translation + forward, up); - float4x4 light_projection = math::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f); - float4x4 bias = math::translate(math::identity4x4, {0.5f, 0.5f, 0.5f}) * math::scale(math::identity4x4, {0.5f, 0.5f, 0.5f}); + directional_light_directions[directional_light_count] = direction; - //float scale_u = 1.0f; - //float scale_v = 1.0f; - //float4x4 light_projection = math::ortho(-scale_u, scale_u, -scale_v, scale_v, -1.0f, 1.0f); - directional_light_matrices[directional_light_count] = bias * light_projection * light_view; - - - directional_light_textures[directional_light_count] = directional_light->get_light_texture(); + if (directional_light->get_light_texture()) + { + directional_light_textures[directional_light_count] = directional_light->get_light_texture(); + directional_light_texture_opacities[directional_light_count] = directional_light->get_light_texture_opacity_tween().interpolate(context->alpha); + + math::transform light_transform = light->get_transform_tween().interpolate(context->alpha); + float3 forward = light_transform.rotation * global_forward; + float3 up = light_transform.rotation * global_up; + float4x4 light_view = math::look_at(light_transform.translation, light_transform.translation + forward, up); + + float2 scale = directional_light->get_light_texture_scale_tween().interpolate(context->alpha); + float4x4 light_projection = math::ortho(-scale.x, scale.x, -scale.y, scale.y, -1.0f, 1.0f); + + directional_light_texture_matrices[directional_light_count] = light_projection * light_view; + } + else + { + directional_light_textures[directional_light_count] = nullptr; + directional_light_texture_opacities[directional_light_count] = 0.0f; + } ++directional_light_count; } @@ -228,19 +232,15 @@ void material_pass::render(render_context* context) const { if (spotlight_count < max_spotlight_count) { + const scene::spotlight* spotlight = static_cast(light); + spotlight_colors[spotlight_count] = light->get_scaled_color_tween().interpolate(context->alpha); - // Transform position into view-space float3 position = light->get_transform_tween().interpolate(context->alpha).translation; - float3 view_space_position = math::resize<3>(view * float4{position.x, position.y, position.z, 1.0f}); - spotlight_positions[spotlight_count] = view_space_position; + spotlight_positions[spotlight_count] = position; - const scene::spotlight* spotlight = static_cast(light); - - // Transform direction into view-space float3 direction = spotlight->get_direction_tween().interpolate(context->alpha); - float3 view_space_direction = math::normalize(math::resize<3>(view * float4{-direction.x, -direction.y, -direction.z, 0.0f})); - spotlight_directions[spotlight_count] = view_space_direction; + spotlight_directions[spotlight_count] = direction; spotlight_attenuations[spotlight_count] = spotlight->get_attenuation_tween().interpolate(context->alpha); spotlight_cutoffs[spotlight_count] = spotlight->get_cosine_cutoff_tween().interpolate(context->alpha); @@ -255,17 +255,17 @@ void material_pass::render(render_context* context) const } } - float4x4 shadow_map_matrices[4]; - float4 shadow_map_split_distances; + float4x4 shadow_matrices_directional[4]; + float4 shadow_splits_directional; if (shadow_map_pass) { for (int i = 0; i < 4; ++i) - shadow_map_matrices[i] = shadow_map_pass->get_shadow_matrices()[i]; + shadow_matrices_directional[i] = shadow_map_pass->get_shadow_matrices()[i]; // Calculate shadow map split distances for (int i = 0; i < 4; ++i) - shadow_map_split_distances[i] = shadow_map_pass->get_split_distances()[i + 1]; + shadow_splits_directional[i] = shadow_map_pass->get_split_distances()[i + 1]; } // Sort render operations @@ -304,7 +304,6 @@ void material_pass::render(render_context* context) const { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } else { @@ -443,6 +442,8 @@ void material_pass::render(render_context* context) const parameters->mouse->upload(mouse_position); if (parameters->resolution) parameters->resolution->upload(resolution); + if (parameters->camera_position) + parameters->camera_position->upload(camera_position); if (parameters->view) parameters->view->upload(view); if (parameters->view_projection) @@ -465,10 +466,14 @@ void material_pass::render(render_context* context) const parameters->directional_light_colors->upload(0, directional_light_colors, directional_light_count); if (parameters->directional_light_directions) parameters->directional_light_directions->upload(0, directional_light_directions, directional_light_count); - if (parameters->directional_light_matrices) - parameters->directional_light_matrices->upload(0, directional_light_matrices, directional_light_count); + if (parameters->directional_light_textures) parameters->directional_light_textures->upload(0, directional_light_textures, directional_light_count); + if (parameters->directional_light_texture_matrices) + parameters->directional_light_texture_matrices->upload(0, directional_light_texture_matrices, directional_light_count); + if (parameters->directional_light_texture_opacities) + parameters->directional_light_texture_opacities->upload(0, directional_light_texture_opacities, directional_light_count); + if (parameters->spotlight_count) parameters->spotlight_count->upload(spotlight_count); if (parameters->spotlight_colors) @@ -483,14 +488,13 @@ void material_pass::render(render_context* context) const parameters->spotlight_cutoffs->upload(0, spotlight_cutoffs, spotlight_count); if (parameters->focal_point) parameters->focal_point->upload(focal_point); - if (parameters->shadow_map_matrices) - parameters->shadow_map_matrices->upload(0, shadow_map_matrices, 4); - if (parameters->shadow_map_split_distances) - parameters->shadow_map_split_distances->upload(shadow_map_split_distances); - if (parameters->shadow_map && shadow_map) - parameters->shadow_map->upload(shadow_map); - if (parameters->shadow_strength) - parameters->shadow_strength->upload(shadow_strength); + + if (parameters->shadow_map_directional && shadow_map) + parameters->shadow_map_directional->upload(shadow_map); + if (parameters->shadow_matrices_directional) + parameters->shadow_matrices_directional->upload(0, shadow_matrices_directional, 4); + if (parameters->shadow_splits_directional) + parameters->shadow_splits_directional->upload(shadow_splits_directional); } // Upload material properties to shader @@ -501,6 +505,7 @@ void material_pass::render(render_context* context) const model = operation.transform; model_view_projection = view_projection * model; model_view = view * model; + normal_model = math::transpose(math::inverse(math::resize<3, 3>(model))); normal_model_view = math::transpose(math::inverse(math::resize<3, 3>(model_view))); // Upload operation-dependent parameters @@ -510,6 +515,8 @@ void material_pass::render(render_context* context) const parameters->model_view->upload(model_view); if (parameters->model_view_projection) parameters->model_view_projection->upload(model_view_projection); + if (parameters->normal_model) + parameters->normal_model->upload(normal_model); if (parameters->normal_model_view) parameters->normal_model_view->upload(normal_model_view); if (parameters->clip_depth) @@ -535,11 +542,6 @@ void material_pass::set_time_tween(const tween* time) this->time_tween = time; } -void material_pass::set_shadow_strength(float strength) -{ - this->shadow_strength = strength; -} - void material_pass::set_focal_point_tween(const tween* focal_point) { this->focal_point_tween = focal_point; @@ -554,12 +556,14 @@ const material_pass::parameter_set* material_pass::load_parameter_set(const gl:: parameters->time = program->get_input("time"); parameters->mouse = program->get_input("mouse"); parameters->resolution = program->get_input("resolution"); + parameters->camera_position = program->get_input("camera_position"); parameters->model = program->get_input("model"); parameters->view = program->get_input("view"); parameters->projection = program->get_input("projection"); parameters->model_view = program->get_input("model_view"); parameters->view_projection = program->get_input("view_projection"); parameters->model_view_projection = program->get_input("model_view_projection"); + parameters->normal_model = program->get_input("normal_model"); parameters->normal_model_view = program->get_input("normal_model_view"); parameters->clip_depth = program->get_input("clip_depth"); parameters->log_depth_coef = program->get_input("log_depth_coef"); @@ -572,8 +576,9 @@ const material_pass::parameter_set* material_pass::load_parameter_set(const gl:: parameters->directional_light_count = program->get_input("directional_light_count"); parameters->directional_light_colors = program->get_input("directional_light_colors"); parameters->directional_light_directions = program->get_input("directional_light_directions"); - parameters->directional_light_matrices = program->get_input("directional_light_matrices"); parameters->directional_light_textures = program->get_input("directional_light_textures"); + parameters->directional_light_texture_matrices = program->get_input("directional_light_texture_matrices"); + parameters->directional_light_texture_opacities = program->get_input("directional_light_texture_opacities"); parameters->spotlight_count = program->get_input("spotlight_count"); parameters->spotlight_colors = program->get_input("spotlight_colors"); parameters->spotlight_positions = program->get_input("spotlight_positions"); @@ -581,10 +586,9 @@ const material_pass::parameter_set* material_pass::load_parameter_set(const gl:: parameters->spotlight_attenuations = program->get_input("spotlight_attenuations"); parameters->spotlight_cutoffs = program->get_input("spotlight_cutoffs"); parameters->focal_point = program->get_input("focal_point"); - parameters->shadow_map_matrices = program->get_input("shadow_map_matrices"); - parameters->shadow_map_split_distances = program->get_input("shadow_map_split_distances"); - parameters->shadow_map = program->get_input("shadow_map"); - parameters->shadow_strength = program->get_input("shadow_strength"); + parameters->shadow_map_directional = program->get_input("shadow_map_directional"); + parameters->shadow_splits_directional = program->get_input("shadow_splits_directional"); + parameters->shadow_matrices_directional = program->get_input("shadow_matrices_directional"); // Add parameter set to map of parameter sets parameter_sets[program] = parameters; diff --git a/src/renderer/passes/material-pass.hpp b/src/renderer/passes/material-pass.hpp index cbd41b5..726faca 100644 --- a/src/renderer/passes/material-pass.hpp +++ b/src/renderer/passes/material-pass.hpp @@ -52,8 +52,6 @@ public: /// Sets the time tween, which is interpolated between updates void set_time_tween(const tween* time); - void set_shadow_strength(float strength); - void set_focal_point_tween(const tween* focal_point); const ::shadow_map_pass* shadow_map_pass; @@ -70,12 +68,14 @@ private: const gl::shader_input* time; const gl::shader_input* mouse; const gl::shader_input* resolution; + const gl::shader_input* camera_position; const gl::shader_input* model; const gl::shader_input* view; const gl::shader_input* projection; const gl::shader_input* model_view; const gl::shader_input* view_projection; const gl::shader_input* model_view_projection; + const gl::shader_input* normal_model; const gl::shader_input* normal_model_view; const gl::shader_input* clip_depth; const gl::shader_input* log_depth_coef; @@ -89,8 +89,9 @@ private: const gl::shader_input* directional_light_count; const gl::shader_input* directional_light_colors; const gl::shader_input* directional_light_directions; - const gl::shader_input* directional_light_matrices; const gl::shader_input* directional_light_textures; + const gl::shader_input* directional_light_texture_matrices; + const gl::shader_input* directional_light_texture_opacities; const gl::shader_input* spotlight_count; const gl::shader_input* spotlight_colors; const gl::shader_input* spotlight_positions; @@ -100,10 +101,9 @@ private: const gl::shader_input* focal_point; - const gl::shader_input* shadow_map_matrices; - const gl::shader_input* shadow_map_split_distances; - const gl::shader_input* shadow_map; - const gl::shader_input* shadow_strength; + const gl::shader_input* shadow_map_directional; + const gl::shader_input* shadow_splits_directional; + const gl::shader_input* shadow_matrices_directional; }; const parameter_set* load_parameter_set(const gl::shader_program* program) const; @@ -113,7 +113,6 @@ private: const tween* time_tween; float2 mouse_position; const tween* focal_point_tween; - float shadow_strength; int max_ambient_light_count; int max_point_light_count; @@ -131,8 +130,9 @@ private: float3* point_light_attenuations; float3* directional_light_colors; float3* directional_light_directions; - float4x4* directional_light_matrices; const gl::texture_2d** directional_light_textures; + float4x4* directional_light_texture_matrices; + float* directional_light_texture_opacities; float3* spotlight_colors; float3* spotlight_positions; float3* spotlight_directions; diff --git a/src/scene/directional-light.cpp b/src/scene/directional-light.cpp index cf78e1a..356d207 100644 --- a/src/scene/directional-light.cpp +++ b/src/scene/directional-light.cpp @@ -34,8 +34,6 @@ directional_light::directional_light(): direction(global_forward, interpolate_direction), light_texture(nullptr), light_texture_opacity(1.0f, math::lerp), - light_texture_translation({0.0f, 0.0f}, math::lerp), - light_texture_rotation(0.0f, math::lerp_angle), light_texture_scale({1.0f, 1.0f}, math::lerp) {} @@ -44,6 +42,16 @@ void directional_light::set_light_texture(const gl::texture_2d* texture) light_texture = texture; } +void directional_light::set_light_texture_opacity(float opacity) +{ + light_texture_opacity[1] = opacity; +} + +void directional_light::set_light_texture_scale(const float2& scale) +{ + light_texture_scale[1] = scale; +} + void directional_light::update_tweens() { light::update_tweens(); @@ -52,8 +60,6 @@ void directional_light::update_tweens() if (light_texture) { light_texture_opacity.update(); - light_texture_translation.update(); - light_texture_rotation.update(); light_texture_scale.update(); } } diff --git a/src/scene/directional-light.hpp b/src/scene/directional-light.hpp index 7f7db04..b1a59da 100644 --- a/src/scene/directional-light.hpp +++ b/src/scene/directional-light.hpp @@ -42,9 +42,18 @@ public: */ void set_light_texture(const gl::texture_2d* texture); + /** + * Sets the opacity of the light texture. + * + * @param opacity Light texture opacity, on `[0, 1]`. + */ void set_light_texture_opacity(float opacity); - void set_light_texture_translation(const float2& translation); - void set_light_texture_rotation(float rotation); + + /** + * Sets the scale of the light texture. + * + * @param scale Scale of the light texture. + */ void set_light_texture_scale(const float2& scale); /// Returns light_type::directional. @@ -56,8 +65,20 @@ public: /// Returns the light texture for this light, or `nullptr` if no light texture is set. const gl::texture_2d* get_light_texture() const; + /// Returns the light texture opacity. + float get_light_texture_opacity() const; + + /// Returns the light texture scale. + const float2& get_light_texture_scale() const; + + /// Returns the light direction tween. const tween& get_direction_tween() const; - + + /// Returns the light texture opacity tween. + const tween& get_light_texture_opacity_tween() const; + + /// Returns the light texture scale tween. + const tween& get_light_texture_scale_tween() const; /// @copydoc object_base::update_tweens(); virtual void update_tweens(); @@ -68,8 +89,6 @@ private: tween direction; const gl::texture_2d* light_texture; tween light_texture_opacity; - tween light_texture_translation; - tween light_texture_rotation; tween light_texture_scale; }; @@ -83,17 +102,36 @@ inline const float3& directional_light::get_direction() const return direction[1]; } +inline const gl::texture_2d* directional_light::get_light_texture() const +{ + return light_texture; +} + +inline float directional_light::get_light_texture_opacity() const +{ + return light_texture_opacity[1]; +} + +inline const float2& directional_light::get_light_texture_scale() const +{ + return light_texture_scale[1]; +} + inline const tween& directional_light::get_direction_tween() const { return direction; } -inline const gl::texture_2d* directional_light::get_light_texture() const +inline const tween& directional_light::get_light_texture_opacity_tween() const { - return light_texture; + return light_texture_opacity; +} + +inline const tween& directional_light::get_light_texture_scale_tween() const +{ + return light_texture_scale; } } // namespace scene #endif // ANTKEEPER_SCENE_DIRECTIONAL_LIGHT_HPP -