forked from Mirrorlandia_minetest/minetest
Improve bloom effect (#12916)
* Remove the built-in exposure factor of 2.5 * Add physics-based bloom (https://learnopengl.com/Guest-Articles/2022/Phys.-Based-Bloom) * Add luminance scaling for bloom layer to simulate HDR * Add setting to control bloom strength
This commit is contained in:
parent
fb3085a2c5
commit
9b24041394
@ -470,21 +470,19 @@ enable_bloom (Enable Bloom) bool false
|
|||||||
# bottom-left - raw base image, bottom-right - bloom texture.
|
# bottom-left - raw base image, bottom-right - bloom texture.
|
||||||
enable_bloom_debug (Enable Bloom Debug) bool false
|
enable_bloom_debug (Enable Bloom Debug) bool false
|
||||||
|
|
||||||
# Set to true to use dedicated texture at each step of bloom effect.
|
# Defines how much bloom is applied to the rendered image
|
||||||
# This is a compatibility setting to avoid visual artifacts
|
|
||||||
# on certain GPUs and video drivers.
|
|
||||||
enable_bloom_dedicated_texture (Enable Bloom Dedicated Texture) bool false
|
|
||||||
|
|
||||||
# Set the intensity of bloom
|
|
||||||
# Smaller values make bloom more subtle
|
# Smaller values make bloom more subtle
|
||||||
# Range: from 0.01 to 1.0, default: 0.05
|
# Range: from 0.01 to 1.0, default: 0.05
|
||||||
bloom_intensity (Bloom Intensity) float 0.05 0.01 1.0
|
bloom_intensity (Bloom Intensity) float 0.05 0.01 1.0
|
||||||
|
|
||||||
# Set the radius of the bloom filter in pixels.
|
# Defines the magnitude of bloom overexposure.
|
||||||
# Larger values render more glow around bright objects
|
# Range: from 0.1 to 10.0, default: 1.0
|
||||||
# at the cost of higher resource consumption.
|
bloom_strength_factor (Bloom Strength Factor) float 1.0 0.1 10.0
|
||||||
# Range: from 1 to 64, default: 16
|
|
||||||
bloom_radius (Bloom Radius) int 16 1 64
|
# Logical value that controls how far the bloom effect spreads
|
||||||
|
# from the bright objects.
|
||||||
|
# Range: from 0.1 to 8, default: 1
|
||||||
|
bloom_radius (Bloom Radius) float 1 0.1 8
|
||||||
|
|
||||||
|
|
||||||
[*Audio]
|
[*Audio]
|
||||||
|
37
client/shaders/bloom_downsample/opengl_fragment.glsl
Normal file
37
client/shaders/bloom_downsample/opengl_fragment.glsl
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// based on Phys.Bloom OpenGL tutorial https://learnopengl.com/Guest-Articles/2022/Phys.-Based-Bloom
|
||||||
|
// and ACM Siggraph talk in 2014 by Jorge Jimenez for Call of Duty: Advanced Warfare.
|
||||||
|
#define rendered texture0
|
||||||
|
|
||||||
|
uniform sampler2D rendered;
|
||||||
|
uniform vec2 texelSize0;
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
varying mediump vec2 varTexCoord;
|
||||||
|
#else
|
||||||
|
centroid varying vec2 varTexCoord;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec2 tx = 2.0 * texelSize0;
|
||||||
|
vec3 a = texture2D(rendered, varTexCoord.st + vec2(-1., -1.) * tx).rgb;
|
||||||
|
vec3 b = texture2D(rendered, varTexCoord.st + vec2(0., -1.) * tx).rgb;
|
||||||
|
vec3 c = texture2D(rendered, varTexCoord.st + vec2(1., -1.) * tx).rgb;
|
||||||
|
vec3 d = texture2D(rendered, varTexCoord.st + vec2(-1., 0.) * tx).rgb;
|
||||||
|
vec3 e = texture2D(rendered, varTexCoord.st + vec2(0., 0.) * tx).rgb;
|
||||||
|
vec3 f = texture2D(rendered, varTexCoord.st + vec2(1., 0.) * tx).rgb;
|
||||||
|
vec3 g = texture2D(rendered, varTexCoord.st + vec2(-1., 1.) * tx).rgb;
|
||||||
|
vec3 h = texture2D(rendered, varTexCoord.st + vec2(0., 1.) * tx).rgb;
|
||||||
|
vec3 i = texture2D(rendered, varTexCoord.st + vec2(1., 1.) * tx).rgb;
|
||||||
|
vec3 j = texture2D(rendered, varTexCoord.st + vec2(-0.5, -0.5) * tx).rgb;
|
||||||
|
vec3 k = texture2D(rendered, varTexCoord.st + vec2(0.5, -0.5) * tx).rgb;
|
||||||
|
vec3 l = texture2D(rendered, varTexCoord.st + vec2(-0.5, 0.5) * tx).rgb;
|
||||||
|
vec3 m = texture2D(rendered, varTexCoord.st + vec2(-0.5, 0.5) * tx).rgb;
|
||||||
|
|
||||||
|
vec3 color =
|
||||||
|
(a + c + g + i) * 0.03125 +
|
||||||
|
(b + d + f + h) * 0.0625 +
|
||||||
|
(e + j + k + l + m) * 0.125;
|
||||||
|
|
||||||
|
gl_FragColor = max(vec4(color, 1.0), 1e-4);
|
||||||
|
}
|
11
client/shaders/bloom_downsample/opengl_vertex.glsl
Normal file
11
client/shaders/bloom_downsample/opengl_vertex.glsl
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifdef GL_ES
|
||||||
|
varying mediump vec2 varTexCoord;
|
||||||
|
#else
|
||||||
|
centroid varying vec2 varTexCoord;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
varTexCoord.st = inTexCoord0.st;
|
||||||
|
gl_Position = inVertexPosition;
|
||||||
|
}
|
35
client/shaders/bloom_upsample/opengl_fragment.glsl
Normal file
35
client/shaders/bloom_upsample/opengl_fragment.glsl
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#define current texture0
|
||||||
|
#define previous texture1
|
||||||
|
|
||||||
|
uniform sampler2D current;
|
||||||
|
uniform sampler2D previous;
|
||||||
|
uniform vec2 texelSize0;
|
||||||
|
uniform mediump float bloomRadius;
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
varying mediump vec2 varTexCoord;
|
||||||
|
#else
|
||||||
|
centroid varying vec2 varTexCoord;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec2 offset = bloomRadius * texelSize0;
|
||||||
|
|
||||||
|
vec3 a = texture2D(previous, varTexCoord.st + vec2(-1., -1.) * offset).rgb;
|
||||||
|
vec3 b = texture2D(previous, varTexCoord.st + vec2(0., -1.) * offset).rgb;
|
||||||
|
vec3 c = texture2D(previous, varTexCoord.st + vec2(1., -1.) * offset).rgb;
|
||||||
|
vec3 d = texture2D(previous, varTexCoord.st + vec2(-1., 0.) * offset).rgb;
|
||||||
|
vec3 e = texture2D(previous, varTexCoord.st + vec2(0., 0.) * offset).rgb;
|
||||||
|
vec3 f = texture2D(previous, varTexCoord.st + vec2(1., 0.) * offset).rgb;
|
||||||
|
vec3 g = texture2D(previous, varTexCoord.st + vec2(-1., 1.) * offset).rgb;
|
||||||
|
vec3 h = texture2D(previous, varTexCoord.st + vec2(0., 1.) * offset).rgb;
|
||||||
|
vec3 i = texture2D(previous, varTexCoord.st + vec2(1., 1.) * offset).rgb;
|
||||||
|
|
||||||
|
vec3 base = texture2D(current, varTexCoord.st).rgb;
|
||||||
|
|
||||||
|
gl_FragColor = max(vec4(base +
|
||||||
|
(a + c + g + i) * 0.0625 +
|
||||||
|
(b + d + f + h) * 0.125 +
|
||||||
|
e * 0.25, 1.), 1e-4);
|
||||||
|
}
|
11
client/shaders/bloom_upsample/opengl_vertex.glsl
Normal file
11
client/shaders/bloom_upsample/opengl_vertex.glsl
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifdef GL_ES
|
||||||
|
varying mediump vec2 varTexCoord;
|
||||||
|
#else
|
||||||
|
centroid varying vec2 varTexCoord;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
varTexCoord.st = inTexCoord0.st;
|
||||||
|
gl_Position = inVertexPosition;
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
uniform sampler2D rendered;
|
uniform sampler2D rendered;
|
||||||
uniform vec2 texelSize0;
|
uniform vec2 texelSize0;
|
||||||
uniform mediump float bloomRadius;
|
uniform mediump float bloomRadius;
|
||||||
|
uniform mat3 bloomBlurWeights;
|
||||||
|
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
varying mediump vec2 varTexCoord;
|
varying mediump vec2 varTexCoord;
|
||||||
@ -10,6 +11,13 @@ varying mediump vec2 varTexCoord;
|
|||||||
centroid varying vec2 varTexCoord;
|
centroid varying vec2 varTexCoord;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// smoothstep - squared
|
||||||
|
float smstsq(float f)
|
||||||
|
{
|
||||||
|
f = f * f * (3 - 2 * f);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
// kernel distance and linear size
|
// kernel distance and linear size
|
||||||
@ -19,8 +27,8 @@ void main(void)
|
|||||||
vec4 color = vec4(0.);
|
vec4 color = vec4(0.);
|
||||||
mediump float sum = 0.;
|
mediump float sum = 0.;
|
||||||
for (mediump float i = 0.; i < n; i++) {
|
for (mediump float i = 0.; i < n; i++) {
|
||||||
mediump float weight = pow(1. - (abs(i / bloomRadius - 1.)), 1.3);
|
mediump float weight = smstsq(1. - (abs(i / bloomRadius - 1.)));
|
||||||
color += texture2D(rendered, uv).rgba * weight;
|
color.rgb += texture2D(rendered, uv).rgb * weight;
|
||||||
sum += weight;
|
sum += weight;
|
||||||
uv += vec2(texelSize0.x, 0.);
|
uv += vec2(texelSize0.x, 0.);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
uniform sampler2D rendered;
|
uniform sampler2D rendered;
|
||||||
uniform vec2 texelSize0;
|
uniform vec2 texelSize0;
|
||||||
uniform mediump float bloomRadius;
|
uniform mediump float bloomRadius;
|
||||||
|
uniform mat3 bloomBlurWeights;
|
||||||
|
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
varying mediump vec2 varTexCoord;
|
varying mediump vec2 varTexCoord;
|
||||||
@ -10,6 +11,13 @@ varying mediump vec2 varTexCoord;
|
|||||||
centroid varying vec2 varTexCoord;
|
centroid varying vec2 varTexCoord;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// smoothstep - squared
|
||||||
|
float smstsq(float f)
|
||||||
|
{
|
||||||
|
f = f * f * (3 - 2 * f);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
// kernel distance and linear size
|
// kernel distance and linear size
|
||||||
@ -19,8 +27,8 @@ void main(void)
|
|||||||
vec4 color = vec4(0.);
|
vec4 color = vec4(0.);
|
||||||
mediump float sum = 0.;
|
mediump float sum = 0.;
|
||||||
for (mediump float i = 0.; i < n; i++) {
|
for (mediump float i = 0.; i < n; i++) {
|
||||||
mediump float weight = pow(1. - (abs(i / bloomRadius - 1.)), 1.3);
|
mediump float weight = smstsq(1. - (abs(i / bloomRadius - 1.)));
|
||||||
color += texture2D(rendered, uv).rgba * weight;
|
color.rgb += texture2D(rendered, uv).rgb * weight;
|
||||||
sum += weight;
|
sum += weight;
|
||||||
uv += vec2(0., texelSize0.y);
|
uv += vec2(0., texelSize0.y);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
uniform sampler2D rendered;
|
uniform sampler2D rendered;
|
||||||
uniform mediump float exposureFactor;
|
uniform mediump float exposureFactor;
|
||||||
uniform float bloomLuminanceThreshold;
|
uniform mediump float bloomStrength;
|
||||||
|
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
varying mediump vec2 varTexCoord;
|
varying mediump vec2 varTexCoord;
|
||||||
@ -14,8 +14,14 @@ centroid varying vec2 varTexCoord;
|
|||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
vec2 uv = varTexCoord.st;
|
vec2 uv = varTexCoord.st;
|
||||||
vec4 color = texture2D(rendered, uv).rgba;
|
vec3 color = texture2D(rendered, uv).rgb;
|
||||||
// translate to linear colorspace (approximate)
|
// translate to linear colorspace (approximate)
|
||||||
color.rgb = pow(color.rgb, vec3(2.2)) * exposureFactor;
|
color = pow(color, vec3(2.2));
|
||||||
gl_FragColor = vec4(color.rgb, 1.0); // force full alpha to avoid holes in the image.
|
|
||||||
|
// Scale colors by luminance to amplify bright colors
|
||||||
|
// in SDR textures.
|
||||||
|
float luminance = dot(color, vec3(0.213, 0.515, 0.072));
|
||||||
|
luminance *= luminance;
|
||||||
|
color *= luminance * exposureFactor * bloomStrength;
|
||||||
|
gl_FragColor = vec4(color, 1.0); // force full alpha to avoid holes in the image.
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,14 @@ centroid varying vec2 varTexCoord;
|
|||||||
|
|
||||||
vec4 applyBloom(vec4 color, vec2 uv)
|
vec4 applyBloom(vec4 color, vec2 uv)
|
||||||
{
|
{
|
||||||
float bias = bloomIntensity;
|
vec3 light = texture2D(bloom, uv).rgb;
|
||||||
vec4 bloom = texture2D(bloom, uv);
|
|
||||||
#ifdef ENABLE_BLOOM_DEBUG
|
#ifdef ENABLE_BLOOM_DEBUG
|
||||||
if (uv.x > 0.5 && uv.y < 0.5)
|
if (uv.x > 0.5 && uv.y < 0.5)
|
||||||
return vec4(bloom.rgb, color.a);
|
return vec4(light, color.a);
|
||||||
if (uv.x < 0.5)
|
if (uv.x < 0.5)
|
||||||
return color;
|
return light;
|
||||||
#endif
|
#endif
|
||||||
color.rgb = mix(color.rgb, bloom.rgb, bias);
|
color.rgb = mix(color.rgb, light, bloomIntensity);
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,8 +85,6 @@ void main(void)
|
|||||||
{
|
{
|
||||||
#if ENABLE_TONE_MAPPING
|
#if ENABLE_TONE_MAPPING
|
||||||
color = applyToneMapping(color);
|
color = applyToneMapping(color);
|
||||||
#else
|
|
||||||
color.rgb /= 2.5; // default exposure factor, see also RenderingEngine::DEFAULT_EXPOSURE_FACTOR;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,6 +432,8 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter
|
|||||||
bool m_bloom_enabled;
|
bool m_bloom_enabled;
|
||||||
CachedPixelShaderSetting<float> m_bloom_intensity_pixel;
|
CachedPixelShaderSetting<float> m_bloom_intensity_pixel;
|
||||||
float m_bloom_intensity;
|
float m_bloom_intensity;
|
||||||
|
CachedPixelShaderSetting<float> m_bloom_strength_pixel;
|
||||||
|
float m_bloom_strength;
|
||||||
CachedPixelShaderSetting<float> m_bloom_radius_pixel;
|
CachedPixelShaderSetting<float> m_bloom_radius_pixel;
|
||||||
float m_bloom_radius;
|
float m_bloom_radius;
|
||||||
|
|
||||||
@ -444,8 +446,10 @@ public:
|
|||||||
m_user_exposure_factor = g_settings->getFloat("exposure_factor", 0.1f, 10.0f);
|
m_user_exposure_factor = g_settings->getFloat("exposure_factor", 0.1f, 10.0f);
|
||||||
if (name == "bloom_intensity")
|
if (name == "bloom_intensity")
|
||||||
m_bloom_intensity = g_settings->getFloat("bloom_intensity", 0.01f, 1.0f);
|
m_bloom_intensity = g_settings->getFloat("bloom_intensity", 0.01f, 1.0f);
|
||||||
|
if (name == "bloom_strength_factor")
|
||||||
|
m_bloom_strength = RenderingEngine::BASE_BLOOM_STRENGTH * g_settings->getFloat("bloom_strength_factor", 0.1f, 10.0f);
|
||||||
if (name == "bloom_radius")
|
if (name == "bloom_radius")
|
||||||
m_bloom_radius = g_settings->getFloat("bloom_radius", 1.0f, 64.0f);
|
m_bloom_radius = g_settings->getFloat("bloom_radius", 0.1f, 8.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void settingsCallback(const std::string &name, void *userdata)
|
static void settingsCallback(const std::string &name, void *userdata)
|
||||||
@ -479,17 +483,20 @@ public:
|
|||||||
m_texel_size0("texelSize0"),
|
m_texel_size0("texelSize0"),
|
||||||
m_exposure_factor_pixel("exposureFactor"),
|
m_exposure_factor_pixel("exposureFactor"),
|
||||||
m_bloom_intensity_pixel("bloomIntensity"),
|
m_bloom_intensity_pixel("bloomIntensity"),
|
||||||
|
m_bloom_strength_pixel("bloomStrength"),
|
||||||
m_bloom_radius_pixel("bloomRadius")
|
m_bloom_radius_pixel("bloomRadius")
|
||||||
{
|
{
|
||||||
g_settings->registerChangedCallback("enable_fog", settingsCallback, this);
|
g_settings->registerChangedCallback("enable_fog", settingsCallback, this);
|
||||||
g_settings->registerChangedCallback("exposure_factor", settingsCallback, this);
|
g_settings->registerChangedCallback("exposure_factor", settingsCallback, this);
|
||||||
g_settings->registerChangedCallback("bloom_intensity", settingsCallback, this);
|
g_settings->registerChangedCallback("bloom_intensity", settingsCallback, this);
|
||||||
|
g_settings->registerChangedCallback("bloom_strength_factor", settingsCallback, this);
|
||||||
g_settings->registerChangedCallback("bloom_radius", settingsCallback, this);
|
g_settings->registerChangedCallback("bloom_radius", settingsCallback, this);
|
||||||
m_fog_enabled = g_settings->getBool("enable_fog");
|
m_fog_enabled = g_settings->getBool("enable_fog");
|
||||||
m_user_exposure_factor = g_settings->getFloat("exposure_factor", 0.1f, 10.0f);
|
m_user_exposure_factor = g_settings->getFloat("exposure_factor", 0.1f, 10.0f);
|
||||||
m_bloom_enabled = g_settings->getBool("enable_bloom");
|
m_bloom_enabled = g_settings->getBool("enable_bloom");
|
||||||
m_bloom_intensity = g_settings->getFloat("bloom_intensity", 0.01f, 1.0f);
|
m_bloom_intensity = g_settings->getFloat("bloom_intensity", 0.01f, 1.0f);
|
||||||
m_bloom_radius = g_settings->getFloat("bloom_radius", 1.0f, 64.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);
|
||||||
}
|
}
|
||||||
|
|
||||||
~GameGlobalShaderConstantSetter()
|
~GameGlobalShaderConstantSetter()
|
||||||
@ -567,14 +574,15 @@ public:
|
|||||||
|
|
||||||
m_texel_size0.set(m_texel_size0_values.data(), services);
|
m_texel_size0.set(m_texel_size0_values.data(), services);
|
||||||
|
|
||||||
float exposure_factor = RenderingEngine::DEFAULT_EXPOSURE_FACTOR * m_user_exposure_factor;
|
float exposure_factor = m_user_exposure_factor;
|
||||||
if (std::isnan(exposure_factor))
|
if (std::isnan(exposure_factor))
|
||||||
exposure_factor = RenderingEngine::DEFAULT_EXPOSURE_FACTOR;
|
exposure_factor = 1.0f;
|
||||||
m_exposure_factor_pixel.set(&exposure_factor, services);
|
m_exposure_factor_pixel.set(&exposure_factor, services);
|
||||||
|
|
||||||
if (m_bloom_enabled) {
|
if (m_bloom_enabled) {
|
||||||
m_bloom_intensity_pixel.set(&m_bloom_intensity, services);
|
m_bloom_intensity_pixel.set(&m_bloom_intensity, services);
|
||||||
m_bloom_radius_pixel.set(&m_bloom_radius, services);
|
m_bloom_radius_pixel.set(&m_bloom_radius, services);
|
||||||
|
m_bloom_strength_pixel.set(&m_bloom_strength, services);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,9 +390,10 @@ public:
|
|||||||
* @return RenderStep* Pointer to the created step for further configuration.
|
* @return RenderStep* Pointer to the created step for further configuration.
|
||||||
*/
|
*/
|
||||||
template<typename T, typename... Args>
|
template<typename T, typename... Args>
|
||||||
RenderStep *addStep(Args&&... args) {
|
T *addStep(Args&&... args) {
|
||||||
T* result = own(std::make_unique<T>(std::forward<Args>(args)...));
|
T* result = own(std::make_unique<T>(std::forward<Args>(args)...));
|
||||||
return addStep(result);
|
addStep(result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderSource *getInput();
|
RenderSource *getInput();
|
||||||
|
@ -115,8 +115,8 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
|
|||||||
static const u8 TEXTURE_COLOR = 0;
|
static const u8 TEXTURE_COLOR = 0;
|
||||||
static const u8 TEXTURE_DEPTH = 1;
|
static const u8 TEXTURE_DEPTH = 1;
|
||||||
static const u8 TEXTURE_BLOOM = 2;
|
static const u8 TEXTURE_BLOOM = 2;
|
||||||
static const u8 TEXTURE_BLUR = 3;
|
static const u8 TEXTURE_BLOOM_DOWN = 10;
|
||||||
static const u8 TEXTURE_BLUR_SECONDARY = 4;
|
static const u8 TEXTURE_BLOOM_UP = 20;
|
||||||
|
|
||||||
buffer->setTexture(TEXTURE_COLOR, scale, "3d_render", color_format);
|
buffer->setTexture(TEXTURE_COLOR, scale, "3d_render", color_format);
|
||||||
buffer->setTexture(TEXTURE_DEPTH, scale, "3d_depthmap", depth_format);
|
buffer->setTexture(TEXTURE_DEPTH, scale, "3d_depthmap", depth_format);
|
||||||
@ -124,39 +124,56 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
|
|||||||
// attach buffer to the previous step
|
// attach buffer to the previous step
|
||||||
previousStep->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, std::vector<u8> { TEXTURE_COLOR }, TEXTURE_DEPTH));
|
previousStep->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, std::vector<u8> { TEXTURE_COLOR }, TEXTURE_DEPTH));
|
||||||
|
|
||||||
|
// shared variables
|
||||||
|
u32 shader_id;
|
||||||
|
|
||||||
// post-processing stage
|
// post-processing stage
|
||||||
// set up bloom
|
// set up bloom
|
||||||
if (g_settings->getBool("enable_bloom")) {
|
if (g_settings->getBool("enable_bloom")) {
|
||||||
|
|
||||||
buffer->setTexture(TEXTURE_BLUR, scale * 0.5, "blur", color_format);
|
|
||||||
buffer->setTexture(TEXTURE_BLOOM, scale * 0.5, "bloom", color_format);
|
|
||||||
u8 bloom_input_texture = TEXTURE_BLOOM;
|
|
||||||
|
|
||||||
if (g_settings->getBool("enable_bloom_dedicated_texture")) {
|
buffer->setTexture(TEXTURE_BLOOM, scale, "bloom", color_format);
|
||||||
buffer->setTexture(TEXTURE_BLUR_SECONDARY, scale * 0.5, "blur2", color_format);
|
|
||||||
bloom_input_texture = TEXTURE_BLUR_SECONDARY;
|
const u8 MIPMAP_LEVELS = 4;
|
||||||
|
v2f downscale = scale * 0.5;
|
||||||
|
for (u8 i = 0; i < MIPMAP_LEVELS; i++) {
|
||||||
|
buffer->setTexture(TEXTURE_BLOOM_DOWN + i, downscale, std::string("bloom_down") + std::to_string(i), color_format);
|
||||||
|
buffer->setTexture(TEXTURE_BLOOM_UP + i, downscale, std::string("bloom_up") + std::to_string(i), color_format);
|
||||||
|
downscale *= 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get bright spots
|
// get bright spots
|
||||||
u32 shader_id = client->getShaderSource()->getShader("extract_bloom", TILE_MATERIAL_PLAIN, NDT_MESH);
|
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 });
|
RenderStep *extract_bloom = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_COLOR });
|
||||||
extract_bloom->setRenderSource(buffer);
|
extract_bloom->setRenderSource(buffer);
|
||||||
extract_bloom->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, bloom_input_texture));
|
extract_bloom->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_BLOOM));
|
||||||
// horizontal blur
|
|
||||||
shader_id = client->getShaderSource()->getShader("blur_h", TILE_MATERIAL_PLAIN, NDT_MESH);
|
// downsample
|
||||||
RenderStep *blur_h = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { bloom_input_texture });
|
shader_id = client->getShaderSource()->getShader("bloom_downsample", TILE_MATERIAL_PLAIN, NDT_MESH);
|
||||||
blur_h->setRenderSource(buffer);
|
u8 source = TEXTURE_BLOOM;
|
||||||
blur_h->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_BLUR));
|
for (u8 i = 0; i < MIPMAP_LEVELS; i++) {
|
||||||
// vertical blur
|
auto step = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { source });
|
||||||
shader_id = client->getShaderSource()->getShader("blur_v", TILE_MATERIAL_PLAIN, NDT_MESH);
|
step->setRenderSource(buffer);
|
||||||
RenderStep *blur_v = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_BLUR });
|
step->setBilinearFilter(0, true);
|
||||||
blur_v->setRenderSource(buffer);
|
step->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_BLOOM_DOWN + i));
|
||||||
blur_v->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_BLOOM));
|
source = TEXTURE_BLOOM_DOWN + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 });
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// final post-processing
|
// final post-processing
|
||||||
u32 shader_id = client->getShaderSource()->getShader("second_stage", TILE_MATERIAL_PLAIN, NDT_MESH);
|
shader_id = client->getShaderSource()->getShader("second_stage", TILE_MATERIAL_PLAIN, NDT_MESH);
|
||||||
PostProcessingStep *effect = pipeline->createOwned<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_COLOR, TEXTURE_BLOOM });
|
PostProcessingStep *effect = pipeline->createOwned<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_COLOR, TEXTURE_BLOOM_UP });
|
||||||
pipeline->addStep(effect);
|
pipeline->addStep(effect);
|
||||||
effect->setBilinearFilter(1, true); // apply filter to the bloom
|
effect->setBilinearFilter(1, true); // apply filter to the bloom
|
||||||
effect->setRenderSource(buffer);
|
effect->setRenderSource(buffer);
|
||||||
|
@ -56,6 +56,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
RenderingEngine *RenderingEngine::s_singleton = nullptr;
|
RenderingEngine *RenderingEngine::s_singleton = nullptr;
|
||||||
|
const float RenderingEngine::BASE_BLOOM_STRENGTH = 8.0f;
|
||||||
|
|
||||||
|
|
||||||
static gui::GUISkin *createSkin(gui::IGUIEnvironment *environment,
|
static gui::GUISkin *createSkin(gui::IGUIEnvironment *environment,
|
||||||
|
@ -46,9 +46,7 @@ class RenderingCore;
|
|||||||
class RenderingEngine
|
class RenderingEngine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Default color factor before applying effects like bloom or tomemapping
|
static const float BASE_BLOOM_STRENGTH;
|
||||||
/// this is derived from tonemapping code and tuned empirically
|
|
||||||
static constexpr float DEFAULT_EXPOSURE_FACTOR = 2.5f;
|
|
||||||
|
|
||||||
RenderingEngine(IEventReceiver *eventReceiver);
|
RenderingEngine(IEventReceiver *eventReceiver);
|
||||||
~RenderingEngine();
|
~RenderingEngine();
|
||||||
|
@ -273,9 +273,9 @@ void set_default_settings()
|
|||||||
settings->setDefault("exposure_factor", "1.0");
|
settings->setDefault("exposure_factor", "1.0");
|
||||||
settings->setDefault("enable_bloom", "false");
|
settings->setDefault("enable_bloom", "false");
|
||||||
settings->setDefault("enable_bloom_debug", "false");
|
settings->setDefault("enable_bloom_debug", "false");
|
||||||
settings->setDefault("enable_bloom_dedicated_texture", "false");
|
settings->setDefault("bloom_strength_factor", "1.0");
|
||||||
settings->setDefault("bloom_intensity", "0.05");
|
settings->setDefault("bloom_intensity", "0.05");
|
||||||
settings->setDefault("bloom_radius", "16");
|
settings->setDefault("bloom_radius", "1");
|
||||||
|
|
||||||
// Effects Shadows
|
// Effects Shadows
|
||||||
settings->setDefault("enable_dynamic_shadows", "false");
|
settings->setDefault("enable_dynamic_shadows", "false");
|
||||||
|
Loading…
Reference in New Issue
Block a user