1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-11 17:51:04 +00:00

Update volumetrics

This commit is contained in:
Gefüllte Taubenbrust 2024-08-18 15:13:26 +02:00
parent 22ba7449f2
commit e6752008e0
17 changed files with 420 additions and 181 deletions

View file

@ -45,7 +45,7 @@ Clouds::Clouds(scene::ISceneManager* mgr, IShaderSource *ssrc,
s32 id,
u32 seed
):
scene::ISceneNode(mgr->getRootSceneNode(), mgr, id),
scene::ISceneNode(g_settings->getBool("enable_volumetric_clouds") ? nullptr : mgr->getRootSceneNode(), mgr, id),
m_seed(seed)
{
m_enable_shaders = g_settings->getBool("enable_shaders");
@ -106,6 +106,14 @@ void Clouds::updateMesh()
std::floor(center_of_drawing_in_noise_f.Y / cloud_size)
);
// The world position of the integer center point of drawing in the noise
v2f world_center_of_drawing_in_noise_f = v2f(
center_of_drawing_in_noise_i.X * cloud_size,
center_of_drawing_in_noise_i.Y * cloud_size
) + m_origin;
m_noise_position = world_center_of_drawing_in_noise_f - ((float)m_cloud_radius_i + 0.5f) * cloud_size;
// Only update mesh if it has moved enough, this saves lots of GPU buffer uploads.
constexpr float max_d = 5 * BS;
@ -128,12 +136,6 @@ void Clouds::updateMesh()
const u32 num_faces_to_draw = m_enable_3d ? 6 : 1;
// The world position of the integer center point of drawing in the noise
v2f world_center_of_drawing_in_noise_f = v2f(
center_of_drawing_in_noise_i.X * cloud_size,
center_of_drawing_in_noise_i.Y * cloud_size
) + m_origin;
// Colors with primitive shading
video::SColorf c_top_f(m_color);
@ -160,7 +162,7 @@ void Clouds::updateMesh()
// Read noise
std::vector<bool> grid(m_cloud_radius_i * 2 * m_cloud_radius_i * 2);
m_grid.resize(m_cloud_radius_i * 2 * m_cloud_radius_i * 2);
for(s16 zi = -m_cloud_radius_i; zi < m_cloud_radius_i; zi++) {
u32 si = (zi + m_cloud_radius_i) * m_cloud_radius_i * 2 + m_cloud_radius_i;
@ -168,7 +170,7 @@ void Clouds::updateMesh()
for (s16 xi = -m_cloud_radius_i; xi < m_cloud_radius_i; xi++) {
u32 i = si + xi;
grid[i] = gridFilled(
m_grid[i] = gridFilled(
xi + center_of_drawing_in_noise_i.X,
zi + center_of_drawing_in_noise_i.Y
);
@ -205,7 +207,7 @@ void Clouds::updateMesh()
u32 i = GETINDEX(xi, zi, m_cloud_radius_i);
if (!grid[i])
if (!m_grid[i])
continue;
v2f p0 = v2f(xi,zi)*cloud_size + world_center_of_drawing_in_noise_f;
@ -238,7 +240,7 @@ void Clouds::updateMesh()
case 1: // back
if (INAREA(xi, zi - 1, m_cloud_radius_i)) {
u32 j = GETINDEX(xi, zi - 1, m_cloud_radius_i);
if(grid[j])
if(m_grid[j])
continue;
}
for (video::S3DVertex &vertex : v) {
@ -253,7 +255,7 @@ void Clouds::updateMesh()
case 2: //right
if (INAREA(xi + 1, zi, m_cloud_radius_i)) {
u32 j = GETINDEX(xi+1, zi, m_cloud_radius_i);
if(grid[j])
if(m_grid[j])
continue;
}
for (video::S3DVertex &vertex : v) {
@ -268,7 +270,7 @@ void Clouds::updateMesh()
case 3: // front
if (INAREA(xi, zi + 1, m_cloud_radius_i)) {
u32 j = GETINDEX(xi, zi + 1, m_cloud_radius_i);
if(grid[j])
if(m_grid[j])
continue;
}
for (video::S3DVertex &vertex : v) {
@ -283,7 +285,7 @@ void Clouds::updateMesh()
case 4: // left
if (INAREA(xi-1, zi, m_cloud_radius_i)) {
u32 j = GETINDEX(xi-1, zi, m_cloud_radius_i);
if(grid[j])
if(m_grid[j])
continue;
}
for (video::S3DVertex &vertex : v) {
@ -343,7 +345,6 @@ void Clouds::updateMesh()
void Clouds::render()
{
#if 0
if (m_params.density <= 0.0f)
return; // no need to do anything
@ -389,12 +390,38 @@ void Clouds::render()
cloud_full_radius*1.2, fog_density, fog_pixelfog, fog_rangefog);
}
//#if 0
driver->drawMeshBuffer(m_meshbuffer.get());
//#endif
// Restore fog settings
driver->setFog(fog_color, fog_type, fog_start, fog_end, fog_density,
fog_pixelfog, fog_rangefog);
#endif
}
void Clouds::renderDepth() {
if (m_params.density <= 0.0f)
return; // no need to do anything
video::IVideoDriver* driver = SceneManager->getVideoDriver();
updateMesh();
// Update position
{
v2f off_origin = m_origin - m_mesh_origin;
v3f rel(off_origin.X, 0, off_origin.Y);
rel -= intToFloat(m_camera_offset, BS);
setPosition(rel);
updateAbsolutePosition();
}
video::SMaterial material = m_material;
material.MaterialType = video::EMT_SOLID;
material.ZWriteEnable = video::EZW_ON;
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->setMaterial(material);
driver->drawMeshBuffer(m_meshbuffer.get());
}
void Clouds::step(float dtime)

View file

@ -52,6 +52,8 @@ public:
virtual void render();
void renderDepth();
virtual const aabb3f &getBoundingBox() const
{
return m_box;
@ -140,6 +142,16 @@ public:
const video::SColor getColor() const { return m_color.toSColor(); }
bool getGrid(int x, int y)
{
int index = x + y * m_cloud_radius_i * 2;
if (index < 0 || index >= m_grid.size())
return false;
return m_grid[index];
}
v2f getCloudOffset() const { return m_noise_position; }
private:
void updateBox()
{
@ -173,6 +185,7 @@ private:
u16 m_cloud_radius_i;
u32 m_seed;
v3f m_camera_pos;
v2f m_noise_position;
v3s16 m_camera_offset;
bool m_camera_inside_cloud = false;
@ -180,4 +193,7 @@ private:
bool m_enable_shaders, m_enable_3d;
video::SColorf m_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
CloudParams m_params;
std::vector<bool> m_grid;
};

View file

@ -383,11 +383,10 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter
m_animation_timer_delta_pixel{"animationTimerDelta"};
CachedPixelShaderSetting<float, 3> m_artificial_light{ "artificialLight" };
CachedPixelShaderSetting<float, 3> m_day_light{"dayLight"};
CachedPixelShaderSetting<float, 3> m_eye_position_pixel{ "eyePosition" };
CachedVertexShaderSetting<float, 3> m_eye_position_vertex{ "eyePosition" };
CachedPixelShaderSetting<float, 3> m_minimap_yaw{"yawVec"};
CachedPixelShaderSetting<float, 3> m_camera_offset_pixel{"cameraOffset"};
CachedVertexShaderSetting<float, 3> m_camera_offset_vertex{"cameraOffset"};
CachedPixelShaderSetting<float, 3> m_camera_offset_pixel{ "cameraOffset" };
CachedVertexShaderSetting<float, 3> m_camera_position_vertex{"cameraPosition"};
CachedPixelShaderSetting<float, 3> m_camera_position_pixel{"cameraPosition"};
CachedVertexShaderSetting<float, 16> m_camera_projinv_vertex{"mCameraProjInv"};
CachedPixelShaderSetting<float, 16> m_camera_projinv_pixel{"mCameraProjInv"};
@ -420,6 +419,8 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter
CachedPixelShaderSetting<float> m_cloud_height_pixel{"cloudHeight"};
CachedPixelShaderSetting<float> m_cloud_thickness_pixel{"cloudThickness"};
CachedPixelShaderSetting<float> m_cloud_density_pixel{"cloudDensity"};
CachedPixelShaderSetting<float, 2> m_cloud_offset_pixel{"cloudOffset"};
CachedPixelShaderSetting<float> m_cloud_radius_pixel{"cloudRadius"};
CachedPixelShaderSetting<float> m_saturation_pixel{"saturation"};
float m_gamma;
CachedPixelShaderSetting<float> m_gamma_pixel{"gamma"};
@ -432,6 +433,8 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter
CachedPixelShaderSetting<float> m_moon_brightness_pixel{"moonBrightness"};
CachedPixelShaderSetting<float>
m_volumetric_light_strength_pixel{"volumetricLightStrength"};
CachedPixelShaderSetting<float, 3>
m_volumetric_cloud_color{"cloudColor"};
static constexpr std::array<const char*, 5> SETTING_CALLBACKS = {
"exposure_compensation",
@ -501,20 +504,17 @@ public:
m_animation_timer_delta_vertex.set(&animation_timer_delta_f, services);
m_animation_timer_delta_pixel.set(&animation_timer_delta_f, services);
v3f epos = m_client->getEnv().getLocalPlayer()->getEyePosition();
m_eye_position_pixel.set(epos, services);
m_eye_position_vertex.set(epos, services);
if (m_client->getMinimap()) {
v3f minimap_yaw = m_client->getMinimap()->getYawVec();
m_minimap_yaw.set(minimap_yaw, services);
}
v3f offset = intToFloat(m_client->getCamera()->getOffset(), BS);
m_camera_offset_pixel.set(offset, services);
m_camera_offset_vertex.set(offset, services);
m_camera_offset_pixel.set(offset, services);
v3f camera_position = m_client->getCamera()->getPosition();
m_camera_position_vertex.set(camera_position, services);
m_camera_position_pixel.set(camera_position, services);
core::matrix4 camera_proj = m_client->getCamera()->getCameraNode()->getProjectionMatrix();
@ -573,13 +573,19 @@ public:
// TODO: settings
Clouds* clouds = m_client->getClouds();
if (m_client->getClouds()) {
if (clouds && g_settings->getBool("enable_volumetric_clouds")) {
float cloud_height = clouds->getHeight() * 10.0f;
m_cloud_height_pixel.set(&cloud_height, services);
float cloud_thickness = clouds->getThickness() * 10.0f;
m_cloud_thickness_pixel.set(&cloud_thickness, services);
float cloud_density = clouds->getDensity();
m_cloud_density_pixel.set(&cloud_density, services);
v2f cloud_offset = clouds->getCloudOffset();
m_cloud_offset_pixel.set(cloud_offset, services);
float cloud_radius = g_settings->getU16("cloud_radius");
m_cloud_radius_pixel.set(&cloud_radius, services);
video::SColor cloud_color = clouds->getColor();
m_volumetric_cloud_color.set(cloud_color, services);
}
if (m_volumetric_light_enabled) {
@ -4294,7 +4300,7 @@ void Game::updateClouds(float dtime)
camera_node_position.Y = camera_node_position.Y + camera_offset.Y * BS;
camera_node_position.Z = camera_node_position.Z + camera_offset.Z * BS;
this->clouds->update(camera_node_position, this->sky->getCloudColor());
if (this->clouds->isCameraInsideCloud() && this->fogEnabled()) {
if (this->clouds->isCameraInsideCloud() && this->fogEnabled() && !g_settings->getBool("enable_volumetric_clouds")) {
// If camera is inside cloud and fog is enabled, use cloud's colors as sky colors.
video::SColor clouds_dark = this->clouds->getColor().getInterpolated(
video::SColor(255, 0, 0, 0), 0.9);

View file

@ -113,6 +113,18 @@ void TextureBuffer::swapTextures(u8 texture_a, u8 texture_b)
m_textures[texture_b] = temp;
}
void TextureBuffer::setTextureImage(u8 id, video::IImage* image) {
assert(m_definitions[id].valid);
auto &definition = m_definitions[id];
if (m_textures[id]) m_driver->removeTexture(m_textures[id]);
m_textures[id] = m_driver->addTexture(definition.name.c_str(), image);
definition.fixed_size = true;
definition.size = image->getDimension();
definition.dirty = false;
}
bool TextureBuffer::ensureTexture(video::ITexture **texture, const TextureDefinition& definition, PipelineContext &context)
{
@ -183,6 +195,8 @@ void TextureBufferOutput::activate(PipelineContext &context)
if (!render_target)
render_target = driver->addRenderTarget();
if (disable_clear) m_clear = false;
core::array<video::ITexture *> textures;
core::dimension2du size(0, 0);
for (size_t i = 0; i < texture_map.size(); i++) {

View file

@ -141,6 +141,7 @@ public:
virtual video::ITexture *getTexture(u8 index) override;
virtual void reset(PipelineContext &context) override;
void swapTextures(u8 texture_a, u8 texture_b);
void setTextureImage(u8 id, video::IImage* image);
private:
static const u8 NO_DEPTH_TEXTURE = 255;
@ -182,6 +183,7 @@ public:
TextureBufferOutput(TextureBuffer *buffer, const std::vector<u8> &texture_map, u8 depth_stencil);
virtual ~TextureBufferOutput() override;
void activate(PipelineContext &context) override;
void disableClearing() { disable_clear = true; }
private:
static const u8 NO_DEPTH_TEXTURE = 255;
@ -190,6 +192,7 @@ private:
u8 depth_stencil { NO_DEPTH_TEXTURE };
video::IRenderTarget* render_target { nullptr };
video::IVideoDriver* driver { nullptr };
bool disable_clear = false;
};
/**

View file

@ -24,64 +24,114 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client/shader.h"
#include "client/tile.h"
#include "settings.h"
#include "noise.h"
class NoiseStep : public RenderStep {
public:
NoiseStep(u32 shader_id, u8 texture_id) :
shader_id(shader_id), texture_id(texture_id)
NoiseStep(TextureBuffer* buffer, u8 id, u32 size) :
buffer(buffer), id(id), size(size)
{
material.UseMipMaps = false;
material.ZBuffer = true;
material.ZWriteEnable = video::EZW_ON;
}
void setRenderSource(RenderSource* _source) override {
source = _source;
void setRenderSource(RenderSource* _source) override {}
void setRenderTarget(RenderTarget* _target) override {}
void reset(PipelineContext& context) override {}
void run(PipelineContext& context) override
{
if (!needs_run) return;
needs_run = false;
video::IImage* noise_image = context.device->getVideoDriver()->createImage(video::ECF_A8R8G8B8, core::dimension2du(256, 256));
PseudoRandom random;
for (u32 i = 0; i < size * size; ++i) {
noise_image->setPixel(i % size, i / size, video::SColor(0, random.next() % 256, 0, 0));
}
buffer->setTextureImage(id, noise_image);
noise_image->drop();
}
void setRenderTarget(RenderTarget* _target) override {
private:
u32 size;
u8 id;
TextureBuffer* buffer = nullptr;
bool needs_run = true;
};
class CloudDensityStep : public RenderStep {
public:
CloudDensityStep(TextureBuffer* buffer, u8 id, Clouds* clouds) :
buffer(buffer), id(id), clouds(clouds)
{
}
void setRenderSource(RenderSource* _source) override {}
void setRenderTarget(RenderTarget* _target) override {}
void reset(PipelineContext& context) override {}
void run(PipelineContext& context) override
{
u16 cloud_radius = g_settings->getU16("cloud_radius");
if (cloud_radius < 1) cloud_radius = 1;
video::IImage* image = context.device->getVideoDriver()->createImage(video::ECF_A8R8G8B8, core::dimension2du(8 * cloud_radius, 8 * cloud_radius));
for (int x = 0; x < 2 * cloud_radius; ++x) {
for (int y = 0; y < 2 * cloud_radius; ++y) {
bool isFilled = clouds->getGrid(x, y);
for (int i = 0; i < 16; ++i) {
int xp = x * 4 + i % 4;
int yp = y * 4 + i / 4;
image->setPixel(xp, yp, video::SColor(255, isFilled * 255, 0, 0));
}
}
}
buffer->setTextureImage(id, image);
image->drop();
}
private:
Clouds* clouds = nullptr;
u8 id = 0;
TextureBuffer* buffer = nullptr;
};
class CloudDepthStep : public RenderStep {
public:
CloudDepthStep(Clouds* clouds) :
clouds(clouds)
{
}
void setRenderSource(RenderSource* _source) override {}
void setRenderTarget(RenderTarget* _target) override
{
target = _target;
}
void reset(PipelineContext& context) override {}
void run(PipelineContext& context) override {
video::ITexture* texture = source->getTexture(texture_id);
if (texture != last_texture) {
last_texture = texture;
void run(PipelineContext& context) override
{
if (target)
target->activate(context);
if (target)
target->activate(context);
// attach the shader
material.MaterialType = context.client->getShaderSource()->getShaderInfo(shader_id).material;
auto driver = context.device->getVideoDriver();
static const video::SColor color = video::SColor(0, 0, 0, 255);
static const video::S3DVertex vertices[4] = {
video::S3DVertex(1.0, -1.0, 0.0, 0.0, 0.0, -1.0,
color, 1.0, 0.0),
video::S3DVertex(-1.0, -1.0, 0.0, 0.0, 0.0, -1.0,
color, 0.0, 0.0),
video::S3DVertex(-1.0, 1.0, 0.0, 0.0, 0.0, -1.0,
color, 0.0, 1.0),
video::S3DVertex(1.0, 1.0, 0.0, 0.0, 0.0, -1.0,
color, 1.0, 1.0),
};
static const u16 indices[6] = { 0, 1, 2, 2, 3, 0 };
driver->setMaterial(material);
driver->drawVertexPrimitiveList(&vertices, 4, &indices, 2);
}
clouds->renderDepth();
}
private:
u32 shader_id;
u8 texture_id;
video::SMaterial material;
video::ITexture* last_texture = nullptr;
RenderSource* source{ nullptr };
RenderTarget* target{ nullptr };
Clouds* clouds = nullptr;
RenderTarget* target = nullptr;
};
PostProcessingStep::PostProcessingStep(u32 _shader_id, const std::vector<u8> &_texture_map) :
@ -160,6 +210,11 @@ void PostProcessingStep::setWrapRepeat(u8 index, bool value) {
material.TextureLayers[index].TextureWrapV = value ? video::ETC_REPEAT : video::ETC_CLAMP_TO_EDGE;
}
void PostProcessingStep::disableDepthTest() {
material.ZBuffer = video::ECFN_DISABLED;
material.ZWriteEnable = video::EZW_OFF;
}
RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep, v2f scale, Client *client)
{
auto buffer = pipeline->createOwned<TextureBuffer>();
@ -201,8 +256,8 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
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;
const bool enable_volumetric_clouds = true;
// TODO: Add clouds setting
// TODO: Proper constraints
const bool enable_volumetric_clouds = g_settings->getBool("enable_volumetric_clouds") && client->getClouds();
if (enable_ssaa) {
u16 ssaa_scale = MYMAX(2, g_settings->getU16("fsaa"));
@ -226,22 +281,21 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
// post-processing stage
u8 source = TEXTURE_COLOR;
u8 final_color_source = TEXTURE_COLOR;
if (enable_volumetric_clouds) {
const u16 cloud_radius = g_settings->getU16("cloud_radius");
buffer->setTexture(TEXTURE_NOISE, core::dimension2du(256, 256), "noise", color_format);
pipeline->addStep<NoiseStep>(buffer, TEXTURE_NOISE, 256);
shader_id = client->getShaderSource()->getShader("noise_shader", TILE_MATERIAL_PLAIN, NDT_MESH);
RenderStep *noise_step = pipeline->addStep<NoiseStep>(shader_id, TEXTURE_NOISE);
noise_step->setRenderSource(buffer);
noise_step->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_NOISE));
buffer->setTexture(TEXTURE_NOISE_COARSE, core::dimension2du(cloud_radius * 8, cloud_radius * 8), "noise_coarse", color_format);
pipeline->addStep<CloudDensityStep>(buffer, TEXTURE_NOISE_COARSE, client->getClouds());
buffer->setTexture(TEXTURE_NOISE_COARSE, core::dimension2du(256, 256), "noise", color_format);
u32 undersampling = core::clamp(g_settings->getU32("volumetrics_undersampling"), (u32)1, (u32)4);
shader_id = client->getShaderSource()->getShader("coarse_noise_shader", TILE_MATERIAL_PLAIN, NDT_MESH);
noise_step = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8>());
noise_step->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_NOISE_COARSE));
buffer->setTexture(TEXTURE_CLOUDS_1, scale * 0.25f, "clouds_1", color_format, /*clear:*/ true);
buffer->setTexture(TEXTURE_CLOUDS_1, scale / (float)undersampling, "clouds_1", color_format, /*clear:*/ true);
buffer->setTexture(TEXTURE_CLOUDS_2, scale, "clouds_2", color_format);
buffer->setTexture(TEXTURE_CLOUD_DENSITY, scale, "cloud_density", color_format);
@ -253,16 +307,24 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
volumetric_clouds->setBilinearFilter(2, true);
volumetric_clouds->setWrapRepeat(1, true);
volumetric_clouds->setWrapRepeat(2, true);
volumetric_clouds->disableDepthTest();
source = TEXTURE_CLOUDS_1;
shader_id = client->getShaderSource()->getShader("clouds_merge", TILE_MATERIAL_PLAIN, NDT_MESH);
PostProcessingStep* blend_clouds = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_CLOUDS_1, TEXTURE_COLOR });
PostProcessingStep* blend_clouds = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_CLOUDS_1, TEXTURE_COLOR, TEXTURE_DEPTH });
blend_clouds->setRenderSource(buffer);
blend_clouds->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_CLOUDS_2));
blend_clouds->setBilinearFilter(0, true);
blend_clouds->disableDepthTest();
CloudDepthStep* cloud_depth = pipeline->addStep<CloudDepthStep>(client->getClouds());
TextureBufferOutput* cloud_depth_output = pipeline->createOwned<TextureBufferOutput>(buffer, std::vector<u8>{ TEXTURE_COLOR }, TEXTURE_DEPTH);
cloud_depth_output->disableClearing();
cloud_depth->setRenderTarget(cloud_depth_output);
source = TEXTURE_CLOUDS_2;
final_color_source = TEXTURE_CLOUDS_2;
}
// common downsampling step for bloom or autoexposure
@ -281,7 +343,7 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
// get bright spots
u32 shader_id = client->getShaderSource()->getShader("extract_bloom", TILE_MATERIAL_PLAIN, NDT_MESH);
auto extract_bloom = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { source, TEXTURE_EXPOSURE_1 });
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;
@ -332,14 +394,14 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
}
// FXAA
u8 final_stage_source = TEXTURE_CLOUDS_2;
u8 final_stage_source = final_color_source;
if (enable_fxaa) {
final_stage_source = TEXTURE_FXAA;
buffer->setTexture(TEXTURE_FXAA, scale, "fxaa", color_format);
shader_id = client->getShaderSource()->getShader("fxaa", TILE_MATERIAL_PLAIN);
PostProcessingStep *effect = pipeline->createOwned<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_COLOR });
PostProcessingStep* effect = pipeline->createOwned<PostProcessingStep>(shader_id, std::vector<u8> { final_color_source });
pipeline->addStep(effect);
effect->setBilinearFilter(0, true);
effect->setRenderSource(buffer);
@ -348,7 +410,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_SCALE_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

@ -52,6 +52,10 @@ public:
void setWrapRepeat(u8 index, bool value);
void setColor(video::SColor color);
void disableDepthTest();
private:
u32 shader_id;
std::vector<u8> texture_map;

View file

@ -342,6 +342,7 @@ void set_default_settings()
settings->setDefault("bloom_intensity", "0.05");
settings->setDefault("bloom_radius", "1");
settings->setDefault("enable_volumetric_lighting", "false");
settings->setDefault("enable_volumetric_clouds", "false");
settings->setDefault("enable_bumpmaps", "false");
// Effects Shadows