mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-10 07:31:30 +01:00
Light the cab with the sun coming in through its windows
This commit is contained in:
@@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "stdafx.h"
|
||||
#include "rendering/common/cabprobe.h"
|
||||
|
||||
#include "rendering/common/skyocclusion.h"
|
||||
#include "utilities/Globals.h"
|
||||
#include "utilities/Logs.h"
|
||||
#include "utilities/utilities.h"
|
||||
@@ -69,6 +70,7 @@ void cab_probe::release()
|
||||
gpu_release();
|
||||
m_size = 0;
|
||||
m_valid = false;
|
||||
m_masked = false;
|
||||
}
|
||||
|
||||
bool cab_probe::update_wanted(TDynamicObject const *Vehicle, TModel3d const *Cab, glm::vec3 const &Center, glm::vec3 const &Extent, gfx::local_lights::light const *Lamp, unsigned int const Framestamp)
|
||||
@@ -81,22 +83,31 @@ bool cab_probe::update_wanted(TDynamicObject const *Vehicle, TModel3d const *Cab
|
||||
if (size != m_size)
|
||||
allocate(size);
|
||||
m_valid = false;
|
||||
m_masked = false;
|
||||
}
|
||||
if ((m_size == 0) || (Vehicle == nullptr) || (Cab == nullptr) || (Extent == glm::vec3{0.f}))
|
||||
{
|
||||
// with no cab drawn nothing reads the probe; once there is one again it may be another
|
||||
m_valid = false;
|
||||
m_masked = false;
|
||||
return false;
|
||||
}
|
||||
auto const lamp{Lamp != nullptr ? Lamp->color : glm::vec3{0.f}};
|
||||
auto const lampchange{glm::length(lamp - m_lamp)};
|
||||
auto const lampchanged{(lampchange > 0.f) && ((max_component(m_lamp) <= 0.f) || (max_component(lamp) <= 0.f) || (lampchange > LAMP_CHANGED * glm::length(m_lamp)))};
|
||||
if ((Vehicle != m_vehicle) || (Cab != m_cab) || (Center != m_center) || (Extent != m_extent) || lampchanged)
|
||||
if ((Vehicle != m_vehicle) || (Cab != m_cab) || (Center != m_center) || (Extent != m_extent))
|
||||
{
|
||||
// the mask is of another cab
|
||||
m_valid = false;
|
||||
m_masked = false;
|
||||
}
|
||||
if (lampchanged)
|
||||
{
|
||||
m_valid = false;
|
||||
}
|
||||
// the moving parts of the cab and the lights of the desk are followed every few frames
|
||||
if (m_valid && (Framestamp - m_drawnframe < static_cast<unsigned int>(std::max(Global.gfx_cabprobe_interval, 1))))
|
||||
// the moving parts of the cab, the lights of the desk and the sun are followed every few frames; a probe drawn without its mask
|
||||
// is drawn again at once
|
||||
if (m_valid && (false == m_settle) && (Framestamp - m_drawnframe < static_cast<unsigned int>(std::max(Global.gfx_cabprobe_interval, 1))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -124,6 +135,37 @@ void cab_probe::setup_drawing(gl::scene_ubs &Scene, gfx::local_lights::light con
|
||||
Scene.cab_probe_lamp_shadow = Shadowweights;
|
||||
}
|
||||
|
||||
void cab_probe::setup_sun(gl::scene_ubs &Scene, TDynamicObject const *Vehicle, glm::vec3 const &Tosun, glm::vec3 const &Sunlight, glm::dvec3 const &Camera) const
|
||||
{
|
||||
Scene.cab_probe_sun = glm::vec4{0.f};
|
||||
Scene.cab_probe_sun_color = glm::vec4{0.f};
|
||||
Scene.cab_probe_sun_box = glm::vec4{m_extent, 0.f};
|
||||
Scene.cab_probe_sun_world = glm::vec4{0.f};
|
||||
if ((Vehicle == nullptr) || (false == m_masked) || (Global.gfx_cabprobe_sun <= 0.f) || (glm::length(Tosun) <= 0.f))
|
||||
return;
|
||||
auto const rotation{glm::dmat3{Vehicle->mMatrix}};
|
||||
auto const middle{Vehicle->GetPosition() + rotation * glm::dvec3{m_center}};
|
||||
// the scenery around the cab holds the sun back as it does in the shading (the vehicle's light level of the environment flags with
|
||||
// Global.gfx_tunnelflags, as walk_sunlight() takes it in Render_cab())
|
||||
auto share{1.f};
|
||||
if (Global.gfx_tunnelflags)
|
||||
{
|
||||
auto const shade{vehicle_shade(Vehicle)};
|
||||
share = (shade > 0.f ? shade : 1.f);
|
||||
}
|
||||
else if (auto const *occlusion{sky_occlusion::current()})
|
||||
{
|
||||
share = std::clamp(occlusion->sample(middle).y, 0.f, 1.f);
|
||||
}
|
||||
auto const light{Sunlight * (share * Global.gfx_cabprobe_sun)};
|
||||
if (max_component(light) <= 0.f)
|
||||
return;
|
||||
auto const tosun{glm::normalize(glm::vec3{glm::inverse(rotation) * glm::dvec3{Tosun}})};
|
||||
Scene.cab_probe_sun = glm::vec4{tosun, 1.f};
|
||||
Scene.cab_probe_sun_color = glm::vec4{light, 0.f};
|
||||
Scene.cab_probe_sun_world = glm::vec4{glm::vec3{middle - Camera}, 0.f};
|
||||
}
|
||||
|
||||
void cab_probe::begin()
|
||||
{
|
||||
m_cpustart = std::chrono::steady_clock::now();
|
||||
@@ -133,6 +175,9 @@ void cab_probe::begin()
|
||||
void cab_probe::end(std::uint32_t const Drawcalls)
|
||||
{
|
||||
gpu_end();
|
||||
// the mask was copied from this drawing: a drawing without it is made again with it
|
||||
m_settle = (false == m_masked);
|
||||
m_masked = true;
|
||||
m_valid = true;
|
||||
m_drawcalls = Drawcalls;
|
||||
++m_updatecount;
|
||||
@@ -182,6 +227,19 @@ int cab_probe::sh_size() const
|
||||
return std::max(m_size >> sh_level(), 1);
|
||||
}
|
||||
|
||||
int cab_probe::mask_level() const
|
||||
{
|
||||
auto level{0};
|
||||
while ((m_size >> level) > static_cast<int>(gl::CAB_PROBE_MASK_SIZE))
|
||||
++level;
|
||||
return level;
|
||||
}
|
||||
|
||||
int cab_probe::mask_size() const
|
||||
{
|
||||
return std::max(m_size >> mask_level(), 1);
|
||||
}
|
||||
|
||||
std::string cab_probe::info() const
|
||||
{
|
||||
if (m_size == 0)
|
||||
@@ -199,6 +257,7 @@ void cab_probe::draw_debug_ui()
|
||||
ImGui::SliderInt("frames between its updates (gfx.cabprobe.interval)", &Global.gfx_cabprobe_interval, 1, 60);
|
||||
ImGui::SliderFloat("light bounced around the cab (gfx.cabprobe.bounce)", &Global.gfx_cabprobe_bounce, 0.f, 4.f);
|
||||
ImGui::Checkbox("the cab reflects itself (gfx.cabprobe.reflections)", &Global.gfx_cabprobe_reflections);
|
||||
ImGui::SliderFloat("sun through the windows (gfx.cabprobe.sun)", &Global.gfx_cabprobe_sun, 0.f, 4.f);
|
||||
ImGui::TextUnformatted(info().c_str());
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,12 @@ namespace gfx
|
||||
// light lights the cab again, in place of the share of the light of the lamp the ambient light kept (Global.gfx_lights_cab_bounce),
|
||||
// and the cab reflects itself where the screen space reflections don't find it, the box standing for its walls; what the cab
|
||||
// shows there is the light of the lamp it reflects and its albedo lit by the ambient light of the reflecting surface.
|
||||
// the ambient light and the sun are left out of the probe: the cab gets them as before
|
||||
// the ambient light is left out of the probe, the cab gets it as before. the sun (the moon) lights the probe where it comes in
|
||||
// through the windows (Global.gfx_cabprobe_sun), so the light which bounces around the cab is also the light of the sun where it
|
||||
// falls in the cab; the cab gets the sun itself from the shading, as before. where the windows are the probe drawn last tells:
|
||||
// a small level of its albedo is copied after each drawing (the mask, CAB_PROBE_MASK_TEX), and the ray towards the sun is taken
|
||||
// from a point of the cab to the box of the cab and looked up in it. the first drawing of a cab has no mask yet, so it's drawn
|
||||
// without the sun and again in the next frame
|
||||
class cab_probe
|
||||
{
|
||||
public:
|
||||
@@ -54,6 +59,10 @@ class cab_probe
|
||||
// the fields of the block of the scene the drawing of the probe reads: the cab lamp (Lamp, at Lamplocal in the space of the cab
|
||||
// model, nullptr: none) with its shadow map when Shadows (Shadowweights: the headlight_weights of the map)
|
||||
void setup_drawing(gl::scene_ubs &Scene, gfx::local_lights::light const *Lamp, glm::vec3 const &Lamplocal, bool const Shadows, glm::vec4 const &Shadowweights) const;
|
||||
// the fields of the block of the scene the drawing of the probe takes the sun with: Vehicle the vehicle whose cab is drawn, Tosun the
|
||||
// direction towards the sun (the moon), world space, Sunlight its light as the shading gets it (the colour of the light buffer times
|
||||
// its intensity), Camera the camera of the main view (world space). no sun until the mask holds the cab
|
||||
void setup_sun(gl::scene_ubs &Scene, TDynamicObject const *Vehicle, glm::vec3 const &Tosun, glm::vec3 const &Sunlight, glm::dvec3 const &Camera) const;
|
||||
// the drawing to the probe: the target, the viewport, the cleared faces, the state of the faces. the cab is to be drawn with the
|
||||
// programs of the probe and a modelview from the space of the cab model to the space of the probe (model_to_probe())
|
||||
void begin();
|
||||
@@ -79,6 +88,14 @@ class cab_probe
|
||||
// the level of the mipmaps the spherical harmonics are taken from, and its size
|
||||
int sh_level() const;
|
||||
int sh_size() const;
|
||||
// the level of the mipmaps of the albedo the mask is a copy of, and its size
|
||||
int mask_level() const;
|
||||
int mask_size() const;
|
||||
// whether the mask holds the cab being drawn (the drawing of the probe reads it then)
|
||||
bool masked() const
|
||||
{
|
||||
return m_masked;
|
||||
}
|
||||
// line for the statistics of the debug panel
|
||||
std::string info() const;
|
||||
// controls and counters for the debug window
|
||||
@@ -99,6 +116,9 @@ class cab_probe
|
||||
|
||||
int m_level{-1};
|
||||
bool m_valid{false};
|
||||
// the mask holds the cab drawn; the probe was drawn without it and is drawn again in the next frame
|
||||
bool m_masked{false};
|
||||
bool m_settle{false};
|
||||
TDynamicObject const *m_vehicle{nullptr};
|
||||
TModel3d const *m_cab{nullptr};
|
||||
glm::vec3 m_center{0.f};
|
||||
|
||||
@@ -174,12 +174,15 @@ bool scene_walk::Render_lowpoly( TDynamicObject *Dynamic, float const Squaredist
|
||||
1.f )
|
||||
- luminance,
|
||||
0.f, 1.f ) );
|
||||
// the sun coming in through the windows bounces around the interior
|
||||
model_ubs.cab_interior = 2.f;
|
||||
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), Squaredistance );
|
||||
// HACK: if the model has low poly interior, we presume the load is placed inside and also affected by reduced light level
|
||||
if( Dynamic->mdLoad ) {
|
||||
// renderowanie nieprzezroczystego ładunku
|
||||
Render( Dynamic->mdLoad, Dynamic->Material(), Squaredistance, { 0.f, Dynamic->LoadOffset, 0.f }, {} );
|
||||
}
|
||||
model_ubs.cab_interior = 0.f;
|
||||
walk_sunlight( gfx::vehicle_shade( Dynamic ) > 0.f ? gfx::vehicle_shade( Dynamic ) : 1.f );
|
||||
}
|
||||
else {
|
||||
@@ -2886,7 +2889,9 @@ bool scene_walk::Render_Alpha(TDynamicObject *Dynamic)
|
||||
// render
|
||||
if( Dynamic->mdLowPolyInt ) {
|
||||
// low poly interior
|
||||
model_ubs.cab_interior = 2.f;
|
||||
Render_Alpha( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
|
||||
model_ubs.cab_interior = 0.f;
|
||||
}
|
||||
if( Dynamic->mdModel ) {
|
||||
// main model
|
||||
|
||||
Reference in New Issue
Block a user