Browse Source

Add support for directional light textures

master
C. J. Howard 3 years ago
parent
commit
cd557896d3
7 changed files with 133 additions and 84 deletions
  1. +1
    -1
      src/ecs/systems/astronomy-system.cpp
  2. +0
    -1
      src/ecs/systems/weather-system.cpp
  3. +4
    -2
      src/game/states/play-state.cpp
  4. +63
    -59
      src/renderer/passes/material-pass.cpp
  5. +9
    -9
      src/renderer/passes/material-pass.hpp
  6. +10
    -4
      src/scene/directional-light.cpp
  7. +46
    -8
      src/scene/directional-light.hpp

+ 1
- 1
src/ecs/systems/astronomy-system.cpp View File

@ -81,7 +81,7 @@ void astronomy_system::update(double t, double dt)
math::quaternion<float> sun_elevation_rotation = math::angle_axis(static_cast<float>(spherical.y), float3{-1, 0, 0});
math::quaternion<float> 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<float>, float3{1, 0, 0});
//sun_az_el_rotation = math::angle_axis((float)universal_time * math::two_pi<float>, float3{1, 0, 0});
//
//sun_light->look_at({0, 0, 0}, {0, -1, 0}, {0, 0, 1});

+ 0
- 1
src/ecs/systems/weather-system.cpp View File

@ -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)

+ 4
- 2
src/game/states/play-state.cpp View File

@ -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<gl::texture_2d>("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

+ 63
- 59
src/renderer/passes/material-pass.cpp View File

@ -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<float>(std::get<0>(viewport)), static_cast<float>(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<const scene::point_light*>(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<const scene::directional_light*>(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<float> 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<float>, {0.5f, 0.5f, 0.5f}) * math::scale(math::identity4x4<float>, {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<float> 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<const scene::spotlight*>(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<const scene::spotlight*>(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<float3>* 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;

+ 9
- 9
src/renderer/passes/material-pass.hpp View File

@ -52,8 +52,6 @@ public:
/// Sets the time tween, which is interpolated between updates
void set_time_tween(const tween<double>* time);
void set_shadow_strength(float strength);
void set_focal_point_tween(const tween<float3>* 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<double>* time_tween;
float2 mouse_position;
const tween<float3>* 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;

+ 10
- 4
src/scene/directional-light.cpp View File

@ -34,8 +34,6 @@ directional_light::directional_light():
direction(global_forward, interpolate_direction),
light_texture(nullptr),
light_texture_opacity(1.0f, math::lerp<float, float>),
light_texture_translation({0.0f, 0.0f}, math::lerp<float2, float>),
light_texture_rotation(0.0f, math::lerp_angle<float>),
light_texture_scale({1.0f, 1.0f}, math::lerp<float2, float>)
{}
@ -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();
}
}

+ 46
- 8
src/scene/directional-light.hpp View File

@ -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<float3>& get_direction_tween() const;
/// Returns the light texture opacity tween.
const tween<float>& get_light_texture_opacity_tween() const;
/// Returns the light texture scale tween.
const tween<float2>& get_light_texture_scale_tween() const;
/// @copydoc object_base::update_tweens();
virtual void update_tweens();
@ -68,8 +89,6 @@ private:
tween<float3> direction;
const gl::texture_2d* light_texture;
tween<float> light_texture_opacity;
tween<float2> light_texture_translation;
tween<float> light_texture_rotation;
tween<float2> 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<float3>& directional_light::get_direction_tween() const
{
return direction;
}
inline const gl::texture_2d* directional_light::get_light_texture() const
inline const tween<float>& directional_light::get_light_texture_opacity_tween() const
{
return light_texture;
return light_texture_opacity;
}
inline const tween<float2>& directional_light::get_light_texture_scale_tween() const
{
return light_texture_scale;
}
} // namespace scene
#endif // ANTKEEPER_SCENE_DIRECTIONAL_LIGHT_HPP

Loading…
Cancel
Save