Re-Added screen space reflection.
This commit is contained in:
parent
ff14d071cc
commit
87c658b304
|
@ -365,9 +365,10 @@ void EditorNode::_notification(int p_what) {
|
|||
RS::get_singleton()->camera_effects_set_dof_blur_quality(dof_quality, dof_jitter);
|
||||
RS::get_singleton()->environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/quality/ssao/quality"))), GLOBAL_GET("rendering/quality/ssao/half_size"));
|
||||
RS::get_singleton()->screen_space_roughness_limiter_set_active(GLOBAL_GET("rendering/quality/filters/screen_space_roughness_limiter"), GLOBAL_GET("rendering/quality/filters/screen_space_roughness_limiter_curve"));
|
||||
|
||||
bool glow_bicubic = int(GLOBAL_GET("rendering/quality/glow/upscale_mode")) > 0;
|
||||
RS::get_singleton()->environment_glow_set_use_bicubic_upscale(glow_bicubic);
|
||||
RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/quality/screen_space_reflection/roughness_quality")));
|
||||
RS::get_singleton()->environment_set_ssr_roughness_quality(ssr_roughness_quality);
|
||||
}
|
||||
|
||||
ResourceImporterTexture::get_singleton()->update_imports();
|
||||
|
|
|
@ -850,6 +850,9 @@ void register_scene_types() {
|
|||
ClassDB::add_compatibility_class("VisualShaderNodeScalarOp", "VisualShaderNodeFloatOp");
|
||||
ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform");
|
||||
ClassDB::add_compatibility_class("World", "World3D");
|
||||
ClassDB::add_compatibility_class("ProceduralSky", "Sky");
|
||||
ClassDB::add_compatibility_class("PanoramaSky", "Sky");
|
||||
|
||||
#endif
|
||||
|
||||
OS::get_singleton()->yield(); //may take time to init
|
||||
|
|
|
@ -389,7 +389,7 @@ void Environment::_validate_property(PropertyInfo &property) const {
|
|||
void Environment::set_ssr_enabled(bool p_enable) {
|
||||
|
||||
ssr_enabled = p_enable;
|
||||
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
|
||||
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance);
|
||||
_change_notify();
|
||||
}
|
||||
|
||||
|
@ -401,7 +401,7 @@ bool Environment::is_ssr_enabled() const {
|
|||
void Environment::set_ssr_max_steps(int p_steps) {
|
||||
|
||||
ssr_max_steps = p_steps;
|
||||
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
|
||||
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance);
|
||||
}
|
||||
int Environment::get_ssr_max_steps() const {
|
||||
|
||||
|
@ -411,7 +411,7 @@ int Environment::get_ssr_max_steps() const {
|
|||
void Environment::set_ssr_fade_in(float p_fade_in) {
|
||||
|
||||
ssr_fade_in = p_fade_in;
|
||||
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
|
||||
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance);
|
||||
}
|
||||
float Environment::get_ssr_fade_in() const {
|
||||
|
||||
|
@ -421,7 +421,7 @@ float Environment::get_ssr_fade_in() const {
|
|||
void Environment::set_ssr_fade_out(float p_fade_out) {
|
||||
|
||||
ssr_fade_out = p_fade_out;
|
||||
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
|
||||
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance);
|
||||
}
|
||||
float Environment::get_ssr_fade_out() const {
|
||||
|
||||
|
@ -431,23 +431,13 @@ float Environment::get_ssr_fade_out() const {
|
|||
void Environment::set_ssr_depth_tolerance(float p_depth_tolerance) {
|
||||
|
||||
ssr_depth_tolerance = p_depth_tolerance;
|
||||
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
|
||||
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance);
|
||||
}
|
||||
float Environment::get_ssr_depth_tolerance() const {
|
||||
|
||||
return ssr_depth_tolerance;
|
||||
}
|
||||
|
||||
void Environment::set_ssr_rough(bool p_enable) {
|
||||
|
||||
ssr_roughness = p_enable;
|
||||
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
|
||||
}
|
||||
bool Environment::is_ssr_rough() const {
|
||||
|
||||
return ssr_roughness;
|
||||
}
|
||||
|
||||
void Environment::set_ssao_enabled(bool p_enable) {
|
||||
|
||||
ssao_enabled = p_enable;
|
||||
|
@ -981,16 +971,12 @@ void Environment::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_ssr_depth_tolerance", "depth_tolerance"), &Environment::set_ssr_depth_tolerance);
|
||||
ClassDB::bind_method(D_METHOD("get_ssr_depth_tolerance"), &Environment::get_ssr_depth_tolerance);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_ssr_rough", "rough"), &Environment::set_ssr_rough);
|
||||
ClassDB::bind_method(D_METHOD("is_ssr_rough"), &Environment::is_ssr_rough);
|
||||
|
||||
ADD_GROUP("SS Reflections", "ss_reflections_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ss_reflections_enabled"), "set_ssr_enabled", "is_ssr_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "ss_reflections_max_steps", PROPERTY_HINT_RANGE, "1,512,1"), "set_ssr_max_steps", "get_ssr_max_steps");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ss_reflections_fade_in", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_in", "get_ssr_fade_in");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ss_reflections_fade_out", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_out", "get_ssr_fade_out");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ss_reflections_depth_tolerance", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssr_depth_tolerance", "get_ssr_depth_tolerance");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ss_reflections_roughness"), "set_ssr_rough", "is_ssr_rough");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ss_reflections_depth_tolerance", PROPERTY_HINT_RANGE, "0.01,128,0.1"), "set_ssr_depth_tolerance", "get_ssr_depth_tolerance");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_ssao_enabled", "enabled"), &Environment::set_ssao_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_ssao_enabled"), &Environment::is_ssao_enabled);
|
||||
|
@ -1173,7 +1159,6 @@ Environment::Environment() :
|
|||
ssr_fade_in = 0.15;
|
||||
ssr_fade_out = 2.0;
|
||||
ssr_depth_tolerance = 0.2;
|
||||
ssr_roughness = true;
|
||||
|
||||
ssao_enabled = false;
|
||||
ssao_radius = 1;
|
||||
|
|
|
@ -125,7 +125,6 @@ private:
|
|||
float ssr_fade_in;
|
||||
float ssr_fade_out;
|
||||
float ssr_depth_tolerance;
|
||||
bool ssr_roughness;
|
||||
|
||||
bool ssao_enabled;
|
||||
float ssao_radius;
|
||||
|
@ -257,9 +256,6 @@ public:
|
|||
void set_ssr_depth_tolerance(float p_depth_tolerance);
|
||||
float get_ssr_depth_tolerance() const;
|
||||
|
||||
void set_ssr_rough(bool p_enable);
|
||||
bool is_ssr_rough() const;
|
||||
|
||||
void set_ssao_enabled(bool p_enable);
|
||||
bool is_ssao_enabled() const;
|
||||
|
||||
|
|
|
@ -79,7 +79,9 @@ public:
|
|||
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
|
||||
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_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0;
|
||||
virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0;
|
||||
|
||||
virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0;
|
||||
|
||||
virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) = 0;
|
||||
|
@ -107,7 +109,6 @@ public:
|
|||
struct InstanceBase;
|
||||
|
||||
struct InstanceDependency {
|
||||
|
||||
void instance_notify_changed(bool p_aabb, bool p_dependencies);
|
||||
void instance_notify_deleted(RID p_deleted);
|
||||
|
||||
|
@ -119,7 +120,6 @@ public:
|
|||
};
|
||||
|
||||
struct InstanceBase {
|
||||
|
||||
RS::InstanceType base_type;
|
||||
RID base;
|
||||
|
||||
|
@ -231,7 +231,9 @@ public:
|
|||
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0;
|
||||
virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0) = 0;
|
||||
virtual void light_instance_mark_visible(RID p_light_instance) = 0;
|
||||
virtual bool light_instances_can_render_shadow_cube() const { return true; }
|
||||
virtual bool light_instances_can_render_shadow_cube() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual RID reflection_atlas_create() = 0;
|
||||
virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) = 0;
|
||||
|
|
|
@ -50,6 +50,16 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar
|
|||
p_array[11] = 0;
|
||||
}
|
||||
|
||||
static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
|
||||
p_array[i * 4 + j] = p_mtx.matrix[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RID RasterizerEffectsRD::_get_uniform_set_from_image(RID p_image) {
|
||||
|
||||
if (image_to_uniform_set_cache.has(p_image)) {
|
||||
|
@ -120,6 +130,80 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bo
|
|||
return uniform_set;
|
||||
}
|
||||
|
||||
RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_texture1, RID p_texture2, bool p_use_mipmaps) {
|
||||
|
||||
TexturePair tp;
|
||||
tp.texture1 = p_texture1;
|
||||
tp.texture2 = p_texture2;
|
||||
|
||||
if (texture_pair_to_compute_uniform_set_cache.has(tp)) {
|
||||
RID uniform_set = texture_pair_to_compute_uniform_set_cache[tp];
|
||||
if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
|
||||
return uniform_set;
|
||||
}
|
||||
}
|
||||
|
||||
Vector<RD::Uniform> uniforms;
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
|
||||
u.binding = 0;
|
||||
u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler);
|
||||
u.ids.push_back(p_texture1);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
|
||||
u.binding = 1;
|
||||
u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler);
|
||||
u.ids.push_back(p_texture2);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
//any thing with the same configuration (one texture in binding 0 for set 0), is good
|
||||
RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0), 1);
|
||||
|
||||
texture_pair_to_compute_uniform_set_cache[tp] = uniform_set;
|
||||
|
||||
return uniform_set;
|
||||
}
|
||||
|
||||
RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1, RID p_texture2) {
|
||||
|
||||
TexturePair tp;
|
||||
tp.texture1 = p_texture1;
|
||||
tp.texture2 = p_texture2;
|
||||
|
||||
if (image_pair_to_compute_uniform_set_cache.has(tp)) {
|
||||
RID uniform_set = image_pair_to_compute_uniform_set_cache[tp];
|
||||
if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
|
||||
return uniform_set;
|
||||
}
|
||||
}
|
||||
|
||||
Vector<RD::Uniform> uniforms;
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_IMAGE;
|
||||
u.binding = 0;
|
||||
u.ids.push_back(p_texture1);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_IMAGE;
|
||||
u.binding = 1;
|
||||
u.ids.push_back(p_texture2);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
//any thing with the same configuration (one texture in binding 0 for set 0), is good
|
||||
RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0), 3);
|
||||
|
||||
image_pair_to_compute_uniform_set_cache[tp] = uniform_set;
|
||||
|
||||
return uniform_set;
|
||||
}
|
||||
|
||||
void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y, bool p_force_luminance) {
|
||||
|
||||
zeromem(&blur.push_constant, sizeof(BlurPushConstant));
|
||||
|
@ -218,6 +302,7 @@ void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_framebuff
|
|||
blur.push_constant.glow_exposure = p_exposure;
|
||||
blur.push_constant.glow_white = 0; //actually unused
|
||||
blur.push_constant.glow_luminance_cap = p_luminance_cap;
|
||||
|
||||
blur.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also
|
||||
|
||||
//HORIZONTAL
|
||||
|
@ -250,6 +335,165 @@ void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_framebuff
|
|||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_roughness, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) {
|
||||
|
||||
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
||||
|
||||
int32_t x_groups = (p_screen_size.width - 1) / 8 + 1;
|
||||
int32_t y_groups = (p_screen_size.height - 1) / 8 + 1;
|
||||
|
||||
{ //scale color and depth to half
|
||||
ssr_scale.push_constant.camera_z_far = p_camera.get_z_far();
|
||||
ssr_scale.push_constant.camera_z_near = p_camera.get_z_near();
|
||||
ssr_scale.push_constant.orthogonal = p_camera.is_orthogonal();
|
||||
ssr_scale.push_constant.filter = false; //enabling causes arctifacts
|
||||
ssr_scale.push_constant.screen_size[0] = p_screen_size.x;
|
||||
ssr_scale.push_constant.screen_size[1] = p_screen_size.y;
|
||||
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_scale.pipeline);
|
||||
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_diffuse), 0);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_pair(p_depth, p_normal), 1);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output_blur), 2);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_scale_depth, p_scale_normal), 3);
|
||||
|
||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_scale.push_constant, sizeof(ScreenSpaceReflectionScalePushConstant));
|
||||
|
||||
RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
|
||||
|
||||
RD::get_singleton()->compute_list_add_barrier(compute_list);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
ssr.push_constant.camera_z_far = p_camera.get_z_far();
|
||||
ssr.push_constant.camera_z_near = p_camera.get_z_near();
|
||||
ssr.push_constant.orthogonal = p_camera.is_orthogonal();
|
||||
ssr.push_constant.screen_size[0] = p_screen_size.x;
|
||||
ssr.push_constant.screen_size[1] = p_screen_size.y;
|
||||
ssr.push_constant.curve_fade_in = p_fade_in;
|
||||
ssr.push_constant.distance_fade = p_fade_out;
|
||||
ssr.push_constant.num_steps = p_max_steps;
|
||||
ssr.push_constant.depth_tolerance = p_tolerance;
|
||||
ssr.push_constant.use_half_res = true;
|
||||
ssr.push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_camera.matrix[0][0]);
|
||||
ssr.push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_camera.matrix[1][1]);
|
||||
ssr.push_constant.proj_info[2] = (1.0f - p_camera.matrix[0][2]) / p_camera.matrix[0][0];
|
||||
ssr.push_constant.proj_info[3] = (1.0f + p_camera.matrix[1][2]) / p_camera.matrix[1][1];
|
||||
ssr.push_constant.metallic_mask[0] = CLAMP(p_metallic_mask.r * 255.0, 0, 255);
|
||||
ssr.push_constant.metallic_mask[1] = CLAMP(p_metallic_mask.g * 255.0, 0, 255);
|
||||
ssr.push_constant.metallic_mask[2] = CLAMP(p_metallic_mask.b * 255.0, 0, 255);
|
||||
ssr.push_constant.metallic_mask[3] = CLAMP(p_metallic_mask.a * 255.0, 0, 255);
|
||||
store_camera(p_camera, ssr.push_constant.projection);
|
||||
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr.pipelines[(p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) ? SCREEN_SPACE_REFLECTION_ROUGH : SCREEN_SPACE_REFLECTION_NORMAL]);
|
||||
|
||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr.push_constant, sizeof(ScreenSpaceReflectionPushConstant));
|
||||
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output_blur, p_scale_depth), 0);
|
||||
|
||||
if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) {
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output, p_blur_radius), 1);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_pair(p_metallic, p_roughness), 3);
|
||||
} else {
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output), 1);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_metallic), 3);
|
||||
}
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 2);
|
||||
|
||||
RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
|
||||
}
|
||||
|
||||
if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) {
|
||||
|
||||
//blurr
|
||||
|
||||
RD::get_singleton()->compute_list_add_barrier(compute_list);
|
||||
|
||||
ssr_filter.push_constant.orthogonal = p_camera.is_orthogonal();
|
||||
ssr_filter.push_constant.edge_tolerance = Math::sin(Math::deg2rad(15.0));
|
||||
ssr_filter.push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_camera.matrix[0][0]);
|
||||
ssr_filter.push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_camera.matrix[1][1]);
|
||||
ssr_filter.push_constant.proj_info[2] = (1.0f - p_camera.matrix[0][2]) / p_camera.matrix[0][0];
|
||||
ssr_filter.push_constant.proj_info[3] = (1.0f + p_camera.matrix[1][2]) / p_camera.matrix[1][1];
|
||||
ssr_filter.push_constant.vertical = 0;
|
||||
if (p_roughness_quality == RS::ENV_SSR_ROUGNESS_QUALITY_LOW) {
|
||||
ssr_filter.push_constant.steps = p_max_steps / 3;
|
||||
ssr_filter.push_constant.increment = 3;
|
||||
} else if (p_roughness_quality == RS::ENV_SSR_ROUGNESS_QUALITY_MEDIUM) {
|
||||
ssr_filter.push_constant.steps = p_max_steps / 2;
|
||||
ssr_filter.push_constant.increment = 2;
|
||||
} else {
|
||||
ssr_filter.push_constant.steps = p_max_steps;
|
||||
ssr_filter.push_constant.increment = 1;
|
||||
}
|
||||
|
||||
ssr_filter.push_constant.screen_size[0] = p_screen_size.width;
|
||||
ssr_filter.push_constant.screen_size[1] = p_screen_size.height;
|
||||
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_filter.pipelines[SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL]);
|
||||
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output, p_blur_radius), 0);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 1);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output_blur, p_blur_radius2), 2);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_depth), 3);
|
||||
|
||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_filter.push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant));
|
||||
|
||||
RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
|
||||
|
||||
RD::get_singleton()->compute_list_add_barrier(compute_list);
|
||||
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_filter.pipelines[SCREEN_SPACE_REFLECTION_FILTER_VERTICAL]);
|
||||
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output_blur, p_blur_radius2), 0);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 1);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output), 2);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_depth), 3);
|
||||
|
||||
ssr_filter.push_constant.vertical = 1;
|
||||
|
||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_filter.push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant));
|
||||
|
||||
RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
|
||||
}
|
||||
|
||||
RD::get_singleton()->compute_list_end();
|
||||
}
|
||||
|
||||
void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection) {
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>());
|
||||
|
||||
if (p_reflection.is_valid()) {
|
||||
|
||||
if (p_base.is_valid()) {
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_SSR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base), 2);
|
||||
} else {
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADDITIVE_SSR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
|
||||
}
|
||||
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_specular), 0);
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_reflection), 1);
|
||||
|
||||
} else {
|
||||
|
||||
if (p_base.is_valid()) {
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADD].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base), 2);
|
||||
} else {
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADDITIVE_ADD].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
|
||||
}
|
||||
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_specular), 0);
|
||||
}
|
||||
|
||||
RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
|
||||
RD::get_singleton()->draw_list_draw(draw_list, true);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_framebuffer, const Vector2 &p_pixel_size) {
|
||||
|
||||
zeromem(&blur.push_constant, sizeof(BlurPushConstant));
|
||||
|
@ -970,6 +1214,7 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
|
|||
|
||||
for (int i = SSAO_BLUR_PASS; i <= SSAO_BLUR_UPSCALE; i++) {
|
||||
ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.blur_shader.version_get_shader(ssao.blur_shader_version, i - SSAO_BLUR_PASS));
|
||||
|
||||
pipeline++;
|
||||
}
|
||||
}
|
||||
|
@ -1035,6 +1280,82 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
|
|||
filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1);
|
||||
}
|
||||
|
||||
{
|
||||
Vector<String> specular_modes;
|
||||
specular_modes.push_back("\n#define MODE_MERGE\n");
|
||||
specular_modes.push_back("\n#define MODE_MERGE\n#define MODE_SSR\n");
|
||||
specular_modes.push_back("\n");
|
||||
specular_modes.push_back("\n#define MODE_SSR\n");
|
||||
|
||||
specular_merge.shader.initialize(specular_modes);
|
||||
|
||||
specular_merge.shader_version = specular_merge.shader.version_create();
|
||||
|
||||
//use additive
|
||||
|
||||
RD::PipelineColorBlendState::Attachment ba;
|
||||
ba.enable_blend = true;
|
||||
ba.src_color_blend_factor = RD::BLEND_FACTOR_ONE;
|
||||
ba.dst_color_blend_factor = RD::BLEND_FACTOR_ONE;
|
||||
ba.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
|
||||
ba.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
|
||||
ba.color_blend_op = RD::BLEND_OP_ADD;
|
||||
ba.alpha_blend_op = RD::BLEND_OP_ADD;
|
||||
|
||||
RD::PipelineColorBlendState blend_additive;
|
||||
blend_additive.attachments.push_back(ba);
|
||||
|
||||
for (int i = 0; i < SPECULAR_MERGE_MAX; i++) {
|
||||
|
||||
RD::PipelineColorBlendState blend_state;
|
||||
if (i == SPECULAR_MERGE_ADDITIVE_ADD || i == SPECULAR_MERGE_ADDITIVE_SSR) {
|
||||
blend_state = blend_additive;
|
||||
} else {
|
||||
blend_state = RD::PipelineColorBlendState::create_disabled();
|
||||
}
|
||||
specular_merge.pipelines[i].setup(specular_merge.shader.version_get_shader(specular_merge.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Vector<String> ssr_modes;
|
||||
ssr_modes.push_back("\n");
|
||||
ssr_modes.push_back("\n#define MODE_ROUGH\n");
|
||||
|
||||
ssr.shader.initialize(ssr_modes);
|
||||
|
||||
ssr.shader_version = ssr.shader.version_create();
|
||||
|
||||
for (int i = 0; i < SCREEN_SPACE_REFLECTION_MAX; i++) {
|
||||
ssr.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssr.shader.version_get_shader(ssr.shader_version, i));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Vector<String> ssr_filter_modes;
|
||||
ssr_filter_modes.push_back("\n");
|
||||
ssr_filter_modes.push_back("\n#define VERTICAL_PASS\n");
|
||||
|
||||
ssr_filter.shader.initialize(ssr_filter_modes);
|
||||
|
||||
ssr_filter.shader_version = ssr_filter.shader.version_create();
|
||||
|
||||
for (int i = 0; i < SCREEN_SPACE_REFLECTION_FILTER_MAX; i++) {
|
||||
ssr_filter.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssr_filter.shader.version_get_shader(ssr_filter.shader_version, i));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Vector<String> ssr_scale_modes;
|
||||
ssr_scale_modes.push_back("\n");
|
||||
|
||||
ssr_scale.shader.initialize(ssr_scale_modes);
|
||||
|
||||
ssr_scale.shader_version = ssr_scale.shader.version_create();
|
||||
|
||||
ssr_scale.pipeline = RD::get_singleton()->compute_pipeline_create(ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0));
|
||||
}
|
||||
|
||||
RD::SamplerState sampler;
|
||||
sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR;
|
||||
sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
|
||||
|
|
|
@ -41,6 +41,10 @@
|
|||
#include "servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl.gen.h"
|
||||
#include "servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl.gen.h"
|
||||
#include "servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl.gen.h"
|
||||
#include "servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl.gen.h"
|
||||
#include "servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl.gen.h"
|
||||
#include "servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl.gen.h"
|
||||
#include "servers/rendering/rasterizer_rd/shaders/specular_merge.glsl.gen.h"
|
||||
#include "servers/rendering/rasterizer_rd/shaders/ssao.glsl.gen.h"
|
||||
#include "servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl.gen.h"
|
||||
#include "servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl.gen.h"
|
||||
|
@ -378,6 +382,104 @@ class RasterizerEffectsRD {
|
|||
float pad[3];
|
||||
};
|
||||
|
||||
enum SpecularMergeMode {
|
||||
SPECULAR_MERGE_ADD,
|
||||
SPECULAR_MERGE_SSR,
|
||||
SPECULAR_MERGE_ADDITIVE_ADD,
|
||||
SPECULAR_MERGE_ADDITIVE_SSR,
|
||||
SPECULAR_MERGE_MAX
|
||||
};
|
||||
|
||||
struct SpecularMerge {
|
||||
|
||||
SpecularMergeShaderRD shader;
|
||||
RID shader_version;
|
||||
RenderPipelineVertexFormatCacheRD pipelines[SPECULAR_MERGE_MAX];
|
||||
|
||||
} specular_merge;
|
||||
|
||||
enum ScreenSpaceReflectionMode {
|
||||
SCREEN_SPACE_REFLECTION_NORMAL,
|
||||
SCREEN_SPACE_REFLECTION_ROUGH,
|
||||
SCREEN_SPACE_REFLECTION_MAX,
|
||||
};
|
||||
|
||||
struct ScreenSpaceReflectionPushConstant {
|
||||
|
||||
float proj_info[4];
|
||||
|
||||
int32_t screen_size[2];
|
||||
float camera_z_near;
|
||||
float camera_z_far;
|
||||
|
||||
int32_t num_steps;
|
||||
float depth_tolerance;
|
||||
float distance_fade;
|
||||
float curve_fade_in;
|
||||
|
||||
uint32_t orthogonal;
|
||||
float filter_mipmap_levels;
|
||||
uint32_t use_half_res;
|
||||
uint8_t metallic_mask[4];
|
||||
|
||||
float projection[16];
|
||||
};
|
||||
|
||||
struct ScreenSpaceReflection {
|
||||
|
||||
ScreenSpaceReflectionPushConstant push_constant;
|
||||
ScreenSpaceReflectionShaderRD shader;
|
||||
RID shader_version;
|
||||
RID pipelines[SCREEN_SPACE_REFLECTION_MAX];
|
||||
|
||||
} ssr;
|
||||
|
||||
struct ScreenSpaceReflectionFilterPushConstant {
|
||||
|
||||
float proj_info[4];
|
||||
|
||||
uint32_t orthogonal;
|
||||
float edge_tolerance;
|
||||
int32_t increment;
|
||||
uint32_t pad;
|
||||
|
||||
int32_t screen_size[2];
|
||||
uint32_t vertical;
|
||||
uint32_t steps;
|
||||
};
|
||||
enum {
|
||||
SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL,
|
||||
SCREEN_SPACE_REFLECTION_FILTER_VERTICAL,
|
||||
SCREEN_SPACE_REFLECTION_FILTER_MAX,
|
||||
};
|
||||
|
||||
struct ScreenSpaceReflectionFilter {
|
||||
|
||||
ScreenSpaceReflectionFilterPushConstant push_constant;
|
||||
ScreenSpaceReflectionFilterShaderRD shader;
|
||||
RID shader_version;
|
||||
RID pipelines[SCREEN_SPACE_REFLECTION_FILTER_MAX];
|
||||
} ssr_filter;
|
||||
|
||||
struct ScreenSpaceReflectionScalePushConstant {
|
||||
|
||||
int32_t screen_size[2];
|
||||
float camera_z_near;
|
||||
float camera_z_far;
|
||||
|
||||
uint32_t orthogonal;
|
||||
uint32_t filter;
|
||||
uint32_t pad[2];
|
||||
};
|
||||
|
||||
struct ScreenSpaceReflectionScale {
|
||||
|
||||
ScreenSpaceReflectionScalePushConstant push_constant;
|
||||
ScreenSpaceReflectionScaleShaderRD shader;
|
||||
RID shader_version;
|
||||
RID pipeline;
|
||||
} ssr_scale;
|
||||
|
||||
RID default_sampler;
|
||||
RID default_mipmap_sampler;
|
||||
RID index_buffer;
|
||||
|
@ -386,11 +488,28 @@ class RasterizerEffectsRD {
|
|||
Map<RID, RID> texture_to_uniform_set_cache;
|
||||
|
||||
Map<RID, RID> image_to_uniform_set_cache;
|
||||
|
||||
struct TexturePair {
|
||||
RID texture1;
|
||||
RID texture2;
|
||||
_FORCE_INLINE_ bool operator<(const TexturePair &p_pair) const {
|
||||
if (texture1 == p_pair.texture1) {
|
||||
return texture2 < p_pair.texture2;
|
||||
} else {
|
||||
return texture1 < p_pair.texture1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Map<RID, RID> texture_to_compute_uniform_set_cache;
|
||||
Map<TexturePair, RID> texture_pair_to_compute_uniform_set_cache;
|
||||
Map<TexturePair, RID> image_pair_to_compute_uniform_set_cache;
|
||||
|
||||
RID _get_uniform_set_from_image(RID p_texture);
|
||||
RID _get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps = false);
|
||||
RID _get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps = false);
|
||||
RID _get_compute_uniform_set_from_texture_pair(RID p_texture, RID p_texture2, bool p_use_mipmaps = false);
|
||||
RID _get_compute_uniform_set_from_image_pair(RID p_texture, RID p_texture2);
|
||||
|
||||
public:
|
||||
//TODO must re-do most of the shaders in compute
|
||||
|
@ -450,6 +569,9 @@ public:
|
|||
void cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array);
|
||||
void render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_lights, RenderPipelineVertexFormatCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position);
|
||||
|
||||
void screen_space_reflection(RID p_diffuse, RID p_normal, RS::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_roughness, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera);
|
||||
void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection);
|
||||
|
||||
RasterizerEffectsRD();
|
||||
~RasterizerEffectsRD();
|
||||
};
|
||||
|
|
|
@ -321,7 +321,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
|
|||
} else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL) {
|
||||
blend_state = blend_state_depth_normal;
|
||||
} else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) {
|
||||
blend_state = blend_state_depth_normal;
|
||||
blend_state = blend_state_depth_normal_roughness;
|
||||
} else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) {
|
||||
blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
|
||||
|
||||
|
@ -537,6 +537,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() {
|
|||
|
||||
specular = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
|
||||
{
|
||||
Vector<RID> fb;
|
||||
fb.push_back(color);
|
||||
fb.push_back(specular);
|
||||
|
@ -544,6 +545,13 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() {
|
|||
|
||||
color_specular_fb = RD::get_singleton()->framebuffer_create(fb);
|
||||
}
|
||||
{
|
||||
Vector<RID> fb;
|
||||
fb.push_back(specular);
|
||||
|
||||
specular_only_fb = RD::get_singleton()->framebuffer_create(fb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::clear() {
|
||||
|
@ -554,6 +562,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::clear() {
|
|||
}
|
||||
|
||||
color_specular_fb = RID();
|
||||
specular_only_fb = RID();
|
||||
color_fb = RID();
|
||||
|
||||
if (normal_buffer.is_valid()) {
|
||||
|
@ -1699,11 +1708,14 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
|
|||
Size2 screen_pixel_size;
|
||||
Size2i screen_size;
|
||||
RID opaque_framebuffer;
|
||||
RID opaque_specular_framebuffer;
|
||||
RID depth_framebuffer;
|
||||
RID alpha_framebuffer;
|
||||
|
||||
PassMode depth_pass_mode = PASS_MODE_DEPTH;
|
||||
Vector<Color> depth_pass_clear;
|
||||
bool using_separate_specular = false;
|
||||
bool using_ssr = false;
|
||||
|
||||
if (render_buffer) {
|
||||
screen_pixel_size.width = 1.0 / render_buffer->width;
|
||||
|
@ -1715,6 +1727,10 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
|
|||
|
||||
if (p_environment.is_valid() && environment_is_ssr_enabled(p_environment)) {
|
||||
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
|
||||
render_buffer->ensure_specular();
|
||||
using_separate_specular = true;
|
||||
using_ssr = true;
|
||||
opaque_specular_framebuffer = render_buffer->color_specular_fb;
|
||||
} else if (screen_space_roughness_limiter_is_active()) {
|
||||
depth_pass_mode = PASS_MODE_DEPTH_NORMAL;
|
||||
//we need to allocate both these, if not allocated
|
||||
|
@ -1845,22 +1861,22 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
|
|||
|
||||
_fill_instances(render_list.elements, render_list.element_count, false);
|
||||
|
||||
bool can_continue = true; //unless the middle buffers are needed
|
||||
bool debug_giprobes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION;
|
||||
bool using_separate_specular = false;
|
||||
|
||||
bool depth_pre_pass = depth_framebuffer.is_valid();
|
||||
RID render_buffers_uniform_set;
|
||||
|
||||
bool using_ssao = depth_pre_pass && p_render_buffer.is_valid() && p_environment.is_valid() && environment_is_ssao_enabled(p_environment);
|
||||
|
||||
if (depth_pre_pass) { //depth pre pass
|
||||
RENDER_TIMESTAMP("Render Depth Pre-Pass");
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, depth_pass_clear);
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, using_ssao ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, depth_pass_clear);
|
||||
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(depth_framebuffer), render_list.elements, render_list.element_count, false, depth_pass_mode, render_buffer == nullptr, radiance_uniform_set, RID());
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
if (p_render_buffer.is_valid() && p_environment.is_valid() && environment_is_ssao_enabled(p_environment)) {
|
||||
if (using_ssao) {
|
||||
_process_ssao(p_render_buffer, p_environment, render_buffer->normal_buffer, p_cam_projection);
|
||||
}
|
||||
|
||||
|
@ -1878,23 +1894,41 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
|
|||
|
||||
RENDER_TIMESTAMP("Render Opaque Pass");
|
||||
|
||||
bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !scene_state.used_sss;
|
||||
bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr;
|
||||
|
||||
{
|
||||
bool will_continue = (can_continue || draw_sky || debug_giprobes);
|
||||
|
||||
bool will_continue_color = (can_continue_color || draw_sky || debug_giprobes);
|
||||
bool will_continue_depth = (can_continue_depth || draw_sky || debug_giprobes);
|
||||
|
||||
//regular forward for now
|
||||
Vector<Color> c;
|
||||
c.push_back(clear_color.to_linear());
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, will_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0);
|
||||
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(opaque_framebuffer), render_list.elements, render_list.element_count, false, PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set);
|
||||
if (using_separate_specular) {
|
||||
c.push_back(Color(0, 0, 0, 0));
|
||||
}
|
||||
RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer;
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (using_ssao ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CONTINUE) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0);
|
||||
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(framebuffer), render_list.elements, render_list.element_count, false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
|
||||
if (will_continue_color && using_separate_specular) {
|
||||
// close the specular framebuffer, as it's no longer used
|
||||
draw_list = RD::get_singleton()->draw_list_begin(render_buffer->specular_only_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_CONTINUE);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
}
|
||||
|
||||
if (debug_giprobes) {
|
||||
//debug giprobes
|
||||
bool will_continue = (can_continue || draw_sky);
|
||||
bool will_continue_color = (can_continue_color || draw_sky);
|
||||
bool will_continue_depth = (can_continue_depth || draw_sky);
|
||||
|
||||
CameraMatrix dc;
|
||||
dc.set_depth_correction(true);
|
||||
CameraMatrix cm = (dc * p_cam_projection) * CameraMatrix(p_cam_transform.affine_inverse());
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
|
||||
for (int i = 0; i < p_gi_probe_cull_count; i++) {
|
||||
_debug_giprobe(p_gi_probe_cull_result[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, 1.0);
|
||||
}
|
||||
|
@ -1911,12 +1945,24 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
|
|||
projection = correction * p_cam_projection;
|
||||
}
|
||||
|
||||
_draw_sky(can_continue, opaque_framebuffer, p_environment, projection, p_cam_transform);
|
||||
_draw_sky(can_continue_color, can_continue_depth, opaque_framebuffer, p_environment, projection, p_cam_transform);
|
||||
}
|
||||
|
||||
if (using_separate_specular && !can_continue) {
|
||||
//can't continue, so close the buffers
|
||||
//RD::get_singleton()->draw_list_begin(render_buffer->color_specular_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ_COLOR_AND_DEPTH, c);
|
||||
//RD::get_singleton()->draw_list_end();
|
||||
if (using_separate_specular) {
|
||||
|
||||
if (scene_state.used_sss) {
|
||||
RENDER_TIMESTAMP("Sub Surface Scattering");
|
||||
|
||||
//_process_sss()
|
||||
}
|
||||
|
||||
if (using_ssr) {
|
||||
RENDER_TIMESTAMP("Screen Space Reflection");
|
||||
_process_ssr(p_render_buffer, render_buffer->color_fb, render_buffer->normal_buffer, render_buffer->roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_environment, p_cam_projection, true);
|
||||
} else {
|
||||
//just mix specular back
|
||||
RENDER_TIMESTAMP("Merge Specular");
|
||||
storage->get_effects()->merge_specular(render_buffer->color_fb, render_buffer->specular, RID(), RID());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1929,7 +1975,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
|
|||
_fill_instances(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false);
|
||||
|
||||
{
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(alpha_framebuffer, can_continue ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
|
||||
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(alpha_framebuffer), &render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
|
|
@ -207,6 +207,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
|
|||
RID depth_normal_roughness_fb;
|
||||
RID color_fb;
|
||||
RID color_specular_fb;
|
||||
RID specular_only_fb;
|
||||
int width, height;
|
||||
|
||||
void ensure_specular();
|
||||
|
|
|
@ -456,7 +456,7 @@ RID RasterizerSceneRD::sky_get_material(RID p_sky) const {
|
|||
return sky->material;
|
||||
}
|
||||
|
||||
void RasterizerSceneRD::_draw_sky(bool p_can_continue, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) {
|
||||
void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) {
|
||||
|
||||
ERR_FAIL_COND(!is_environment(p_environment));
|
||||
|
||||
|
@ -537,7 +537,7 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue, RID p_fb, RID p_environme
|
|||
|
||||
RID texture_uniform_set = _get_sky_textures(sky, SKY_TEXTURE_SET_BACKGROUND);
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CONTINUE, p_can_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_can_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CONTINUE, p_can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
|
||||
storage->get_effects()->render_sky(draw_list, time, p_fb, sky_scene_state.sampler_uniform_set, sky_scene_state.light_uniform_set, pipeline, material->uniform_set, texture_uniform_set, camera, sky_transform, multiplier, p_transform.origin);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
@ -1231,6 +1231,26 @@ void RasterizerSceneRD::environment_glow_set_use_bicubic_upscale(bool p_enable)
|
|||
glow_bicubic_upscale = p_enable;
|
||||
}
|
||||
|
||||
void RasterizerSceneRD::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) {
|
||||
|
||||
Environent *env = environment_owner.getornull(p_env);
|
||||
ERR_FAIL_COND(!env);
|
||||
|
||||
env->ssr_enabled = p_enable;
|
||||
env->ssr_max_steps = p_max_steps;
|
||||
env->ssr_fade_in = p_fade_int;
|
||||
env->ssr_fade_out = p_fade_out;
|
||||
env->ssr_depth_tolerance = p_depth_tolerance;
|
||||
}
|
||||
|
||||
void RasterizerSceneRD::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) {
|
||||
ssr_roughness_quality = p_quality;
|
||||
}
|
||||
|
||||
RS::EnvironmentSSRRoughnessQuality RasterizerSceneRD::environment_get_ssr_roughness_quality() const {
|
||||
return ssr_roughness_quality;
|
||||
}
|
||||
|
||||
void RasterizerSceneRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) {
|
||||
|
||||
Environent *env = environment_owner.getornull(p_env);
|
||||
|
@ -1272,7 +1292,7 @@ bool RasterizerSceneRD::environment_is_ssr_enabled(RID p_env) const {
|
|||
|
||||
Environent *env = environment_owner.getornull(p_env);
|
||||
ERR_FAIL_COND_V(!env, false);
|
||||
return false;
|
||||
return env->ssr_enabled;
|
||||
}
|
||||
|
||||
bool RasterizerSceneRD::is_environment(RID p_env) const {
|
||||
|
@ -3167,6 +3187,74 @@ void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) {
|
|||
rb->ssao.ao_full = RID();
|
||||
rb->ssao.depth_slices.clear();
|
||||
}
|
||||
|
||||
if (rb->ssr.blur_radius[0].is_valid()) {
|
||||
RD::get_singleton()->free(rb->ssr.blur_radius[0]);
|
||||
RD::get_singleton()->free(rb->ssr.blur_radius[1]);
|
||||
rb->ssr.blur_radius[0] = RID();
|
||||
rb->ssr.blur_radius[1] = RID();
|
||||
}
|
||||
|
||||
if (rb->ssr.depth_scaled.is_valid()) {
|
||||
RD::get_singleton()->free(rb->ssr.depth_scaled);
|
||||
rb->ssr.depth_scaled = RID();
|
||||
RD::get_singleton()->free(rb->ssr.normal_scaled);
|
||||
rb->ssr.normal_scaled = RID();
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_roughness_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) {
|
||||
|
||||
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
||||
ERR_FAIL_COND(!rb);
|
||||
|
||||
bool can_use_effects = rb->width >= 8 && rb->height >= 8;
|
||||
|
||||
if (!can_use_effects) {
|
||||
//just copy
|
||||
storage->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->texture, RID());
|
||||
return;
|
||||
}
|
||||
|
||||
Environent *env = environment_owner.getornull(p_environment);
|
||||
ERR_FAIL_COND(!env);
|
||||
|
||||
ERR_FAIL_COND(!env->ssr_enabled);
|
||||
|
||||
if (rb->ssr.depth_scaled.is_null()) {
|
||||
RD::TextureFormat tf;
|
||||
tf.format = RD::DATA_FORMAT_R32_SFLOAT;
|
||||
tf.width = rb->width / 2;
|
||||
tf.height = rb->height / 2;
|
||||
tf.type = RD::TEXTURE_TYPE_2D;
|
||||
tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
|
||||
|
||||
rb->ssr.depth_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
|
||||
tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
rb->ssr.normal_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
}
|
||||
|
||||
if (ssr_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED && !rb->ssr.blur_radius[0].is_valid()) {
|
||||
RD::TextureFormat tf;
|
||||
tf.format = RD::DATA_FORMAT_R8_UNORM;
|
||||
tf.width = rb->width / 2;
|
||||
tf.height = rb->height / 2;
|
||||
tf.type = RD::TEXTURE_TYPE_2D;
|
||||
tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
|
||||
|
||||
rb->ssr.blur_radius[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
rb->ssr.blur_radius[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
}
|
||||
|
||||
if (rb->blur[0].texture.is_null()) {
|
||||
_allocate_blur_textures(rb);
|
||||
_render_buffers_uniform_set_changed(p_render_buffers);
|
||||
}
|
||||
|
||||
storage->get_effects()->screen_space_reflection(rb->texture, p_normal_buffer, ssr_roughness_quality, p_roughness_buffer, rb->ssr.blur_radius[0], rb->ssr.blur_radius[1], p_metallic, p_metallic_mask, rb->depth_texture, rb->ssr.depth_scaled, rb->ssr.normal_scaled, rb->blur[0].mipmaps[1].texture, rb->blur[1].mipmaps[0].texture, Size2i(rb->width / 2, rb->height / 2), env->ssr_max_steps, env->ssr_fade_in, env->ssr_fade_out, env->ssr_depth_tolerance, p_projection);
|
||||
storage->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->texture, rb->blur[0].mipmaps[1].texture);
|
||||
}
|
||||
|
||||
void RasterizerSceneRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) {
|
||||
|
@ -4012,6 +4100,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
|
|||
screen_space_roughness_limiter = GLOBAL_GET("rendering/quality/filters/screen_space_roughness_limiter");
|
||||
screen_space_roughness_limiter_curve = GLOBAL_GET("rendering/quality/filters/screen_space_roughness_limiter_curve");
|
||||
glow_bicubic_upscale = int(GLOBAL_GET("rendering/quality/glow/upscale_mode")) > 0;
|
||||
ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/quality/screen_space_reflection/roughness_quality")));
|
||||
}
|
||||
|
||||
RasterizerSceneRD::~RasterizerSceneRD() {
|
||||
|
|
|
@ -92,10 +92,11 @@ protected:
|
|||
virtual RID _render_buffers_get_normal_texture(RID p_render_buffers) = 0;
|
||||
|
||||
void _process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection);
|
||||
void _process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_roughness_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive);
|
||||
|
||||
void _setup_sky(RID p_environment, const Vector3 &p_position, const Size2i p_screen_size);
|
||||
void _update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
|
||||
void _draw_sky(bool p_can_continue, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
|
||||
void _draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
|
||||
|
||||
private:
|
||||
RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED;
|
||||
|
@ -657,11 +658,20 @@ private:
|
|||
float ssao_ao_channel_affect = 0.0;
|
||||
float ssao_blur_edge_sharpness = 4.0;
|
||||
RS::EnvironmentSSAOBlur ssao_blur = RS::ENV_SSAO_BLUR_3x3;
|
||||
|
||||
/// SSR
|
||||
///
|
||||
bool ssr_enabled = false;
|
||||
int ssr_max_steps = 64;
|
||||
float ssr_fade_in = 0.15;
|
||||
float ssr_fade_out = 2.0;
|
||||
float ssr_depth_tolerance = 0.2;
|
||||
};
|
||||
|
||||
RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM;
|
||||
bool ssao_half_size = false;
|
||||
bool glow_bicubic_upscale = false;
|
||||
RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGNESS_QUALITY_LOW;
|
||||
|
||||
static uint64_t auto_exposure_counter;
|
||||
|
||||
|
@ -733,6 +743,12 @@ private:
|
|||
RID ao[2];
|
||||
RID ao_full; //when using half-size
|
||||
} ssao;
|
||||
|
||||
struct SSR {
|
||||
RID normal_scaled;
|
||||
RID depth_scaled;
|
||||
RID blur_radius[2];
|
||||
} ssr;
|
||||
};
|
||||
|
||||
bool screen_space_roughness_limiter = false;
|
||||
|
@ -832,7 +848,7 @@ public:
|
|||
|
||||
void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) {}
|
||||
|
||||
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) {}
|
||||
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);
|
||||
void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness);
|
||||
void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size);
|
||||
bool environment_is_ssao_enabled(RID p_env) const;
|
||||
|
@ -840,6 +856,9 @@ public:
|
|||
float environment_get_ssao_light_affect(RID p_env) const;
|
||||
bool environment_is_ssr_enabled(RID p_env) const;
|
||||
|
||||
void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality);
|
||||
RS::EnvironmentSSRRoughnessQuality environment_get_ssr_roughness_quality() const;
|
||||
|
||||
void environment_set_tonemap(RID p_env, RS::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);
|
||||
void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) {}
|
||||
|
||||
|
|
|
@ -22,3 +22,7 @@ if "RD_GLSL" in env["BUILDERS"]:
|
|||
env.RD_GLSL("ssao_minify.glsl")
|
||||
env.RD_GLSL("ssao_blur.glsl")
|
||||
env.RD_GLSL("roughness_limiter.glsl")
|
||||
env.RD_GLSL("screen_space_reflection.glsl")
|
||||
env.RD_GLSL("screen_space_reflection_filter.glsl")
|
||||
env.RD_GLSL("screen_space_reflection_scale.glsl")
|
||||
env.RD_GLSL("specular_merge.glsl")
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
/* clang-format off */
|
||||
[compute]
|
||||
|
||||
#version 450
|
||||
|
||||
VERSION_DEFINES
|
||||
|
||||
|
||||
|
||||
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
layout(rgba16f, set = 0, binding = 0) uniform restrict readonly image2D source_diffuse;
|
||||
layout(r32f, set = 0, binding = 1) uniform restrict readonly image2D source_depth;
|
||||
layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly image2D ssr_image;
|
||||
#ifdef MODE_ROUGH
|
||||
layout(r8, set = 1, binding = 1) uniform restrict writeonly image2D blur_radius_image;
|
||||
#endif
|
||||
layout(rgba8, set = 2, binding = 0) uniform restrict readonly image2D source_normal;
|
||||
layout(set = 3, binding = 0) uniform sampler2D source_metallic;
|
||||
#ifdef MODE_ROUGH
|
||||
layout(set = 3, binding = 1) uniform sampler2D source_roughness;
|
||||
#endif
|
||||
|
||||
layout(push_constant, binding = 2, std430) uniform Params {
|
||||
|
||||
vec4 proj_info;
|
||||
|
||||
ivec2 screen_size;
|
||||
float camera_z_near;
|
||||
float camera_z_far;
|
||||
|
||||
int num_steps;
|
||||
float depth_tolerance;
|
||||
float distance_fade;
|
||||
float curve_fade_in;
|
||||
|
||||
bool orthogonal;
|
||||
float filter_mipmap_levels;
|
||||
bool use_half_res;
|
||||
uint metallic_mask;
|
||||
|
||||
mat4 projection;
|
||||
}
|
||||
params;
|
||||
|
||||
vec2 view_to_screen(vec3 view_pos, out float w) {
|
||||
vec4 projected = params.projection * vec4(view_pos, 1.0);
|
||||
projected.xyz /= projected.w;
|
||||
projected.xy = projected.xy * 0.5 + 0.5;
|
||||
w = projected.w;
|
||||
return projected.xy;
|
||||
}
|
||||
|
||||
#define M_PI 3.14159265359
|
||||
|
||||
vec3 reconstructCSPosition(vec2 S, float z) {
|
||||
if (params.orthogonal) {
|
||||
return vec3((S.xy * params.proj_info.xy + params.proj_info.zw), z);
|
||||
} else {
|
||||
return vec3((S.xy * params.proj_info.xy + params.proj_info.zw) * z, z);
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
// Pixel being shaded
|
||||
ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 pixel_size = 1.0 / vec2(params.screen_size);
|
||||
vec2 uv = vec2(ssC) * pixel_size;
|
||||
|
||||
uv += pixel_size * 0.5;
|
||||
|
||||
float base_depth = imageLoad(source_depth, ssC).r;
|
||||
|
||||
// World space point being shaded
|
||||
vec3 vertex = reconstructCSPosition(uv * vec2(params.screen_size), base_depth);
|
||||
|
||||
vec3 normal = imageLoad(source_normal, ssC).xyz * 2.0 - 1.0;
|
||||
normal = normalize(normal);
|
||||
normal.y = -normal.y; //because this code reads flipped
|
||||
|
||||
vec3 view_dir = normalize(vertex);
|
||||
vec3 ray_dir = normalize(reflect(view_dir, normal));
|
||||
|
||||
if (dot(ray_dir, normal) < 0.001) {
|
||||
imageStore(ssr_image, ssC, vec4(0.0));
|
||||
return;
|
||||
}
|
||||
//ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0);
|
||||
//ray_dir = normalize(vec3(1.0, 1.0, -1.0));
|
||||
|
||||
////////////////
|
||||
|
||||
// make ray length and clip it against the near plane (don't want to trace beyond visible)
|
||||
float ray_len = (vertex.z + ray_dir.z * params.camera_z_far) > -params.camera_z_near ? (-params.camera_z_near - vertex.z) / ray_dir.z : params.camera_z_far;
|
||||
vec3 ray_end = vertex + ray_dir * ray_len;
|
||||
|
||||
float w_begin;
|
||||
vec2 vp_line_begin = view_to_screen(vertex, w_begin);
|
||||
float w_end;
|
||||
vec2 vp_line_end = view_to_screen(ray_end, w_end);
|
||||
vec2 vp_line_dir = vp_line_end - vp_line_begin;
|
||||
|
||||
// we need to interpolate w along the ray, to generate perspective correct reflections
|
||||
w_begin = 1.0 / w_begin;
|
||||
w_end = 1.0 / w_end;
|
||||
|
||||
float z_begin = vertex.z * w_begin;
|
||||
float z_end = ray_end.z * w_end;
|
||||
|
||||
vec2 line_begin = vp_line_begin / pixel_size;
|
||||
vec2 line_dir = vp_line_dir / pixel_size;
|
||||
float z_dir = z_end - z_begin;
|
||||
float w_dir = w_end - w_begin;
|
||||
|
||||
// clip the line to the viewport edges
|
||||
|
||||
float scale_max_x = min(1.0, 0.99 * (1.0 - vp_line_begin.x) / max(1e-5, vp_line_dir.x));
|
||||
float scale_max_y = min(1.0, 0.99 * (1.0 - vp_line_begin.y) / max(1e-5, vp_line_dir.y));
|
||||
float scale_min_x = min(1.0, 0.99 * vp_line_begin.x / max(1e-5, -vp_line_dir.x));
|
||||
float scale_min_y = min(1.0, 0.99 * vp_line_begin.y / max(1e-5, -vp_line_dir.y));
|
||||
float line_clip = min(scale_max_x, scale_max_y) * min(scale_min_x, scale_min_y);
|
||||
line_dir *= line_clip;
|
||||
z_dir *= line_clip;
|
||||
w_dir *= line_clip;
|
||||
|
||||
// clip z and w advance to line advance
|
||||
vec2 line_advance = normalize(line_dir); // down to pixel
|
||||
float step_size = length(line_advance) / length(line_dir);
|
||||
float z_advance = z_dir * step_size; // adapt z advance to line advance
|
||||
float w_advance = w_dir * step_size; // adapt w advance to line advance
|
||||
|
||||
// make line advance faster if direction is closer to pixel edges (this avoids sampling the same pixel twice)
|
||||
float advance_angle_adj = 1.0 / max(abs(line_advance.x), abs(line_advance.y));
|
||||
line_advance *= advance_angle_adj; // adapt z advance to line advance
|
||||
z_advance *= advance_angle_adj;
|
||||
w_advance *= advance_angle_adj;
|
||||
|
||||
vec2 pos = line_begin;
|
||||
float z = z_begin;
|
||||
float w = w_begin;
|
||||
float z_from = z / w;
|
||||
float z_to = z_from;
|
||||
float depth;
|
||||
vec2 prev_pos = pos;
|
||||
|
||||
bool found = false;
|
||||
|
||||
float steps_taken = 0.0;
|
||||
|
||||
for (int i = 0; i < params.num_steps; i++) {
|
||||
|
||||
pos += line_advance;
|
||||
z += z_advance;
|
||||
w += w_advance;
|
||||
|
||||
// convert to linear depth
|
||||
|
||||
depth = imageLoad(source_depth, ivec2(pos - 0.5)).r;
|
||||
|
||||
if (-depth >= params.camera_z_far) { //went beyond camera
|
||||
break;
|
||||
}
|
||||
|
||||
z_from = z_to;
|
||||
z_to = z / w;
|
||||
|
||||
if (depth > z_to) {
|
||||
// if depth was surpassed
|
||||
if (depth <= max(z_to, z_from) + params.depth_tolerance) {
|
||||
// check the depth tolerance
|
||||
//check that normal is valid
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
steps_taken += 1.0;
|
||||
prev_pos = pos;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
|
||||
float margin_blend = 1.0;
|
||||
|
||||
vec2 margin = vec2((params.screen_size.x + params.screen_size.y) * 0.5 * 0.05); // make a uniform margin
|
||||
if (any(bvec4(lessThan(pos, -margin), greaterThan(pos, params.screen_size + margin)))) {
|
||||
// clip outside screen + margin
|
||||
imageStore(ssr_image, ssC, vec4(0.0));
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
//blend fading out towards external margin
|
||||
vec2 margin_grad = mix(pos - params.screen_size, -pos, lessThan(pos, vec2(0.0)));
|
||||
margin_blend = 1.0 - smoothstep(0.0, margin.x, max(margin_grad.x, margin_grad.y));
|
||||
//margin_blend = 1.0;
|
||||
}
|
||||
|
||||
vec2 final_pos;
|
||||
float grad;
|
||||
grad = steps_taken / float(params.num_steps);
|
||||
float initial_fade = params.curve_fade_in == 0.0 ? 1.0 : pow(clamp(grad, 0.0, 1.0), params.curve_fade_in);
|
||||
float fade = pow(clamp(1.0 - grad, 0.0, 1.0), params.distance_fade) * initial_fade;
|
||||
final_pos = pos;
|
||||
|
||||
vec4 final_color;
|
||||
|
||||
#ifdef MODE_ROUGH
|
||||
|
||||
// if roughness is enabled, do screen space cone tracing
|
||||
float blur_radius = 0.0;
|
||||
float roughness = texelFetch(source_roughness, ssC << 1, 0).r;
|
||||
|
||||
if (roughness > 0.001) {
|
||||
|
||||
float cone_angle = min(roughness, 0.999) * M_PI * 0.5;
|
||||
float cone_len = length(final_pos - line_begin);
|
||||
float op_len = 2.0 * tan(cone_angle) * cone_len; // opposite side of iso triangle
|
||||
{
|
||||
// fit to sphere inside cone (sphere ends at end of cone), something like this:
|
||||
// ___
|
||||
// \O/
|
||||
// V
|
||||
//
|
||||
// as it avoids bleeding from beyond the reflection as much as possible. As a plus
|
||||
// it also makes the rough reflection more elongated.
|
||||
float a = op_len;
|
||||
float h = cone_len;
|
||||
float a2 = a * a;
|
||||
float fh2 = 4.0f * h * h;
|
||||
blur_radius = (a * (sqrt(a2 + fh2) - a)) / (4.0f * h);
|
||||
}
|
||||
}
|
||||
|
||||
final_color = imageLoad(source_diffuse, ivec2((final_pos - 0.5) * pixel_size));
|
||||
|
||||
imageStore(blur_radius_image, ssC, vec4(blur_radius / 255.0)); //stored in r8
|
||||
|
||||
#endif
|
||||
|
||||
final_color = vec4(imageLoad(source_diffuse, ivec2(final_pos - 0.5)).rgb, fade * margin_blend);
|
||||
//change blend by metallic
|
||||
vec4 metallic_mask = unpackUnorm4x8(params.metallic_mask);
|
||||
final_color.a *= dot(metallic_mask, texelFetch(source_metallic, ssC << 1, 0));
|
||||
|
||||
imageStore(ssr_image, ssC, final_color);
|
||||
|
||||
} else {
|
||||
#ifdef MODE_ROUGH
|
||||
imageStore(blur_radius_image, ssC, vec4(0.0));
|
||||
#endif
|
||||
imageStore(ssr_image, ssC, vec4(0.0));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
/* clang-format off */
|
||||
[compute]
|
||||
|
||||
#version 450
|
||||
|
||||
VERSION_DEFINES
|
||||
|
||||
|
||||
|
||||
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
layout(rgba16f, set = 0, binding = 0) uniform restrict readonly image2D source_ssr;
|
||||
layout(r8, set = 0, binding = 1) uniform restrict readonly image2D source_radius;
|
||||
layout(rgba8, set = 1, binding = 0) uniform restrict readonly image2D source_normal;
|
||||
|
||||
layout(rgba16f, set = 2, binding = 0) uniform restrict writeonly image2D dest_ssr;
|
||||
#ifndef VERTICAL_PASS
|
||||
layout(r8, set = 2, binding = 1) uniform restrict writeonly image2D dest_radius;
|
||||
#endif
|
||||
layout(r32f, set = 3, binding = 0) uniform restrict readonly image2D source_depth;
|
||||
|
||||
layout(push_constant, binding = 2, std430) uniform Params {
|
||||
|
||||
vec4 proj_info;
|
||||
|
||||
bool orthogonal;
|
||||
float edge_tolerance;
|
||||
int increment;
|
||||
uint pad;
|
||||
|
||||
ivec2 screen_size;
|
||||
bool vertical;
|
||||
uint steps;
|
||||
}
|
||||
params;
|
||||
|
||||
#define GAUSS_TABLE_SIZE 15
|
||||
|
||||
const float gauss_table[GAUSS_TABLE_SIZE + 1] = float[](
|
||||
0.1847392078702266,
|
||||
0.16595854345772326,
|
||||
0.12031364177766891,
|
||||
0.07038755277896766,
|
||||
0.03322925565155569,
|
||||
0.012657819729901945,
|
||||
0.0038903040680094217,
|
||||
0.0009646503390864025,
|
||||
0.00019297087402915717,
|
||||
0.000031139936308099136,
|
||||
0.000004053309048174758,
|
||||
4.255228059965837e-7,
|
||||
3.602517634249573e-8,
|
||||
2.4592560765896795e-9,
|
||||
1.3534945386863618e-10,
|
||||
0.0 //one more for interpolation
|
||||
);
|
||||
|
||||
float gauss_weight(float p_val) {
|
||||
|
||||
float idxf;
|
||||
float c = modf(max(0.0, p_val * float(GAUSS_TABLE_SIZE)), idxf);
|
||||
int idx = int(idxf);
|
||||
if (idx >= GAUSS_TABLE_SIZE + 1) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return mix(gauss_table[idx], gauss_table[idx + 1], c);
|
||||
}
|
||||
|
||||
#define GAUSS_WEIGHT(m_val) gauss_table[clamp(int(m_val * float(GAUSS_TABLE_SIZE - 1)), 0, GAUSS_TABLE_SIZE - 1)]
|
||||
|
||||
#define M_PI 3.14159265359
|
||||
|
||||
vec3 reconstructCSPosition(vec2 S, float z) {
|
||||
if (params.orthogonal) {
|
||||
return vec3((S.xy * params.proj_info.xy + params.proj_info.zw), z);
|
||||
} else {
|
||||
return vec3((S.xy * params.proj_info.xy + params.proj_info.zw) * z, z);
|
||||
}
|
||||
}
|
||||
|
||||
void do_filter(inout vec4 accum, inout float accum_radius, inout float divisor, ivec2 texcoord, ivec2 increment, vec3 p_pos, vec3 normal, float p_limit_radius) {
|
||||
|
||||
for (int i = 1; i < params.steps; i++) {
|
||||
float d = float(i * params.increment);
|
||||
ivec2 tc = texcoord + increment * i;
|
||||
float depth = imageLoad(source_depth, tc).r;
|
||||
vec3 view_pos = reconstructCSPosition(vec2(tc) + 0.5, depth);
|
||||
vec3 view_normal = normalize(imageLoad(source_normal, tc).rgb * 2.0 - 1.0);
|
||||
view_normal.y = -view_normal.y;
|
||||
|
||||
float r = imageLoad(source_radius, tc).r;
|
||||
float radius = round(r * 255.0);
|
||||
|
||||
float angle_n = 1.0 - abs(dot(normal, view_normal));
|
||||
if (angle_n > params.edge_tolerance) {
|
||||
break;
|
||||
}
|
||||
|
||||
float angle = abs(dot(normal, normalize(view_pos - p_pos)));
|
||||
|
||||
if (angle > params.edge_tolerance) {
|
||||
break;
|
||||
}
|
||||
|
||||
float contrib = 0.0;
|
||||
if (d < radius) {
|
||||
contrib += gauss_weight(d / radius);
|
||||
}
|
||||
|
||||
if (contrib > 0.0) {
|
||||
accum += imageLoad(source_ssr, tc) * contrib;
|
||||
#ifndef VERTICAL_PASS
|
||||
accum_radius += r * contrib;
|
||||
#endif
|
||||
divisor += contrib;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
// Pixel being shaded
|
||||
ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
float base_contrib = gauss_table[0];
|
||||
|
||||
vec4 accum = imageLoad(source_ssr, ssC);
|
||||
|
||||
float accum_radius = imageLoad(source_radius, ssC).r;
|
||||
float radius = accum_radius * 255.0;
|
||||
|
||||
float divisor = gauss_table[0];
|
||||
accum *= divisor;
|
||||
accum_radius *= divisor;
|
||||
#ifdef VERTICAL_PASS
|
||||
ivec2 direction = ivec2(0, params.increment);
|
||||
#else
|
||||
ivec2 direction = ivec2(params.increment, 0);
|
||||
#endif
|
||||
float depth = imageLoad(source_depth, ssC).r;
|
||||
vec3 pos = reconstructCSPosition(vec2(ssC) + 0.5, depth);
|
||||
vec3 normal = imageLoad(source_normal, ssC).xyz * 2.0 - 1.0;
|
||||
normal = normalize(normal);
|
||||
normal.y = -normal.y;
|
||||
|
||||
do_filter(accum, accum_radius, divisor, ssC, direction, pos, normal, radius);
|
||||
do_filter(accum, accum_radius, divisor, ssC, -direction, pos, normal, radius);
|
||||
|
||||
if (divisor > 0.0) {
|
||||
accum /= divisor;
|
||||
accum_radius /= divisor;
|
||||
} else {
|
||||
accum = vec4(0.0);
|
||||
accum_radius = 0.0;
|
||||
}
|
||||
|
||||
imageStore(dest_ssr, ssC, accum);
|
||||
|
||||
#ifndef VERTICAL_PASS
|
||||
imageStore(dest_radius, ssC, vec4(accum_radius));
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/* clang-format off */
|
||||
[compute]
|
||||
|
||||
#version 450
|
||||
|
||||
VERSION_DEFINES
|
||||
|
||||
|
||||
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D source_ssr;
|
||||
layout(set = 1, binding = 0) uniform sampler2D source_depth;
|
||||
layout(set = 1, binding = 1) uniform sampler2D source_normal;
|
||||
layout(rgba16f, set = 2, binding = 0) uniform restrict writeonly image2D dest_ssr;
|
||||
layout(r32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_depth;
|
||||
layout(rgba8, set = 3, binding = 1) uniform restrict writeonly image2D dest_normal;
|
||||
|
||||
layout(push_constant, binding = 1, std430) uniform Params {
|
||||
|
||||
ivec2 screen_size;
|
||||
float camera_z_near;
|
||||
float camera_z_far;
|
||||
|
||||
bool orthogonal;
|
||||
bool filtered;
|
||||
uint pad[2];
|
||||
}
|
||||
params;
|
||||
|
||||
void main() {
|
||||
|
||||
// Pixel being shaded
|
||||
ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing
|
||||
return;
|
||||
}
|
||||
//do not filter, SSR will generate arctifacts if this is done
|
||||
|
||||
float divisor = 0.0;
|
||||
vec4 color;
|
||||
float depth;
|
||||
vec3 normal;
|
||||
|
||||
if (params.filtered) {
|
||||
|
||||
color = vec4(0.0);
|
||||
depth = 0.0;
|
||||
normal = vec3(0.0);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
|
||||
ivec2 ofs = ssC << 1;
|
||||
if (bool(i & 1)) {
|
||||
ofs.x += 1;
|
||||
}
|
||||
if (bool(i & 2)) {
|
||||
ofs.y += 1;
|
||||
}
|
||||
color += texelFetch(source_ssr, ofs, 0);
|
||||
float d = texelFetch(source_depth, ofs, 0).r;
|
||||
normal += texelFetch(source_normal, ofs, 0).xyz * 2.0 - 1.0;
|
||||
|
||||
d = d * 2.0 - 1.0;
|
||||
if (params.orthogonal) {
|
||||
d = ((d + (params.camera_z_far + params.camera_z_near) / (params.camera_z_far - params.camera_z_near)) * (params.camera_z_far - params.camera_z_near)) / 2.0;
|
||||
} else {
|
||||
d = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - d * (params.camera_z_far - params.camera_z_near));
|
||||
}
|
||||
depth += -d;
|
||||
}
|
||||
|
||||
color /= 4.0;
|
||||
depth /= 4.0;
|
||||
normal = normalize(normal / 4.0) * 0.5 + 0.5;
|
||||
|
||||
} else {
|
||||
color = texelFetch(source_ssr, ssC << 1, 0);
|
||||
depth = texelFetch(source_depth, ssC << 1, 0).r;
|
||||
normal = texelFetch(source_normal, ssC << 1, 0).xyz;
|
||||
|
||||
depth = depth * 2.0 - 1.0;
|
||||
if (params.orthogonal) {
|
||||
depth = ((depth + (params.camera_z_far + params.camera_z_near) / (params.camera_z_far - params.camera_z_near)) * (params.camera_z_far - params.camera_z_near)) / 2.0;
|
||||
} else {
|
||||
depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near));
|
||||
}
|
||||
depth = -depth;
|
||||
}
|
||||
|
||||
imageStore(dest_ssr, ssC, color);
|
||||
imageStore(dest_depth, ssC, vec4(depth));
|
||||
imageStore(dest_normal, ssC, vec4(normal, 0.0));
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/* clang-format off */
|
||||
[vertex]
|
||||
|
||||
#version 450
|
||||
|
||||
VERSION_DEFINES
|
||||
|
||||
layout(location = 0) out vec2 uv_interp;
|
||||
/* clang-format on */
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
|
||||
uv_interp = base_arr[gl_VertexIndex];
|
||||
|
||||
gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
[fragment]
|
||||
|
||||
#version 450
|
||||
|
||||
VERSION_DEFINES
|
||||
|
||||
layout(location = 0) in vec2 uv_interp;
|
||||
/* clang-format on */
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D specular;
|
||||
|
||||
#ifdef MODE_SSR
|
||||
|
||||
layout(set = 1, binding = 0) uniform sampler2D ssr;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef MODE_MERGE
|
||||
|
||||
layout(set = 2, binding = 0) uniform sampler2D diffuse;
|
||||
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
|
||||
frag_color.rgb = texture(specular, uv_interp).rgb;
|
||||
frag_color.a = 0.0;
|
||||
#ifdef MODE_SSR
|
||||
|
||||
vec4 ssr = texture(ssr, uv_interp);
|
||||
frag_color.rgb = mix(frag_color.rgb, ssr.rgb, ssr.a);
|
||||
#endif
|
||||
|
||||
#ifdef MODE_MERGE
|
||||
frag_color += texture(diffuse, uv_interp);
|
||||
#endif
|
||||
//added using additive blend
|
||||
}
|
|
@ -523,7 +523,9 @@ public:
|
|||
#if 0
|
||||
BIND2(environment_set_camera_feed_id, RID, int)
|
||||
#endif
|
||||
BIND7(environment_set_ssr, RID, bool, int, float, float, float, bool)
|
||||
BIND6(environment_set_ssr, RID, bool, int, float, float, float)
|
||||
BIND1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality)
|
||||
|
||||
BIND9(environment_set_ssao, RID, bool, float, float, float, float, float, EnvironmentSSAOBlur, float)
|
||||
BIND2(environment_set_ssao_quality, EnvironmentSSAOQuality, bool)
|
||||
|
||||
|
|
|
@ -437,7 +437,9 @@ public:
|
|||
#if 0
|
||||
FUNC2(environment_set_camera_feed_id, RID, int)
|
||||
#endif
|
||||
FUNC7(environment_set_ssr, RID, bool, int, float, float, float, bool)
|
||||
FUNC6(environment_set_ssr, RID, bool, int, float, float, float)
|
||||
FUNC1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality)
|
||||
|
||||
FUNC9(environment_set_ssao, RID, bool, float, float, float, float, float, EnvironmentSSAOBlur, float)
|
||||
|
||||
FUNC2(environment_set_ssao_quality, EnvironmentSSAOQuality, bool)
|
||||
|
|
|
@ -2359,6 +2359,9 @@ RenderingServer::RenderingServer() {
|
|||
GLOBAL_DEF("rendering/quality/glow/upscale_mode", 1);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/glow/upscale_mode", PropertyInfo(Variant::INT, "rendering/quality/glow/upscale_mode", PROPERTY_HINT_ENUM, "Linear (Fast),Bicubic (Slower)"));
|
||||
GLOBAL_DEF("rendering/quality/glow/upscale_mode.mobile", 0);
|
||||
|
||||
GLOBAL_DEF("rendering/quality/screen_space_reflection/roughness_quality", 1);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_space_reflection/roughness_quality", PropertyInfo(Variant::INT, "rendering/quality/screen_space_reflection/roughness_quality", PROPERTY_HINT_ENUM, "Disabled (Fastest),Low, Medium, High (Slowest)"));
|
||||
}
|
||||
|
||||
RenderingServer::~RenderingServer() {
|
||||
|
|
|
@ -747,7 +747,16 @@ public:
|
|||
virtual void environment_set_tonemap(RID p_env, 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_grey) = 0;
|
||||
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_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance) = 0;
|
||||
|
||||
enum EnvironmentSSRRoughnessQuality {
|
||||
ENV_SSR_ROUGNESS_QUALITY_DISABLED,
|
||||
ENV_SSR_ROUGNESS_QUALITY_LOW,
|
||||
ENV_SSR_ROUGNESS_QUALITY_MEDIUM,
|
||||
ENV_SSR_ROUGNESS_QUALITY_HIGH,
|
||||
};
|
||||
|
||||
virtual void environment_set_ssr_roughness_quality(EnvironmentSSRRoughnessQuality p_quality) = 0;
|
||||
|
||||
enum EnvironmentSSAOBlur {
|
||||
ENV_SSAO_BLUR_DISABLED,
|
||||
|
|
Loading…
Reference in New Issue