1
0
mirror of https://github.com/minetest/minetest.git synced 2025-07-03 00:20:21 +02:00

Make volumetric light effect strength server controllable

- Make volumetric light effect strength server controllable
- Separate volumetric and bloom shader pipeline
- Require bloom to be enable, scale godrays with bloom
This commit is contained in:
Lars
2023-10-23 17:05:31 -07:00
committed by lhofhansl
parent 04f0d545da
commit e0d4a9d575
16 changed files with 227 additions and 144 deletions

View File

@ -404,10 +404,12 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter
CachedPixelShaderSetting<float> m_bloom_radius_pixel;
float m_bloom_radius;
CachedPixelShaderSetting<float> m_saturation_pixel;
bool m_volumetric_light_enabled;
CachedPixelShaderSetting<float, 3> m_sun_position_pixel;
CachedPixelShaderSetting<float> m_sun_brightness_pixel;
CachedPixelShaderSetting<float, 3> m_moon_position_pixel;
CachedPixelShaderSetting<float> m_moon_brightness_pixel;
CachedPixelShaderSetting<float> m_volumetric_light_strength_pixel;
public:
void onSettingsChange(const std::string &name)
@ -469,7 +471,8 @@ public:
m_sun_position_pixel("sunPositionScreen"),
m_sun_brightness_pixel("sunBrightness"),
m_moon_position_pixel("moonPositionScreen"),
m_moon_brightness_pixel("moonBrightness")
m_moon_brightness_pixel("moonBrightness"),
m_volumetric_light_strength_pixel("volumetricLightStrength")
{
g_settings->registerChangedCallback("enable_fog", settingsCallback, this);
g_settings->registerChangedCallback("exposure_compensation", settingsCallback, this);
@ -483,6 +486,7 @@ public:
m_bloom_intensity = g_settings->getFloat("bloom_intensity", 0.01f, 1.0f);
m_bloom_strength = RenderingEngine::BASE_BLOOM_STRENGTH * g_settings->getFloat("bloom_strength_factor", 0.1f, 10.0f);
m_bloom_radius = g_settings->getFloat("bloom_radius", 0.1f, 8.0f);
m_volumetric_light_enabled = g_settings->getBool("enable_volumetric_lighting") && m_bloom_enabled;
}
~GameGlobalShaderConstantSetter()
@ -588,49 +592,52 @@ public:
float saturation = m_client->getEnv().getLocalPlayer()->getLighting().saturation;
m_saturation_pixel.set(&saturation, services);
// Map directional light to screen space
auto camera_node = m_client->getCamera()->getCameraNode();
core::matrix4 transform = camera_node->getProjectionMatrix();
transform *= camera_node->getViewMatrix();
if (m_volumetric_light_enabled) {
// Map directional light to screen space
auto camera_node = m_client->getCamera()->getCameraNode();
core::matrix4 transform = camera_node->getProjectionMatrix();
transform *= camera_node->getViewMatrix();
if (m_sky->getSunVisible()) {
v3f sun_position = camera_node->getAbsolutePosition() +
10000. * m_sky->getSunDirection();
transform.transformVect(sun_position);
sun_position.normalize();
if (m_sky->getSunVisible()) {
v3f sun_position = camera_node->getAbsolutePosition() +
10000. * m_sky->getSunDirection();
transform.transformVect(sun_position);
sun_position.normalize();
float sun_position_array[3] = { sun_position.X, sun_position.Y, sun_position.Z};
m_sun_position_pixel.set(sun_position_array, services);
float sun_position_array[3] = { sun_position.X, sun_position.Y, sun_position.Z};
m_sun_position_pixel.set(sun_position_array, services);
float sun_brightness = rangelim(107.143f * m_sky->getSunDirection().dotProduct(v3f(0.f, 1.f, 0.f)), 0.f, 1.f);
m_sun_brightness_pixel.set(&sun_brightness, services);
}
else {
float sun_position_array[3] = { 0.f, 0.f, -1.f };
m_sun_position_pixel.set(sun_position_array, services);
float sun_brightness = rangelim(107.143f * m_sky->getSunDirection().dotProduct(v3f(0.f, 1.f, 0.f)), 0.f, 1.f);
m_sun_brightness_pixel.set(&sun_brightness, services);
} else {
float sun_position_array[3] = { 0.f, 0.f, -1.f };
m_sun_position_pixel.set(sun_position_array, services);
float sun_brightness = 0.f;
m_sun_brightness_pixel.set(&sun_brightness, services);
}
float sun_brightness = 0.f;
m_sun_brightness_pixel.set(&sun_brightness, services);
}
if (m_sky->getMoonVisible()) {
v3f moon_position = camera_node->getAbsolutePosition() +
10000. * m_sky->getMoonDirection();
transform.transformVect(moon_position);
moon_position.normalize();
if (m_sky->getMoonVisible()) {
v3f moon_position = camera_node->getAbsolutePosition() +
10000. * m_sky->getMoonDirection();
transform.transformVect(moon_position);
moon_position.normalize();
float moon_position_array[3] = { moon_position.X, moon_position.Y, moon_position.Z};
m_moon_position_pixel.set(moon_position_array, services);
float moon_position_array[3] = { moon_position.X, moon_position.Y, moon_position.Z};
m_moon_position_pixel.set(moon_position_array, services);
float moon_brightness = rangelim(107.143f * m_sky->getMoonDirection().dotProduct(v3f(0.f, 1.f, 0.f)), 0.f, 1.f);
m_moon_brightness_pixel.set(&moon_brightness, services);
}
else {
float moon_position_array[3] = { 0.f, 0.f, -1.f };
m_moon_position_pixel.set(moon_position_array, services);
float moon_brightness = rangelim(107.143f * m_sky->getMoonDirection().dotProduct(v3f(0.f, 1.f, 0.f)), 0.f, 1.f);
m_moon_brightness_pixel.set(&moon_brightness, services);
}
else {
float moon_position_array[3] = { 0.f, 0.f, -1.f };
m_moon_position_pixel.set(moon_position_array, services);
float moon_brightness = 0.f;
m_moon_brightness_pixel.set(&moon_brightness, services);
float moon_brightness = 0.f;
m_moon_brightness_pixel.set(&moon_brightness, services);
}
float volumetric_light_strength = m_client->getEnv().getLocalPlayer()->getLighting().volumetric_light_strength;
m_volumetric_light_strength_pixel.set(&volumetric_light_strength, services);
}
}
@ -3089,7 +3096,6 @@ void Game::handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam)
else
sky->setFogStart(rangelim(g_settings->getFloat("fog_start"), 0.0f, 0.99f));
delete event->set_sky;
}

View File

@ -120,8 +120,9 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
static const u8 TEXTURE_EXPOSURE_1 = 3;
static const u8 TEXTURE_EXPOSURE_2 = 4;
static const u8 TEXTURE_FXAA = 5;
static const u8 TEXTURE_BLOOM_DOWN = 10;
static const u8 TEXTURE_BLOOM_UP = 20;
static const u8 TEXTURE_VOLUME = 6;
static const u8 TEXTURE_SCALE_DOWN = 10;
static const u8 TEXTURE_SCALE_UP = 20;
// Super-sampling is simply rendering into a larger texture.
// Downscaling is done by the final step when rendering to the screen.
@ -130,6 +131,7 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
const bool enable_auto_exposure = g_settings->getBool("enable_auto_exposure");
const bool enable_ssaa = antialiasing == "ssaa";
const bool enable_fxaa = antialiasing == "fxaa";
const bool enable_volumetric_light = g_settings->getBool("enable_volumetric_lighting") && enable_bloom;
if (enable_ssaa) {
u16 ssaa_scale = MYMAX(2, g_settings->getU16("fsaa"));
@ -160,9 +162,9 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
v2f downscale = scale * 0.5;
for (u8 i = 0; i < MIPMAP_LEVELS; i++) {
buffer->setTexture(TEXTURE_BLOOM_DOWN + i, downscale, std::string("downsample") + std::to_string(i), color_format);
buffer->setTexture(TEXTURE_SCALE_DOWN + i, downscale, std::string("downsample") + std::to_string(i), color_format);
if (enable_bloom)
buffer->setTexture(TEXTURE_BLOOM_UP + i, downscale, std::string("upsample") + std::to_string(i), color_format);
buffer->setTexture(TEXTURE_SCALE_UP + i, downscale, std::string("upsample") + std::to_string(i), color_format);
downscale *= 0.5;
}
@ -171,20 +173,30 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
// get bright spots
u32 shader_id = client->getShaderSource()->getShader("extract_bloom", TILE_MATERIAL_PLAIN, NDT_MESH);
RenderStep *extract_bloom = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_COLOR, TEXTURE_EXPOSURE_1, TEXTURE_DEPTH });
RenderStep *extract_bloom = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { source, TEXTURE_EXPOSURE_1 });
extract_bloom->setRenderSource(buffer);
extract_bloom->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_BLOOM));
source = TEXTURE_BLOOM;
}
if (enable_volumetric_light) {
buffer->setTexture(TEXTURE_VOLUME, scale, "volume", color_format);
shader_id = client->getShaderSource()->getShader("volumetric_light", TILE_MATERIAL_PLAIN, NDT_MESH);
auto volume = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { source, TEXTURE_DEPTH });
volume->setRenderSource(buffer);
volume->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_VOLUME));
source = TEXTURE_VOLUME;
}
// downsample
shader_id = client->getShaderSource()->getShader("bloom_downsample", TILE_MATERIAL_PLAIN, NDT_MESH);
for (u8 i = 0; i < MIPMAP_LEVELS; i++) {
auto step = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { source });
step->setRenderSource(buffer);
step->setBilinearFilter(0, true);
step->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_BLOOM_DOWN + i));
source = TEXTURE_BLOOM_DOWN + i;
step->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_SCALE_DOWN + i));
source = TEXTURE_SCALE_DOWN + i;
}
}
@ -193,19 +205,19 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
// upsample
shader_id = client->getShaderSource()->getShader("bloom_upsample", TILE_MATERIAL_PLAIN, NDT_MESH);
for (u8 i = MIPMAP_LEVELS - 1; i > 0; i--) {
auto step = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { u8(TEXTURE_BLOOM_DOWN + i - 1), source });
auto step = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { u8(TEXTURE_SCALE_DOWN + i - 1), source });
step->setRenderSource(buffer);
step->setBilinearFilter(0, true);
step->setBilinearFilter(1, true);
step->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, u8(TEXTURE_BLOOM_UP + i - 1)));
source = TEXTURE_BLOOM_UP + i - 1;
step->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, u8(TEXTURE_SCALE_UP + i - 1)));
source = TEXTURE_SCALE_UP + i - 1;
}
}
// Dynamic Exposure pt2
if (enable_auto_exposure) {
shader_id = client->getShaderSource()->getShader("update_exposure", TILE_MATERIAL_PLAIN, NDT_MESH);
auto update_exposure = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_EXPOSURE_1, u8(TEXTURE_BLOOM_DOWN + MIPMAP_LEVELS - 1) });
auto update_exposure = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_EXPOSURE_1, u8(TEXTURE_SCALE_DOWN + MIPMAP_LEVELS - 1) });
update_exposure->setBilinearFilter(1, true);
update_exposure->setRenderSource(buffer);
update_exposure->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_EXPOSURE_2));
@ -228,7 +240,7 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
// final merge
shader_id = client->getShaderSource()->getShader("second_stage", TILE_MATERIAL_PLAIN, NDT_MESH);
PostProcessingStep *effect = pipeline->createOwned<PostProcessingStep>(shader_id, std::vector<u8> { final_stage_source, TEXTURE_BLOOM_UP, TEXTURE_EXPOSURE_2 });
PostProcessingStep *effect = pipeline->createOwned<PostProcessingStep>(shader_id, std::vector<u8> { final_stage_source, TEXTURE_SCALE_UP, TEXTURE_EXPOSURE_2 });
pipeline->addStep(effect);
if (enable_ssaa)
effect->setBilinearFilter(0, true);

View File

@ -770,6 +770,10 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
if (g_settings->getBool("debanding"))
shaders_header << "#define ENABLE_DITHERING 1\n";
if (g_settings->getBool("enable_volumetric_lighting")) {
shaders_header << "#define VOLUMETRIC_LIGHT 1\n";
}
shaders_header << "#line 0\n"; // reset the line counter for meaningful diagnostics
std::string common_header = shaders_header.str();

View File

@ -120,6 +120,9 @@ public:
void setFogStart(float fog_start) { m_sky_params.fog_start = fog_start; }
float getFogStart() const { return m_sky_params.fog_start; }
void setVolumetricLightStrength(float volumetric_light_strength) { m_sky_params.volumetric_light_strength = volumetric_light_strength; }
float getVolumetricLightStrength() const { return m_sky_params.volumetric_light_strength; }
private:
aabb3f m_box;
video::SMaterial m_materials[SKY_MATERIAL_COUNT];