17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-08 22:07:20 +01:00

Light the cab with cablight/dashboardlight light points of the cab model

This commit is contained in:
2026-10-28 20:55:45 +01:00
parent 8f891fdc14
commit 9904eddd0d
22 changed files with 512 additions and 214 deletions

View File

@@ -348,8 +348,9 @@ void vulkan14_renderer::render_cab_probe()
{
vehicle = nullptr;
}
// the cab lamp lights the probe when it's a light of the frame
auto const *lamp{(vehicle != nullptr) && (m_locallights.cab_lamp_vehicle() == vehicle) ? m_locallights.cab_lamp() : nullptr};
// the brightest light of the cab lights the probe when it's a light of the frame
auto const *principal{(vehicle != nullptr) && (m_locallights.cab_lamp_vehicle() == vehicle) ? m_locallights.cab_principal() : nullptr};
auto const *lamp{principal != nullptr ? &principal->source : nullptr};
if (false == probe.update_wanted(vehicle, (vehicle != nullptr ? vehicle->mdKabina : nullptr), center, extent, lamp, m_framestamp))
{
return;
@@ -360,9 +361,9 @@ void vulkan14_renderer::render_cab_probe()
return;
}
ctx.passes.begin_pass("cab probe");
// the lamp with its shadow map, when the map holds the shadows of the lamp where it is
auto const shadows{(lamp != nullptr) && scene.lamps.ready(vehicle) && (scene.lamps.lamp() == m_locallights.cab_lamp_local())};
probe.setup_drawing(scene_ubs, lamp, m_locallights.cab_lamp_local(), shadows, scene.lamps.weights());
// the light with its shadow map, when the map holds the shadows of the light where it is
auto const slot{principal != nullptr ? scene.lamps.cab_slot_of(vehicle, *principal) : -1};
probe.setup_drawing(scene_ubs, lamp, (principal != nullptr ? principal->local : glm::vec3{0.f}), (slot >= 0), (slot >= 0 ? scene.lamps.weights(static_cast<std::size_t>(slot)) : glm::vec4{0.f}));
// the sun coming in through the windows, as the shading of the last frame got it. the mask is read once it was copied
probe.setup_sun(scene_ubs, vehicle, -m_sunlight.direction, glm::vec3{light_data.lights[0].color} * light_data.lights[0].intensity, m_colorpass.pass_camera.position());
if (probe.mask_map() == nullptr)

View File

@@ -1629,7 +1629,7 @@ void vulkan14_renderer::render_viewport(std::size_t const Index)
}
if (vp.main)
{
render_weather_view(OpenGLMatrices.data(GL_PROJECTION), glm::mat4{m_colorpass.pass_camera.modelview()}, m_colorpass.pass_camera.position(), fogtarget, (m_cablamplit && clustered) ? 1 : -1);
render_weather_view(OpenGLMatrices.data(GL_PROJECTION), glm::mat4{m_colorpass.pass_camera.modelview()}, m_colorpass.pass_camera.position(), fogtarget, (m_cablamplit && clustered) ? m_cablamps : 0);
}
m_weatherstate.setup_pass(vp.main, fogtarget);
upload_weather_block();
@@ -3789,28 +3789,35 @@ void vulkan14_renderer::update_lights(light_array &Lights, bool const Headlights
std::size_t light_i = 1;
m_lights_dropped = 0;
// the lights other than the headlights are only taken from the lists of the clusters. the lamp of the occupied cab goes first
// the lights other than the headlights are only taken from the lists of the clusters. the lights of the occupied cab go first
auto const locallights{Headlights && Clustered};
m_cablamplit = false;
m_cablamps = 0;
if (locallights)
{
if (auto const *lamp{m_locallights.cab_lamp()})
auto const *vehicle{m_locallights.cab_lamp_vehicle()};
auto const &lamps{m_context->scene.lamps};
for (auto const &cablight : m_locallights.cab_lights())
{
auto &light{light_data.lights[light_i++]};
write_local_light(light, *lamp, camera, mv);
m_cablamplit = true;
auto const *vehicle{m_locallights.cab_lamp_vehicle()};
auto const &lamps{m_context->scene.lamps};
if (lamps.ready(vehicle))
if (light_i >= gl::MAX_LIGHTS)
{
// view space to the space of the map: the space of the cab model, with the lamp at the origin. the vehicle is where it
break;
}
auto &light{light_data.lights[light_i++]};
write_local_light(light, cablight.source, camera, mv);
++m_cablamps;
if (auto const slot{lamps.cab_slot_of(vehicle, cablight)}; slot >= 0)
{
// view space to the space of the map: the space of the cab model, with the light at the origin. the vehicle is where it
// is now, the map stays right as it moves
auto const toworld{glm::dmat4{glm::transpose(glm::mat3{mv})}};
auto const tomap{glm::translate(glm::dmat4{1.0}, -glm::dvec3{lamps.lamp()}) * glm::inverse(vehicle->mMatrix) * glm::translate(glm::dmat4{1.0}, camera - vehicle->GetPosition()) * toworld};
auto const tomap{glm::translate(glm::dmat4{1.0}, -glm::dvec3{lamps.cab(static_cast<std::size_t>(slot)).lamp}) * glm::inverse(vehicle->mMatrix) *
glm::translate(glm::dmat4{1.0}, camera - vehicle->GetPosition()) * toworld};
light.headlight_projection = glm::mat4{tomap};
light.headlight_weights = lamps.weights();
light.headlight_weights = lamps.weights(static_cast<std::size_t>(slot));
}
}
m_cablamplit = (m_cablamps > 0);
}
auto const headlightsstart{light_i};
for (auto const &scenelight : Lights.data)

View File

@@ -110,26 +110,34 @@ void vulkan14_renderer::render_local_shadows()
auto &lamps{m_context->scene.lamps};
// only the light buffers with the lamps read the maps
auto const *vehicle{Global.gfx_lights_clustered ? m_locallights.cab_lamp_vehicle() : nullptr};
if (false == lamps.update_wanted(vehicle, (vehicle != nullptr ? vehicle->mdKabina : nullptr), m_locallights.cab_lamp_local(), m_framestamp))
lamps.update_cab(vehicle, (vehicle != nullptr ? vehicle->mdKabina : nullptr), m_locallights.cab_lights(), m_framestamp);
if (lamps.cab_draws().empty())
{
return;
}
m_context->passes.begin_pass("lamp shadows");
// the cab drawn by the shadow pass, with the programs of the cube map. the camera is put at the vehicle, which Render_cab()
// places the cab relative to, and the modelview takes the cab model to the space of the map
// the cab drawn by the shadow pass to the map of each light, with the programs of the cube map. the camera is put at the vehicle,
// which Render_cab() places the cab relative to, and the modelview takes the cab model to the space of the map
m_renderpass.draw_mode = rendermode::shadows;
m_renderpass.pass_camera.position() = vehicle->GetPosition();
m_renderpass.draw_stats = {};
OpenGLMatrices.mode(GL_MODELVIEW);
OpenGLMatrices.load_matrix(glm::mat4{glm::translate(glm::dmat4{1.0}, -glm::dvec3{lamps.lamp()}) * glm::inverse(vehicle->mMatrix)});
lamps.begin();
begin_local_shadow_rendering();
begin_local_shadow_target();
m_cubeshadows = true;
Render_cab(vehicle, 0.0f, false);
m_cubeshadows = false;
end_local_shadow_rendering();
lamps.end(static_cast<std::uint32_t>(m_renderpass.draw_stats.drawcalls));
auto const previousnear{scene_ubs.shadow_fit.y};
for (auto const slot : lamps.cab_draws())
{
m_renderpass.draw_stats = {};
OpenGLMatrices.load_matrix(glm::mat4{glm::translate(glm::dmat4{1.0}, -glm::dvec3{lamps.cab(slot).lamp}) * glm::inverse(vehicle->mMatrix)});
lamps.begin(slot);
// the near plane of the map, for shadowcube.vert, in the scene block begin_local_shadow_target() uploads
scene_ubs.shadow_fit.y = lamps.cab(slot).nearplane;
begin_local_shadow_rendering();
begin_local_shadow_target();
m_cubeshadows = true;
Render_cab(vehicle, 0.0f, false);
m_cubeshadows = false;
end_local_shadow_rendering();
lamps.end(static_cast<std::uint32_t>(m_renderpass.draw_stats.drawcalls));
}
scene_ubs.shadow_fit.y = previousnear;
m_renderpass = m_colorpass;
m_context->passes.end_pass();
}

View File

@@ -461,7 +461,7 @@ class vulkan14_renderer : public gfx_renderer, public gfx::scene_walk
void make_cloud_noise();
void upload_weather_block();
void update_weather();
void render_weather_view(glm::mat4 const &Projection, glm::mat4 const &View, glm::dvec3 const &Camera, glm::ivec2 const &Size, int const Cablamp);
void render_weather_view(glm::mat4 const &Projection, glm::mat4 const &View, glm::dvec3 const &Camera, glm::ivec2 const &Size, int const Cablamps);
void render_sky_weather(glm::mat4 const &Projection, bool const Mainview);
// the ambient occlusion (vulkan14ao.cpp): the resources, and the occlusion of a viewport multiplied into its colour
bool init_ao(std::string &Reason);

View File

@@ -98,9 +98,9 @@ void local_shadow_maps::let_go(std::shared_ptr<image> &Map, std::vector<VkImageV
Map.reset();
}
bool local_shadow_maps::gpu_allocate(int const Size)
bool local_shadow_maps::gpu_allocate(int const Count, int const Size)
{
return make(m_cab, m_cabviews, Size, 6 * (cab_slot + 1), true, "lamp shadow map");
return make(m_cab, m_cabviews, Size, 6 * Count, true, "cab light shadow maps");
}
void local_shadow_maps::gpu_release()
@@ -129,9 +129,9 @@ void local_shadow_maps::gpu_release_headlights()
let_go(m_headlights, m_headlightviews);
}
void local_shadow_maps::gpu_begin_cab()
void local_shadow_maps::gpu_begin_cab(std::size_t const Slot)
{
m_target = draw_target{m_cab.get(), m_cabviews.empty() ? VK_NULL_HANDLE : m_cabviews[cab_slot], static_cast<std::uint32_t>(m_size), 0x3f, true, true};
m_target = draw_target{m_cab.get(), (Slot < m_cabviews.size()) ? m_cabviews[Slot] : VK_NULL_HANDLE, static_cast<std::uint32_t>(m_size), 0x3f, true, true};
}
void local_shadow_maps::gpu_begin_lamp(int const Scenerycube, int const Workingcube, bool const Vehicles)

View File

@@ -74,13 +74,13 @@ class local_shadow_maps : public gfx::local_shadows
}
protected:
bool gpu_allocate(int const Size) override;
bool gpu_allocate(int const Count, int const Size) override;
void gpu_release() override;
bool gpu_allocate_lamps(int const Count, int const Size) override;
void gpu_release_lamps() override;
bool gpu_allocate_headlights(int const Count, int const Size) override;
void gpu_release_headlights() override;
void gpu_begin_cab() override;
void gpu_begin_cab(std::size_t const Slot) override;
void gpu_end_cab() override {}
void gpu_begin_lamp(int const Scenerycube, int const Workingcube, bool const Vehicles) override;
void gpu_end_lamp() override {}

View File

@@ -114,12 +114,12 @@ struct inject_block
glm::vec3 previous_camera;
float pad1;
glm::vec4 options;
std::int32_t cablamp;
std::int32_t cablamps;
std::int32_t pad2;
glm::vec2 previous_slicing;
glm::vec2 jitter;
};
static_assert(offsetof(inject_block, cablamp) == 256, "the layout of the block of fog_inject.comp");
static_assert(offsetof(inject_block, cablamps) == 256, "the layout of the block of fog_inject.comp");
struct integrate_constants
{
glm::ivec3 grid;
@@ -460,9 +460,9 @@ void vulkan14_renderer::update_weather()
}
// the clouds and the fog volume of the colour pass of the main view (opengl46_weather::render_view()): Projection and View
// (rotation, world axes to the view) of its camera, Size of the target, Cablamp the light of the cab lamp or -1. the lights, the
// (rotation, world axes to the view) of its camera, Size of the target, Cablamps the number of the lights of the cab, from the light 1 on. the lights, the
// clusters and the block of the scene of the pass are written, the shadow map drawn. outside a rendering
void vulkan14_renderer::render_weather_view(glm::mat4 const &Projection, glm::mat4 const &View, glm::dvec3 const &Camera, glm::ivec2 const &Size, int const Cablamp)
void vulkan14_renderer::render_weather_view(glm::mat4 const &Projection, glm::mat4 const &View, glm::dvec3 const &Camera, glm::ivec2 const &Size, int const Cablamps)
{
auto &ctx{*m_context};
auto &weather{ctx.scene.weather};
@@ -568,7 +568,7 @@ void vulkan14_renderer::render_weather_view(glm::mat4 const &Projection, glm::ma
auto const sunshadows{Global.gfx_fog_shadows && Global.gfx_shadowmap_enabled};
auto const share{temporal ? std::clamp(Global.gfx_fog_temporal_share, 0.02f, 1.f) : 1.f};
block.options = glm::vec4{share, Global.gfx_fog_lights, sunshadows ? 1.f : 0.f, Global.gfx_fog_shadows ? 1.f : 0.f};
block.cablamp = Cablamp;
block.cablamps = Cablamps;
block.previous_slicing = glm::vec2{previousfog.slicing.x, previousfog.slicing.z};
block.jitter = glm::vec2{jitter.x, jitter.y};
auto const slice{ctx.ring.allocate(sizeof(block), ctx.device.caps().limits.minUniformBufferOffsetAlignment)};