diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h index f99e16da154..e37d593f9fb 100644 --- a/core/command_queue_mt.h +++ b/core/command_queue_mt.h @@ -227,6 +227,27 @@ class CommandQueueMT { virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } }; + template + struct Command12 : public CommandBase { + + T *instance; + M method; + typename GetSimpleTypeT::type_t p1; + typename GetSimpleTypeT::type_t p2; + typename GetSimpleTypeT::type_t p3; + typename GetSimpleTypeT::type_t p4; + typename GetSimpleTypeT::type_t p5; + typename GetSimpleTypeT::type_t p6; + typename GetSimpleTypeT::type_t p7; + typename GetSimpleTypeT::type_t p8; + typename GetSimpleTypeT::type_t p9; + typename GetSimpleTypeT::type_t p10; + typename GetSimpleTypeT::type_t p11; + typename GetSimpleTypeT::type_t p12; + + virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } + }; + /* comands that return */ template @@ -906,6 +927,31 @@ public: if (sync) sync->post(); } + template + void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11, P12 p12) { + + Command12 *cmd = allocate_and_lock >(); + + cmd->instance = p_instance; + cmd->method = p_method; + cmd->p1 = p1; + cmd->p2 = p2; + cmd->p3 = p3; + cmd->p4 = p4; + cmd->p5 = p5; + cmd->p6 = p6; + cmd->p7 = p7; + cmd->p8 = p8; + cmd->p9 = p9; + cmd->p10 = p10; + cmd->p11 = p11; + cmd->p12 = p12; + + unlock(); + + if (sync) sync->post(); + } + /*** PUSH AND RET COMMANDS ***/ template diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 39f027a5aac..ddcb04fa7df 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -895,7 +895,7 @@ void RasterizerSceneGLES3::environment_set_ssr(RID p_env, bool p_enable, int p_m env->ssr_roughness = p_roughness; } -void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur) { +void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VisualServer::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -909,6 +909,8 @@ void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float env->ssao_light_affect = p_light_affect; env->ssao_color = p_color; env->ssao_filter = p_blur; + env->ssao_quality = p_quality; + env->ssao_bilateral_sharpness = p_bilateral_sharpness; } void RasterizerSceneGLES3::environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { @@ -3186,6 +3188,15 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ glDisable(GL_CULL_FACE); glDisable(GL_BLEND); + if (env->ssao_enabled || env->ssr_enabled) { + + //copy normal and roughness to effect buffer + glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo); + glReadBuffer(GL_COLOR_ATTACHMENT2); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->buffers.effect_fbo); + glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + } + if (env->ssao_enabled) { //copy diffuse to front buffer glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo); @@ -3235,6 +3246,8 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ // do SSAO! state.ssao_shader.set_conditional(SsaoShaderGLES3::ENABLE_RADIUS2, env->ssao_radius2 > 0.001); state.ssao_shader.set_conditional(SsaoShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal()); + state.ssao_shader.set_conditional(SsaoShaderGLES3::SSAO_QUALITY_LOW, env->ssao_quality == VS::ENV_SSAO_QUALITY_LOW); + state.ssao_shader.set_conditional(SsaoShaderGLES3::SSAO_QUALITY_HIGH, env->ssao_quality == VS::ENV_SSAO_QUALITY_HIGH); state.ssao_shader.bind(); state.ssao_shader.set_uniform(SsaoShaderGLES3::CAMERA_Z_FAR, p_cam_projection.get_z_far()); state.ssao_shader.set_uniform(SsaoShaderGLES3::CAMERA_Z_NEAR, p_cam_projection.get_z_near()); @@ -3287,6 +3300,9 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ state.ssao_blur_shader.set_uniform(SsaoBlurShaderGLES3::CAMERA_Z_FAR, p_cam_projection.get_z_far()); state.ssao_blur_shader.set_uniform(SsaoBlurShaderGLES3::CAMERA_Z_NEAR, p_cam_projection.get_z_near()); + state.ssao_blur_shader.set_uniform(SsaoBlurShaderGLES3::EDGE_SHARPNESS, env->ssao_bilateral_sharpness); + state.ssao_blur_shader.set_uniform(SsaoBlurShaderGLES3::FILTER_SCALE, int(env->ssao_filter)); + GLint axis[2] = { i, 1 - i }; glUniform2iv(state.ssao_blur_shader.get_uniform(SsaoBlurShaderGLES3::AXIS), 1, axis); glUniform2iv(state.ssao_blur_shader.get_uniform(SsaoBlurShaderGLES3::SCREEN_SIZE), 1, ss); @@ -3295,6 +3311,8 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.ssao.blur_red[i]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->buffers.effect); glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.ssao.blur_fbo[1 - i]); if (i == 0) { glClearBufferfv(GL_COLOR, 0, white.components); // specular @@ -3386,12 +3404,6 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ if (env->ssr_enabled) { - //copy normal and roughness to effect buffer - glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo); - glReadBuffer(GL_COLOR_ATTACHMENT2); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->buffers.effect_fbo); - glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_NEAREST); - //blur diffuse into effect mipmaps using separatable convolution //storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true); _blur_effect_buffer(); diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 28a5cef0ee4..ff691ddcecd 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -379,7 +379,9 @@ public: float ssao_bias; float ssao_light_affect; Color ssao_color; - bool ssao_filter; + VS::EnvironmentSSAOQuality ssao_quality; + float ssao_bilateral_sharpness; + VS::EnvironmentSSAOBlur ssao_filter; bool glow_enabled; int glow_levels; @@ -456,7 +458,9 @@ public: ssao_radius2 = 0.0; ssao_bias = 0.01; ssao_light_affect = 0; - ssao_filter = true; + ssao_filter = VS::ENV_SSAO_BLUR_3x3; + ssao_quality = VS::ENV_SSAO_QUALITY_LOW; + ssao_bilateral_sharpness = 4; tone_mapper = VS::ENV_TONE_MAPPER_LINEAR; tone_mapper_exposure = 1.0; @@ -532,7 +536,7 @@ public: virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture); virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness); - virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur); + virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness); virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale); diff --git a/drivers/gles3/shaders/ssao.glsl b/drivers/gles3/shaders/ssao.glsl index c668e63745f..219f0957e05 100644 --- a/drivers/gles3/shaders/ssao.glsl +++ b/drivers/gles3/shaders/ssao.glsl @@ -13,8 +13,24 @@ void main() { #define TWO_PI 6.283185307179586476925286766559 +#ifdef SSAO_QUALITY_HIGH + +#define NUM_SAMPLES (80) + +#endif + +#ifdef SSAO_QUALITY_LOW + #define NUM_SAMPLES (15) +#endif + +#if !defined(SSAO_QUALITY_LOW) && !defined(SSAO_QUALITY_HIGH) + +#define NUM_SAMPLES (40) + +#endif + // If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower // miplevel to maintain reasonable spatial locality in the cache // If this number is too small (< 3), too many taps will land in the same pixel, and we'll get bad variance that manifests as flashing. @@ -212,12 +228,12 @@ void main() { //visibility=-C.z/camera_z_far; //return; - - //vec3 n_C = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0; - +#if 0 + vec3 n_C = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0; +#else vec3 n_C = reconstructCSFaceNormal(C); n_C = -n_C; - +#endif // Hash function used in the HPG12 AlchemyAO paper float randomPatternRotationAngle = mod(float((3 * ssC.x ^ ssC.y + ssC.x * ssC.y) * 10), TWO_PI); diff --git a/drivers/gles3/shaders/ssao_blur.glsl b/drivers/gles3/shaders/ssao_blur.glsl index c7c978dc374..472dc21acfd 100644 --- a/drivers/gles3/shaders/ssao_blur.glsl +++ b/drivers/gles3/shaders/ssao_blur.glsl @@ -15,6 +15,7 @@ void main() { uniform sampler2D source_ssao; //texunit:0 uniform sampler2D source_depth; //texunit:1 +uniform sampler2D source_normal; //texunit:3 layout(location = 0) out float visibility; @@ -24,7 +25,7 @@ layout(location = 0) out float visibility; // Tunable Parameters: /** Increase to make depth edges crisper. Decrease to reduce flicker. */ -#define EDGE_SHARPNESS (4.0) +uniform float edge_sharpness; /** Step in 2-pixel intervals since we already blurred against neighbors in the first AO pass. This constant can be increased while R decreases to improve @@ -34,7 +35,8 @@ layout(location = 0) out float visibility; unobjectionable after shading was applied but eliminated most temporal incoherence from using small numbers of sample taps. */ -#define SCALE (3) + +uniform int filter_scale; /** Filter radius in pixels. This will be multiplied by SCALE. */ #define R (4) @@ -63,13 +65,14 @@ void main() { ivec2 ssC = ivec2(gl_FragCoord.xy); float depth = texelFetch(source_depth, ssC, 0).r; + //vec3 normal = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0; depth = depth * 2.0 - 1.0; depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); float depth_divide = 1.0 / camera_z_far; - depth*=depth_divide; +// depth*=depth_divide; /* if (depth > camera_z_far*0.999) { @@ -92,20 +95,23 @@ void main() { // so the IF statement has no runtime cost if (r != 0) { - ivec2 ppos = ssC + axis * (r * SCALE); + ivec2 ppos = ssC + axis * (r * filter_scale); float value = texelFetch(source_ssao, clamp(ppos,ivec2(0),clamp_limit), 0).r; - float temp_depth = texelFetch(source_depth, clamp(ssC,ivec2(0),clamp_limit), 0).r; + ivec2 rpos = clamp(ppos,ivec2(0),clamp_limit); + float temp_depth = texelFetch(source_depth, rpos, 0).r; + //vec3 temp_normal = texelFetch(source_normal, rpos, 0).rgb * 2.0 - 1.0; temp_depth = temp_depth * 2.0 - 1.0; temp_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - temp_depth * (camera_z_far - camera_z_near)); - temp_depth *= depth_divide; +// temp_depth *= depth_divide; // spatial domain: offset gaussian tap float weight = 0.3 + gaussian[abs(r)]; + //weight *= max(0.0,dot(temp_normal,normal)); // range domain (the "bilateral" weight). As depth difference increases, decrease weight. weight *= max(0.0, 1.0 - - (EDGE_SHARPNESS * 2000.0) * abs(temp_depth - depth) + - edge_sharpness * abs(temp_depth - depth) ); sum += value * weight; diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 4c6fa7c8a17..910a2ad2fd0 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -377,7 +377,7 @@ bool Environment::is_ssr_rough() const { void Environment::set_ssao_enabled(bool p_enable) { ssao_enabled = p_enable; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, ssao_blur); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); _change_notify(); } @@ -389,7 +389,7 @@ bool Environment::is_ssao_enabled() const { void Environment::set_ssao_radius(float p_radius) { ssao_radius = p_radius; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, ssao_blur); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } float Environment::get_ssao_radius() const { @@ -399,7 +399,7 @@ float Environment::get_ssao_radius() const { void Environment::set_ssao_intensity(float p_intensity) { ssao_intensity = p_intensity; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, ssao_blur); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } float Environment::get_ssao_intensity() const { @@ -410,7 +410,7 @@ float Environment::get_ssao_intensity() const { void Environment::set_ssao_radius2(float p_radius) { ssao_radius2 = p_radius; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, ssao_blur); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } float Environment::get_ssao_radius2() const { @@ -420,7 +420,7 @@ float Environment::get_ssao_radius2() const { void Environment::set_ssao_intensity2(float p_intensity) { ssao_intensity2 = p_intensity; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, ssao_blur); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } float Environment::get_ssao_intensity2() const { @@ -430,7 +430,7 @@ float Environment::get_ssao_intensity2() const { void Environment::set_ssao_bias(float p_bias) { ssao_bias = p_bias; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, ssao_blur); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } float Environment::get_ssao_bias() const { @@ -440,7 +440,7 @@ float Environment::get_ssao_bias() const { void Environment::set_ssao_direct_light_affect(float p_direct_light_affect) { ssao_direct_light_affect = p_direct_light_affect; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, ssao_blur); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } float Environment::get_ssao_direct_light_affect() const { @@ -450,7 +450,7 @@ float Environment::get_ssao_direct_light_affect() const { void Environment::set_ssao_color(const Color &p_color) { ssao_color = p_color; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, ssao_blur); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } Color Environment::get_ssao_color() const { @@ -458,16 +458,38 @@ Color Environment::get_ssao_color() const { return ssao_color; } -void Environment::set_ssao_blur(bool p_enable) { +void Environment::set_ssao_blur(SSAOBlur p_blur) { - ssao_blur = p_enable; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, ssao_blur); + ssao_blur = p_blur; + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } -bool Environment::is_ssao_blur_enabled() const { +Environment::SSAOBlur Environment::get_ssao_blur() const { return ssao_blur; } +void Environment::set_ssao_quality(SSAOQuality p_quality) { + + ssao_quality = p_quality; + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); +} + +Environment::SSAOQuality Environment::get_ssao_quality() const { + + return ssao_quality; +} + +void Environment::set_ssao_edge_sharpness(float p_edge_sharpness) { + + ssao_edge_sharpness = p_edge_sharpness; + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); +} + +float Environment::get_ssao_edge_sharpness() const { + + return ssao_edge_sharpness; +} + void Environment::set_glow_enabled(bool p_enabled) { glow_enabled = p_enabled; @@ -988,8 +1010,14 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_ssao_color", "color"), &Environment::set_ssao_color); ClassDB::bind_method(D_METHOD("get_ssao_color"), &Environment::get_ssao_color); - ClassDB::bind_method(D_METHOD("set_ssao_blur", "enabled"), &Environment::set_ssao_blur); - ClassDB::bind_method(D_METHOD("is_ssao_blur_enabled"), &Environment::is_ssao_blur_enabled); + ClassDB::bind_method(D_METHOD("set_ssao_blur", "mode"), &Environment::set_ssao_blur); + ClassDB::bind_method(D_METHOD("get_ssao_blur"), &Environment::get_ssao_blur); + + ClassDB::bind_method(D_METHOD("set_ssao_quality", "quality"), &Environment::set_ssao_quality); + ClassDB::bind_method(D_METHOD("get_ssao_quality"), &Environment::get_ssao_quality); + + ClassDB::bind_method(D_METHOD("set_ssao_edge_sharpness", "edge_sharpness"), &Environment::set_ssao_edge_sharpness); + ClassDB::bind_method(D_METHOD("get_ssao_edge_sharpness"), &Environment::get_ssao_edge_sharpness); ADD_GROUP("SSAO", "ssao_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssao_enabled"), "set_ssao_enabled", "is_ssao_enabled"); @@ -1000,7 +1028,9 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_bias", PROPERTY_HINT_RANGE, "0.001,8,0.001"), "set_ssao_bias", "get_ssao_bias"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_light_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_direct_light_affect", "get_ssao_direct_light_affect"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ssao_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_ssao_color", "get_ssao_color"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssao_blur"), "set_ssao_blur", "is_ssao_blur_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "ssao_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_ssao_quality", "get_ssao_quality"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "ssao_blur", PROPERTY_HINT_ENUM, "Disabled,1x1,2x2,3x3"), "set_ssao_blur", "get_ssao_blur"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_edge_sharpness", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_ssao_edge_sharpness", "get_ssao_edge_sharpness"); ClassDB::bind_method(D_METHOD("set_dof_blur_far_enabled", "enabled"), &Environment::set_dof_blur_far_enabled); ClassDB::bind_method(D_METHOD("is_dof_blur_far_enabled"), &Environment::is_dof_blur_far_enabled); @@ -1134,6 +1164,10 @@ void Environment::_bind_methods() { BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_LOW); BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_MEDIUM); BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_HIGH); + + BIND_ENUM_CONSTANT(SSAO_QUALITY_LOW); + BIND_ENUM_CONSTANT(SSAO_QUALITY_MEDIUM); + BIND_ENUM_CONSTANT(SSAO_QUALITY_HIGH); } Environment::Environment() { @@ -1179,7 +1213,9 @@ Environment::Environment() { ssao_intensity2 = 1; ssao_bias = 0.01; ssao_direct_light_affect = false; - ssao_blur = true; + ssao_blur = SSAO_BLUR_3x3; + set_ssao_edge_sharpness(4); + set_ssao_quality(SSAO_QUALITY_LOW); glow_enabled = false; glow_levels = (1 << 2) | (1 << 4); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 59098460742..418949a6ade 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -71,6 +71,19 @@ public: DOF_BLUR_QUALITY_HIGH, }; + enum SSAOBlur { + SSAO_BLUR_DISABLED, + SSAO_BLUR_1x1, + SSAO_BLUR_2x2, + SSAO_BLUR_3x3 + }; + + enum SSAOQuality { + SSAO_QUALITY_LOW, + SSAO_QUALITY_MEDIUM, + SSAO_QUALITY_HIGH + }; + private: RID environment; @@ -114,7 +127,9 @@ private: float ssao_bias; float ssao_direct_light_affect; Color ssao_color; - bool ssao_blur; + SSAOBlur ssao_blur; + float ssao_edge_sharpness; + SSAOQuality ssao_quality; bool glow_enabled; int glow_levels; @@ -261,8 +276,14 @@ public: void set_ssao_color(const Color &p_color); Color get_ssao_color() const; - void set_ssao_blur(bool p_enable); - bool is_ssao_blur_enabled() const; + void set_ssao_blur(SSAOBlur p_blur); + SSAOBlur get_ssao_blur() const; + + void set_ssao_quality(SSAOQuality p_quality); + SSAOQuality get_ssao_quality() const; + + void set_ssao_edge_sharpness(float p_edge_sharpness); + float get_ssao_edge_sharpness() const; void set_glow_enabled(bool p_enabled); bool is_glow_enabled() const; @@ -370,5 +391,7 @@ VARIANT_ENUM_CAST(Environment::BGMode) VARIANT_ENUM_CAST(Environment::ToneMapper) VARIANT_ENUM_CAST(Environment::GlowBlendMode) VARIANT_ENUM_CAST(Environment::DOFBlurQuality) +VARIANT_ENUM_CAST(Environment::SSAOQuality) +VARIANT_ENUM_CAST(Environment::SSAOBlur) #endif // ENVIRONMENT_H diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h index 267e5c63b91..51e7f446ea9 100644 --- a/servers/server_wrap_mt_common.h +++ b/servers/server_wrap_mt_common.h @@ -775,3 +775,12 @@ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ } \ } + +#define FUNC12(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12) { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ + } else { \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ + } \ + } diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index b3f6b243ded..cd4b465d79b 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -65,7 +65,7 @@ public: virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) = 0; virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance, bool p_roughness) = 0; - virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur) = 0; + virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0; virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0; diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 888fb29f932..302f13ee4f2 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -652,6 +652,8 @@ public: void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); } #define BIND11(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11) \ void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); } +#define BIND12(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12) \ + void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); } //from now on, calls forwarded to this singleton #define BINDBASE VSG::storage @@ -974,7 +976,7 @@ public: BIND2(environment_set_canvas_max_layer, RID, int) BIND4(environment_set_ambient_light, RID, const Color &, float, float) BIND7(environment_set_ssr, RID, bool, int, float, float, float, bool) - BIND10(environment_set_ssao, RID, bool, float, float, float, float, float, float, const Color &, bool) + BIND12(environment_set_ssao, RID, bool, float, float, float, float, float, float, const Color &, EnvironmentSSAOQuality, EnvironmentSSAOBlur, float) BIND6(environment_set_dof_blur_near, RID, bool, float, float, float, EnvironmentDOFBlurQuality) BIND6(environment_set_dof_blur_far, RID, bool, float, float, float, EnvironmentDOFBlurQuality) diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index caec8902173..67d503dfca3 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -387,7 +387,7 @@ public: FUNC2(environment_set_canvas_max_layer, RID, int) FUNC4(environment_set_ambient_light, RID, const Color &, float, float) FUNC7(environment_set_ssr, RID, bool, int, float, float, float, bool) - FUNC10(environment_set_ssao, RID, bool, float, float, float, float, float, float, const Color &, bool) + FUNC12(environment_set_ssao, RID, bool, float, float, float, float, float, float, const Color &, EnvironmentSSAOQuality, EnvironmentSSAOBlur, float) FUNC6(environment_set_dof_blur_near, RID, bool, float, float, float, EnvironmentDOFBlurQuality) FUNC6(environment_set_dof_blur_far, RID, bool, float, float, float, EnvironmentDOFBlurQuality) diff --git a/servers/visual_server.h b/servers/visual_server.h index 7b83bb929d7..64ed540501b 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -678,7 +678,21 @@ public: virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) = 0; virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness) = 0; - virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur) = 0; + + enum EnvironmentSSAOQuality { + ENV_SSAO_QUALITY_LOW, + ENV_SSAO_QUALITY_MEDIUM, + ENV_SSAO_QUALITY_HIGH, + }; + + enum EnvironmentSSAOBlur { + ENV_SSAO_BLUR_DISABLED, + ENV_SSAO_BLUR_1x1, + ENV_SSAO_BLUR_2x2, + ENV_SSAO_BLUR_3x3, + }; + + virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, EnvironmentSSAOQuality p_quality, EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0; virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) = 0; virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;