mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-04 11:19:30 +01:00
Lay the light cluster tiles over the window when the post processing is skippe; Bind the light cluster buffers when a viewport is created
This commit is contained in:
@@ -86,7 +86,9 @@ reverse-Z with the far plane at infinity, so the `znear` / `zfar` of the pass bo
|
|||||||
`cluster_cull.comp` handles one cluster per invocation and goes through `lights[1 .. lights_total)`.
|
`cluster_cull.comp` handles one cluster per invocation and goes through `lights[1 .. lights_total)`.
|
||||||
|
|
||||||
- A light's reach is the distance where its brightest possible contribution falls under `MIN_CONTRIBUTION`
|
- A light's reach is the distance where its brightest possible contribution falls under `MIN_CONTRIBUTION`
|
||||||
(1/1024) of the display range, at most `MAX_RANGE` (1000 m, as the 1 km filter on the CPU). Headlights are tested against
|
(1/1024) of the display range. There is no fixed limit on top of that: the 1 km filter on the CPU is the distance
|
||||||
|
of a light from the camera, and the shading lights a surface at any distance, so a headlight without falloff
|
||||||
|
reaches every cluster in its beam. Headlights are tested against
|
||||||
that sphere and against the frustum of their projection (four side planes and the near plane, with 5 cm of margin);
|
that sphere and against the frustum of their projection (four side planes and the near plane, with 5 cm of margin);
|
||||||
point lights against a sphere; spot lights against a sphere and a cone; directional lights reach everything.
|
point lights against a sphere; spot lights against a sphere and a cone; directional lights reach everything.
|
||||||
- A cluster takes up to 64 lights. The ones that come first in `lights[]` win, which is the order from
|
- A cluster takes up to 64 lights. The ones that come first in `lights[]` win, which is the order from
|
||||||
|
|||||||
@@ -464,6 +464,10 @@ bool opengl46_renderer::init_viewport(viewport_config &vp)
|
|||||||
light_ssbo->bind_base();
|
light_ssbo->bind_base();
|
||||||
|
|
||||||
vp.clusters = std::make_unique<gl::cluster_grid>();
|
vp.clusters = std::make_unique<gl::cluster_grid>();
|
||||||
|
// the material shaders declare the cluster blocks whether they read them or not, and drawing with an active storage
|
||||||
|
// block without a buffer behind it is undefined. the context starts with these buffers in place; every pass which
|
||||||
|
// uses a grid binds its own
|
||||||
|
vp.clusters->bind();
|
||||||
|
|
||||||
if (!Global.gfx_skippipeline)
|
if (!Global.gfx_skippipeline)
|
||||||
{
|
{
|
||||||
@@ -941,7 +945,8 @@ void opengl46_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
|||||||
// the environment map is drawn in
|
// the environment map is drawn in
|
||||||
auto const clusterlists{ Global.gfx_lights_clustered || Global.gfx_lights_clusterheatmap };
|
auto const clusterlists{ Global.gfx_lights_clustered || Global.gfx_lights_clusterheatmap };
|
||||||
if( clusterlists ) {
|
if( clusterlists ) {
|
||||||
Update_Clusters( vp );
|
// the tiles are laid over what the scene is drawn to: the buffers of the viewport, or the window itself without the post processing pipeline
|
||||||
|
Update_Clusters( vp, Global.gfx_skippipeline ? target_size : glm::ivec2{ vp.width, vp.height } );
|
||||||
}
|
}
|
||||||
Update_Lights( simulation::Lights, true, Global.gfx_lights_clustered && vp.clusters->valid() );
|
Update_Lights( simulation::Lights, true, Global.gfx_lights_clustered && vp.clusters->valid() );
|
||||||
if( clusterlists ) {
|
if( clusterlists ) {
|
||||||
@@ -6086,14 +6091,14 @@ void opengl46_renderer::Update_Lights(light_array &Lights, bool const Headlights
|
|||||||
light_ssbo->update(&light_data, 0, offsetof(gl::light_data, lights) + sizeof(gl::light_element) * light_i);
|
light_ssbo->update(&light_data, 0, offsetof(gl::light_data, lights) + sizeof(gl::light_element) * light_i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void opengl46_renderer::Update_Clusters(viewport_config &vp)
|
void opengl46_renderer::Update_Clusters(viewport_config &vp, glm::ivec2 const &Targetsize)
|
||||||
{
|
{
|
||||||
glDebug("Update_Clusters");
|
glDebug("Update_Clusters");
|
||||||
|
|
||||||
auto &grid{*vp.clusters};
|
auto &grid{*vp.clusters};
|
||||||
grid.bind();
|
grid.bind();
|
||||||
// the boxes of the clusters depend only on the projection and the depth range, so they are rebuilt only when those change
|
// the boxes of the clusters depend only on the projection and the depth range, so they are rebuilt only when those change
|
||||||
if (grid.update(OpenGLMatrices.data(GL_PROJECTION), m_renderpass.znear, m_renderpass.zfar, glm::vec2{static_cast<float>(vp.width), static_cast<float>(vp.height)}))
|
if (grid.update(OpenGLMatrices.data(GL_PROJECTION), m_renderpass.znear, m_renderpass.zfar, glm::vec2{Targetsize}))
|
||||||
{
|
{
|
||||||
m_clusterstimer.begin();
|
m_clusterstimer.begin();
|
||||||
grid.build(*m_cluster_build_shader);
|
grid.build(*m_cluster_build_shader);
|
||||||
|
|||||||
@@ -345,8 +345,9 @@ class opengl46_renderer : public gfx_renderer {
|
|||||||
// unless Headlights is false, as in the pass which draws the environment map, where lights of vehicles would only get baked into the map.
|
// unless Headlights is false, as in the pass which draws the environment map, where lights of vehicles would only get baked into the map.
|
||||||
// Clustered tells the shading to take the headlights from the lists of the clusters (see Cull_Lights()) and not to go through the first few
|
// Clustered tells the shading to take the headlights from the lists of the clusters (see Cull_Lights()) and not to go through the first few
|
||||||
void Update_Lights(light_array &Lights, bool const Headlights = true, bool const Clustered = false);
|
void Update_Lights(light_array &Lights, bool const Headlights = true, bool const Clustered = false);
|
||||||
// brings the light cluster grid of the viewport up to date with the projection of the color pass being drawn
|
// brings the light cluster grid of the viewport up to date with the projection of the color pass being drawn.
|
||||||
void Update_Clusters(viewport_config &vp);
|
// Targetsize is the size in pixels of what the pass draws to, which gl_FragCoord of the shading counts in
|
||||||
|
void Update_Clusters(viewport_config &vp, glm::ivec2 const &Targetsize);
|
||||||
// assigns the lights set up by Update_Lights() to the clusters of the viewport; run after it, before the scene is drawn
|
// assigns the lights set up by Update_Lights() to the clusters of the viewport; run after it, before the scene is drawn
|
||||||
void Cull_Lights(viewport_config &vp);
|
void Cull_Lights(viewport_config &vp);
|
||||||
// debug view: tints the finished image of the viewport with the cluster of every pixel. Target is the framebuffer
|
// debug view: tints the finished image of the viewport with the cluster of every pixel. Target is the framebuffer
|
||||||
|
|||||||
Reference in New Issue
Block a user