mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-02 17:29:14 +01:00
Shade the sky and the sun by the scenery around the camera instead of the track environment flags
This commit is contained in:
@@ -218,6 +218,7 @@ bool opengl46_renderer::Init(GLFWwindow *Window)
|
||||
m_ao.init();
|
||||
m_localshadows.init();
|
||||
m_cabprobe.init();
|
||||
m_skyocclusion.init();
|
||||
}
|
||||
catch (gl::shader_exception const &e)
|
||||
{
|
||||
@@ -684,11 +685,15 @@ bool opengl46_renderer::Render()
|
||||
// lamps of models and vehicles around the camera and the cab lamp, for the views of the frame to take into their light buffers
|
||||
if ((false == Global.gfx_skiprendering) && (simulation::Region != nullptr))
|
||||
m_locallights.gather(Global.pCamera.Pos, *simulation::Region, m_geometry, m_framestamp);
|
||||
// the occlusion of the sky by the scenery around the camera: the tiles which came in, what the background worked out
|
||||
if (false == Global.gfx_skiprendering)
|
||||
m_skyocclusion.update(simulation::Region, Global.pCamera.Pos, -m_sunlight.direction);
|
||||
}
|
||||
else
|
||||
{
|
||||
// a scenery is being loaded: the cells, instances and models the lights were taken from may be gone
|
||||
m_locallights.reset();
|
||||
m_skyocclusion.clear();
|
||||
m_localshadows.reset_lamps();
|
||||
m_localshadows.reset_headlights();
|
||||
// and so may the tracks the sleeper records were made for, and the models drawn on their own
|
||||
@@ -1055,6 +1060,7 @@ void opengl46_renderer::SwapBuffers()
|
||||
", off in this view\n" ) :
|
||||
std::string{} )
|
||||
+ ( Global.gfx_cabprobe > 0 ? " " + m_cabprobe.info() + "\n" : std::string{} )
|
||||
+ ( Global.gfx_skyvisibility > 0 ? " " + m_skyocclusion.info() + "\n" : std::string{} )
|
||||
+ shadowcascadestext
|
||||
+ " instance buffer: " + std::to_string( m_instancestream->used() / static_cast<GLsizeiptr>( sizeof( glm::mat4 ) ) ) + " matrices, "
|
||||
+ std::to_string( m_instancestream->size() / 1024 ) + " KiB\n"
|
||||
@@ -1471,6 +1477,8 @@ void opengl46_renderer::draw_debug_ui()
|
||||
m_ao.draw_debug_ui(!m_viewports.empty() && m_viewports.front()->ssao_tex != nullptr);
|
||||
m_cabprobe.draw_debug_ui();
|
||||
ImGui::Separator();
|
||||
m_skyocclusion.draw_debug_ui();
|
||||
ImGui::Separator();
|
||||
m_ssr.draw_debug_ui(nullptr);
|
||||
}
|
||||
ImGui::End();
|
||||
@@ -1655,6 +1663,8 @@ void opengl46_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
// pass of the main view only
|
||||
scene_ubs.env_params = glm::vec4{Global.gfx_ambient_groundalbedo, 0.f, 0.f, 0.f};
|
||||
gfx::screen_reflections::clear(scene_ubs);
|
||||
// the occlusion of the sky by the scenery, seen from the camera of the view
|
||||
m_skyocclusion.setup_scene(scene_ubs, m_colorpass.pass_camera.position());
|
||||
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
|
||||
scene_ubs.inv_view = glm::inverse( glm::mat4{ glm::mat3{ m_colorpass.pass_camera.modelview() } } );
|
||||
scene_ubo->update(scene_ubs);
|
||||
@@ -1675,6 +1685,8 @@ void opengl46_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
m_localshadows.bind();
|
||||
// the probe of the cab, or the stand-ins
|
||||
m_cabprobe.bind();
|
||||
// the maps of the occlusion of the sky, or the stand-ins
|
||||
m_skyocclusion.bind();
|
||||
|
||||
if (Global.gfx_shadowmap_enabled && vp.main)
|
||||
{
|
||||
@@ -5730,6 +5742,8 @@ void opengl46_renderer::Preview_Color(TAnimModel *Instance, float const Squaredi
|
||||
scene_ubs.cascade_end[idx] = std::numeric_limits<float>::max();
|
||||
}
|
||||
scene_ubs.shadow_fit = glm::vec4{0.f};
|
||||
// the model stands on its own, nothing around it
|
||||
gfx::sky_occlusion::clear_scene(scene_ubs);
|
||||
scene_ubo->update(scene_ubs);
|
||||
scene_ubo->bind_uniform();
|
||||
// the sun is the only light, and there's no fog
|
||||
@@ -6113,13 +6127,8 @@ void opengl46_renderer::Update_Lights(light_array &Lights, bool const Headlights
|
||||
renderlight.position = lightoffset;
|
||||
renderlight.direction = scenelight.direction;
|
||||
|
||||
auto luminance = static_cast<float>(Global.fLuminance);
|
||||
// adjust luminance level based on vehicle's location, e.g. tunnels
|
||||
auto const environment = scenelight.owner->fShade;
|
||||
if (environment > 0.f)
|
||||
{
|
||||
luminance *= environment;
|
||||
}
|
||||
auto const luminance = static_cast<float>(Global.fLuminance) * gfx::vehicle_light_level(scenelight.owner);
|
||||
renderlight.diffuse = glm::vec4{glm::max(glm::vec3{colors::none}, scenelight.color - glm::vec3{luminance}), renderlight.diffuse[3]};
|
||||
renderlight.ambient = glm::vec4{glm::max(glm::vec3{colors::none}, scenelight.color * glm::vec3{scenelight.intensity} - glm::vec3{luminance}), renderlight.ambient[3]};
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "rendering/common/locallights.h"
|
||||
#include "rendering/opengl46/opengl46localshadows.h"
|
||||
#include "rendering/opengl46/opengl46cabprobe.h"
|
||||
#include "rendering/opengl46/opengl46skyocclusion.h"
|
||||
#include "rendering/opengl46/opengl46instancecull.h"
|
||||
#include "rendering/opengl46/opengl46hiz.h"
|
||||
#include "rendering/opengl46/opengl46shadowfit.h"
|
||||
@@ -783,6 +784,8 @@ class opengl46_renderer : public gfx_renderer, public gfx::scene_walk {
|
||||
// the probe of the occupied cab, and the colour mode draws the cab into it with its programs (Render_cab_probe())
|
||||
opengl46_cab_probe m_cabprobe;
|
||||
bool m_cabprobepass = false;
|
||||
// the occlusion of the sky and of the sun by the scenery around the camera (tunnels, bridges, roofs: the track T)
|
||||
opengl46_sky_occlusion m_skyocclusion;
|
||||
|
||||
double m_precipitationrotation;
|
||||
|
||||
|
||||
97
rendering/opengl46/opengl46skyocclusion.cpp
Normal file
97
rendering/opengl46/opengl46skyocclusion.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "rendering/opengl46/opengl46skyocclusion.h"
|
||||
|
||||
#include "gl/ubo.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// a toroidal map read texel by texel (textureGather): nearest, repeated
|
||||
GLuint make_map(GLenum const Format, int const Side)
|
||||
{
|
||||
GLuint texture{0};
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &texture);
|
||||
glTextureStorage2D(texture, 1, Format, Side, Side);
|
||||
glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTextureParameteri(texture, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTextureParameteri(texture, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
return texture;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
opengl46_sky_occlusion::~opengl46_sky_occlusion()
|
||||
{
|
||||
gpu_release();
|
||||
if (m_emptyheights != 0)
|
||||
glDeleteTextures(1, &m_emptyheights);
|
||||
if (m_emptyocclusion != 0)
|
||||
glDeleteTextures(1, &m_emptyocclusion);
|
||||
}
|
||||
|
||||
void opengl46_sky_occlusion::init()
|
||||
{
|
||||
// a sampler with no texture to read from is undefined, also where the shading doesn't read it
|
||||
m_emptyheights = make_map(GL_R32F, 1);
|
||||
float const none{-1.0e4f};
|
||||
glClearTexImage(m_emptyheights, 0, GL_RED, GL_FLOAT, &none);
|
||||
m_emptyocclusion = make_map(GL_RGBA16F, 1);
|
||||
float const open[4]{1.f, 1.f, -1000.f, 1000.f};
|
||||
glClearTexImage(m_emptyocclusion, 0, GL_RGBA, GL_FLOAT, open);
|
||||
bind();
|
||||
}
|
||||
|
||||
void opengl46_sky_occlusion::bind() const
|
||||
{
|
||||
glBindTextureUnit(gl::SKY_OCCLUSION_HEIGHT_TEX, (m_heights != 0) ? m_heights : m_emptyheights);
|
||||
glBindTextureUnit(gl::SKY_OCCLUSION_TEX, (m_occlusion != 0) ? m_occlusion : m_emptyocclusion);
|
||||
}
|
||||
|
||||
bool opengl46_sky_occlusion::gpu_allocate(int const Side)
|
||||
{
|
||||
gpu_release();
|
||||
m_heights = make_map(GL_R32F, Side);
|
||||
m_occlusion = make_map(GL_RGBA16F, Side);
|
||||
if ((m_heights == 0) || (m_occlusion == 0))
|
||||
return false;
|
||||
bind();
|
||||
return true;
|
||||
}
|
||||
|
||||
void opengl46_sky_occlusion::gpu_release()
|
||||
{
|
||||
if (m_heights != 0)
|
||||
glDeleteTextures(1, &m_heights);
|
||||
if (m_occlusion != 0)
|
||||
glDeleteTextures(1, &m_occlusion);
|
||||
m_heights = 0;
|
||||
m_occlusion = 0;
|
||||
if (m_emptyheights != 0)
|
||||
bind();
|
||||
}
|
||||
|
||||
void opengl46_sky_occlusion::gpu_upload(int const X, int const Y, int const Size, float const *Heights, std::uint16_t const *Occlusion)
|
||||
{
|
||||
if ((m_heights == 0) || (m_occlusion == 0))
|
||||
return;
|
||||
// from the memory of the process: the buffer the texture streaming may have bound and the alignment are put back after
|
||||
GLint unpack{0}, alignment{4};
|
||||
glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &unpack);
|
||||
glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glTextureSubImage2D(m_heights, 0, X, Y, Size, Size, GL_RED, GL_FLOAT, Heights);
|
||||
glTextureSubImage2D(m_occlusion, 0, X, Y, Size, Size, GL_RGBA, GL_HALF_FLOAT, Occlusion);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, static_cast<GLuint>(unpack));
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
|
||||
}
|
||||
37
rendering/opengl46/opengl46skyocclusion.h
Normal file
37
rendering/opengl46/opengl46skyocclusion.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "rendering/common/skyocclusion.h"
|
||||
|
||||
// the maps of the occlusion of the sky by the scenery (gfx::sky_occlusion) for the opengl 4.6 renderer: two textures bound to their
|
||||
// units (gl::SKY_OCCLUSION_HEIGHT_TEX, gl::SKY_OCCLUSION_TEX) for every pass, stand-ins of one texel while there are none
|
||||
class opengl46_sky_occlusion : public gfx::sky_occlusion
|
||||
{
|
||||
public:
|
||||
opengl46_sky_occlusion() = default;
|
||||
~opengl46_sky_occlusion() override;
|
||||
|
||||
// the stand-ins
|
||||
void init();
|
||||
// the textures (or the stand-ins) bound to their units
|
||||
void bind() const;
|
||||
|
||||
protected:
|
||||
bool gpu_allocate(int const Side) override;
|
||||
void gpu_release() override;
|
||||
void gpu_upload(int const X, int const Y, int const Size, float const *Heights, std::uint16_t const *Occlusion) override;
|
||||
|
||||
private:
|
||||
GLuint m_heights{0};
|
||||
GLuint m_occlusion{0};
|
||||
GLuint m_emptyheights{0};
|
||||
GLuint m_emptyocclusion{0};
|
||||
};
|
||||
Reference in New Issue
Block a user