Add support for low-end 3D rendering.

-Reduce number of uniform sets from 6 to 4.
-Remove features in low end mode, in order to reduce the number of texture units fit to 16.
This commit is contained in:
reduz 2020-12-07 18:27:38 -03:00
parent efc2104096
commit 2748b9a10d
11 changed files with 503 additions and 412 deletions

View file

@ -257,6 +257,9 @@ void RendererSceneRenderForward::ShaderData::set_code(const String &p_code) {
RD::RenderPrimitive primitive_rd = uses_point_size ? RD::RENDER_PRIMITIVE_POINTS : primitive_rd_table[j];
for (int k = 0; k < SHADER_VERSION_MAX; k++) {
if (!static_cast<RendererSceneRenderForward *>(singleton)->shader.scene_shader.is_variant_enabled(k)) {
continue;
}
RD::PipelineRasterizationState raster_state;
raster_state.cull_mode = cull_mode_rd;
raster_state.wireframe = wireframe;
@ -516,11 +519,11 @@ RendererStorageRD::MaterialData *RendererSceneRenderForward::_create_material_fu
return material_data;
}
RendererSceneRenderForward::RenderBufferDataHighEnd::~RenderBufferDataHighEnd() {
RendererSceneRenderForward::RenderBufferDataForward::~RenderBufferDataForward() {
clear();
}
void RendererSceneRenderForward::RenderBufferDataHighEnd::ensure_specular() {
void RendererSceneRenderForward::RenderBufferDataForward::ensure_specular() {
if (!specular.is_valid()) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
@ -574,7 +577,7 @@ void RendererSceneRenderForward::RenderBufferDataHighEnd::ensure_specular() {
}
}
void RendererSceneRenderForward::RenderBufferDataHighEnd::ensure_gi() {
void RendererSceneRenderForward::RenderBufferDataForward::ensure_gi() {
if (!reflection_buffer.is_valid()) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
@ -587,7 +590,7 @@ void RendererSceneRenderForward::RenderBufferDataHighEnd::ensure_gi() {
}
}
void RendererSceneRenderForward::RenderBufferDataHighEnd::ensure_giprobe() {
void RendererSceneRenderForward::RenderBufferDataForward::ensure_giprobe() {
if (!giprobe_buffer.is_valid()) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R8G8_UINT;
@ -623,7 +626,7 @@ void RendererSceneRenderForward::RenderBufferDataHighEnd::ensure_giprobe() {
}
}
void RendererSceneRenderForward::RenderBufferDataHighEnd::clear() {
void RendererSceneRenderForward::RenderBufferDataForward::clear() {
if (ambient_buffer != RID() && ambient_buffer != color) {
RD::get_singleton()->free(ambient_buffer);
ambient_buffer = RID();
@ -687,7 +690,7 @@ void RendererSceneRenderForward::RenderBufferDataHighEnd::clear() {
}
}
void RendererSceneRenderForward::RenderBufferDataHighEnd::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) {
void RendererSceneRenderForward::RenderBufferDataForward::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) {
clear();
msaa = p_msaa;
@ -754,7 +757,7 @@ void RendererSceneRenderForward::RenderBufferDataHighEnd::configure(RID p_color_
}
}
void RendererSceneRenderForward::_allocate_normal_roughness_texture(RenderBufferDataHighEnd *rb) {
void RendererSceneRenderForward::_allocate_normal_roughness_texture(RenderBufferDataForward *rb) {
if (rb->normal_roughness_buffer.is_valid()) {
return;
}
@ -793,7 +796,7 @@ void RendererSceneRenderForward::_allocate_normal_roughness_texture(RenderBuffer
}
RendererSceneRenderRD::RenderBufferData *RendererSceneRenderForward::_create_render_buffer_data() {
return memnew(RenderBufferDataHighEnd);
return memnew(RenderBufferDataForward);
}
bool RendererSceneRenderForward::free(RID p_rid) {
@ -911,7 +914,7 @@ void RendererSceneRenderForward::_fill_instances(RenderList::Element **p_element
id.flags |= INSTANCE_DATA_FLAG_USE_GI_BUFFERS;
}
if (!e->instance->gi_probe_instances.empty()) {
if (!low_end && !e->instance->gi_probe_instances.empty()) {
uint32_t written = 0;
for (int j = 0; j < e->instance->gi_probe_instances.size(); j++) {
RID probe = e->instance->gi_probe_instances[j];
@ -950,23 +953,13 @@ void RendererSceneRenderForward::_fill_instances(RenderList::Element **p_element
/// RENDERING ///
void RendererSceneRenderForward::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set, bool p_force_wireframe, const Vector2 &p_uv_offset) {
void RendererSceneRenderForward::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe, const Vector2 &p_uv_offset) {
RD::DrawListID draw_list = p_draw_list;
RD::FramebufferFormatID framebuffer_format = p_framebuffer_Format;
//global scope bindings
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, render_base_uniform_set, SCENE_UNIFORM_SET);
if (p_radiance_uniform_set.is_valid()) {
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_radiance_uniform_set, RADIANCE_UNIFORM_SET);
} else {
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, default_radiance_uniform_set, RADIANCE_UNIFORM_SET);
}
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, view_dependant_uniform_set, VIEW_DEPENDANT_UNIFORM_SET);
if (p_render_buffers_uniform_set.is_valid()) {
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_render_buffers_uniform_set, RENDER_BUFFERS_UNIFORM_SET);
} else {
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, default_render_buffers_uniform_set, RENDER_BUFFERS_UNIFORM_SET);
}
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_render_pass_uniform_set, RENDER_PASS_UNIFORM_SET);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, default_vec4_xform_uniform_set, TRANSFORMS_UNIFORM_SET);
MaterialData *prev_material = nullptr;
@ -1214,7 +1207,7 @@ void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_ren
scene_state.ubo.fog_enabled = false;
if (p_render_buffers.is_valid()) {
RenderBufferDataHighEnd *render_buffers = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
RenderBufferDataForward *render_buffers = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
if (render_buffers->msaa != RS::VIEWPORT_MSAA_DISABLED) {
scene_state.ubo.gi_upscale_for_msaa = true;
}
@ -1639,9 +1632,9 @@ void RendererSceneRenderForward::_setup_lightmaps(InstanceBase **p_lightmap_cull
}
void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, int p_directional_light_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color) {
RenderBufferDataHighEnd *render_buffer = nullptr;
RenderBufferDataForward *render_buffer = nullptr;
if (p_render_buffer.is_valid()) {
render_buffer = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffer);
render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffer);
}
//first of all, make a new render pass
@ -1686,7 +1679,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
opaque_framebuffer = render_buffer->color_fb;
if (p_gi_probe_cull_count > 0) {
if (!low_end && p_gi_probe_cull_count > 0) {
using_giprobe = true;
render_buffer->ensure_gi();
}
@ -1761,7 +1754,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
render_list.clear();
_fill_render_list(p_cull_result, p_cull_count, PASS_MODE_COLOR, using_sdfgi);
bool using_sss = render_buffer && scene_state.used_sss && sub_surface_scattering_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
bool using_sss = !low_end && render_buffer && scene_state.used_sss && sub_surface_scattering_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
if (using_sss) {
using_separate_specular = true;
@ -1769,7 +1762,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
using_separate_specular = true;
opaque_specular_framebuffer = render_buffer->color_specular_fb;
}
RID radiance_uniform_set;
RID radiance_texture;
bool draw_sky = false;
bool draw_sky_fog_only = false;
@ -1831,7 +1824,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
RID sky = environment_get_sky(p_environment);
if (sky.is_valid()) {
_update_sky(p_environment, projection, p_cam_transform);
radiance_uniform_set = sky_get_radiance_uniform_set_rd(sky, default_shader_rd, RADIANCE_UNIFORM_SET);
radiance_texture = sky_get_radiance_texture_rd(sky);
} else {
// do not try to draw sky if invalid
draw_sky = false;
@ -1841,7 +1834,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
clear_color = p_default_bg_color;
}
_setup_view_dependant_uniform_set(p_shadow_atlas, p_reflection_atlas, p_gi_probe_cull_result, p_gi_probe_cull_count);
RID rp_uniform_set = _setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_gi_probe_cull_result, p_gi_probe_cull_count);
render_list.sort_by_key(false);
@ -1850,8 +1843,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
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 debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES;
bool depth_pre_pass = depth_framebuffer.is_valid();
RID render_buffers_uniform_set;
bool depth_pre_pass = !low_end && depth_framebuffer.is_valid();
bool using_ssao = depth_pre_pass && p_render_buffer.is_valid() && p_environment.is_valid() && environment_is_ssao_enabled(p_environment);
bool continue_depth = false;
@ -1860,7 +1852,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
bool finish_depth = using_ssao || using_sdfgi || using_giprobe;
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, finish_depth ? 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(), get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME);
_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, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME);
RD::get_singleton()->draw_list_end();
if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
@ -1884,12 +1876,6 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
_process_gi(p_render_buffer, render_buffer->normal_roughness_buffer, render_buffer->ambient_buffer, render_buffer->reflection_buffer, render_buffer->giprobe_buffer, p_environment, p_cam_projection, p_cam_transform, p_gi_probe_cull_result, p_gi_probe_cull_count);
}
if (p_render_buffer.is_valid()) {
//update the render buffers uniform set in case it changed
_update_render_buffers_uniform_set(p_render_buffer);
render_buffers_uniform_set = render_buffer->uniform_set;
}
_setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), p_render_buffer.is_valid());
RENDER_TIMESTAMP("Render Opaque Pass");
@ -1914,7 +1900,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
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 ? (continue_depth ? 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, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME);
_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, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME);
RD::get_singleton()->draw_list_end();
if (will_continue_color && using_separate_specular) {
@ -2002,7 +1988,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
{
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, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME);
_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, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME);
RD::get_singleton()->draw_list_end();
}
@ -2028,7 +2014,7 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, InstanceBase
_fill_render_list(p_cull_result, p_cull_count, pass_mode);
_setup_view_dependant_uniform_set(RID(), RID(), nullptr, 0);
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), nullptr, 0);
RENDER_TIMESTAMP("Render Shadow");
@ -2039,7 +2025,7 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, InstanceBase
{
//regular forward for now
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, p_use_dp_flip, pass_mode, true, RID(), RID());
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, p_use_dp_flip, pass_mode, true, rp_uniform_set);
RD::get_singleton()->draw_list_end();
}
}
@ -2061,7 +2047,7 @@ void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb,
_fill_render_list(p_cull_result, p_cull_count, pass_mode);
_setup_view_dependant_uniform_set(RID(), RID(), nullptr, 0);
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), nullptr, 0);
RENDER_TIMESTAMP("Render Collider Heightield");
@ -2072,7 +2058,7 @@ void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb,
{
//regular forward for now
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_fb), render_list.elements, render_list.element_count, false, pass_mode, true, RID(), RID());
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_fb), render_list.elements, render_list.element_count, false, pass_mode, true, rp_uniform_set);
RD::get_singleton()->draw_list_end();
}
}
@ -2094,7 +2080,7 @@ void RendererSceneRenderForward::_render_material(const Transform &p_cam_transfo
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
_fill_render_list(p_cull_result, p_cull_count, pass_mode);
_setup_view_dependant_uniform_set(RID(), RID(), nullptr, 0);
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), nullptr, 0);
RENDER_TIMESTAMP("Render Material");
@ -2111,7 +2097,7 @@ void RendererSceneRenderForward::_render_material(const Transform &p_cam_transfo
clear.push_back(Color(0, 0, 0, 0));
clear.push_back(Color(0, 0, 0, 0));
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region);
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, RID(), RID());
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set);
RD::get_singleton()->draw_list_end();
}
}
@ -2133,7 +2119,7 @@ void RendererSceneRenderForward::_render_uv2(InstanceBase **p_cull_result, int p
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
_fill_render_list(p_cull_result, p_cull_count, pass_mode);
_setup_view_dependant_uniform_set(RID(), RID(), nullptr, 0);
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), nullptr, 0);
RENDER_TIMESTAMP("Render Material");
@ -2169,9 +2155,9 @@ void RendererSceneRenderForward::_render_uv2(InstanceBase **p_cull_result, int p
Vector2 ofs = uv_offsets[i];
ofs.x /= p_region.size.width;
ofs.y /= p_region.size.height;
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, RID(), RID(), true, ofs); //first wireframe, for pseudo conservative
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, true, ofs); //first wireframe, for pseudo conservative
}
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, RID(), RID(), false); //second regular triangles
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, false); //second regular triangles
RD::get_singleton()->draw_list_end();
}
@ -2182,7 +2168,7 @@ void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vecto
_update_render_base_uniform_set();
RenderBufferDataHighEnd *render_buffer = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
RenderBufferDataForward *render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
ERR_FAIL_COND(!render_buffer);
render_pass++;
@ -2193,45 +2179,11 @@ void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vecto
render_list.sort_by_key(false);
_fill_instances(render_list.elements, render_list.element_count, true);
_setup_view_dependant_uniform_set(RID(), RID(), nullptr, 0);
RID rp_uniform_set = _setup_sdfgi_render_pass_uniform_set(p_albedo_texture, p_emission_texture, p_emission_aniso_texture, p_geom_facing_texture);
Vector3 half_extents = p_bounds.size * 0.5;
Vector3 center = p_bounds.position + half_extents;
if (render_buffer->render_sdfgi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_buffer->render_sdfgi_uniform_set)) {
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 0;
u.ids.push_back(p_albedo_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 1;
u.ids.push_back(p_emission_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 2;
u.ids.push_back(p_emission_aniso_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 3;
u.ids.push_back(p_geom_facing_texture);
uniforms.push_back(u);
}
render_buffer->render_sdfgi_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_sdfgi_rd, RENDER_BUFFERS_UNIFORM_SET);
}
Vector<RID> sbs;
sbs.push_back(p_albedo_texture);
sbs.push_back(p_emission_texture);
@ -2287,7 +2239,7 @@ void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vecto
}
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(E->get(), RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, Rect2(), sbs);
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(E->get()), render_list.elements, render_list.element_count, true, pass_mode, true, RID(), render_buffer->render_sdfgi_uniform_set, false); //second regular triangles
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(E->get()), render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, false); //second regular triangles
RD::get_singleton()->draw_list_end();
}
}
@ -2455,7 +2407,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
uniforms.push_back(u);
}
{
if (!low_end) {
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 20;
@ -2467,9 +2419,14 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
}
}
void RendererSceneRenderForward::_setup_view_dependant_uniform_set(RID p_shadow_atlas, RID p_reflection_atlas, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count) {
if (view_dependant_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(view_dependant_uniform_set)) {
RD::get_singleton()->free(view_dependant_uniform_set);
RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count) {
if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) {
RD::get_singleton()->free(render_pass_uniform_set);
}
RenderBufferDataForward *rb = nullptr;
if (p_render_buffers.is_valid()) {
rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
}
//default render buffer and scene state uniform set
@ -2477,10 +2434,24 @@ void RendererSceneRenderForward::_setup_view_dependant_uniform_set(RID p_shadow_
Vector<RD::Uniform> uniforms;
{
RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID();
RID radiance_texture;
if (p_radiance_texture.is_valid()) {
radiance_texture = p_radiance_texture;
} else {
radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK);
}
RD::Uniform u;
u.binding = 0;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(radiance_texture);
uniforms.push_back(u);
}
{
RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID();
RD::Uniform u;
u.binding = 1;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
if (ref_texture.is_valid()) {
u.ids.push_back(ref_texture);
} else {
@ -2491,7 +2462,7 @@ void RendererSceneRenderForward::_setup_view_dependant_uniform_set(RID p_shadow_
{
RD::Uniform u;
u.binding = 1;
u.binding = 2;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture;
if (p_shadow_atlas.is_valid()) {
@ -2506,8 +2477,9 @@ void RendererSceneRenderForward::_setup_view_dependant_uniform_set(RID p_shadow_
{
RD::Uniform u;
u.binding = 2;
u.binding = 3;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.resize(MAX_GI_PROBES);
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
for (int i = 0; i < MAX_GI_PROBES; i++) {
if (i < p_gi_probe_cull_count) {
@ -2515,84 +2487,47 @@ void RendererSceneRenderForward::_setup_view_dependant_uniform_set(RID p_shadow_
if (!tex.is_valid()) {
tex = default_tex;
}
u.ids.push_back(tex);
u.ids.write[i] = tex;
} else {
u.ids.push_back(default_tex);
u.ids.write[i] = default_tex;
}
}
uniforms.push_back(u);
}
view_dependant_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, VIEW_DEPENDANT_UNIFORM_SET);
}
void RendererSceneRenderForward::_render_buffers_clear_uniform_set(RenderBufferDataHighEnd *rb) {
if (!rb->uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(rb->uniform_set)) {
RD::get_singleton()->free(rb->uniform_set);
{
RD::Uniform u;
u.binding = 4;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = false && rb && rb->depth.is_valid() ? rb->depth : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
u.ids.push_back(texture);
uniforms.push_back(u);
}
rb->uniform_set = RID();
}
void RendererSceneRenderForward::_render_buffers_uniform_set_changed(RID p_render_buffers) {
RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
_render_buffers_clear_uniform_set(rb);
}
RID RendererSceneRenderForward::_render_buffers_get_normal_texture(RID p_render_buffers) {
RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
return rb->normal_roughness_buffer;
}
RID RendererSceneRenderForward::_render_buffers_get_ambient_texture(RID p_render_buffers) {
RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
return rb->ambient_buffer;
}
RID RendererSceneRenderForward::_render_buffers_get_reflection_texture(RID p_render_buffers) {
RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
return rb->reflection_buffer;
}
void RendererSceneRenderForward::_update_render_buffers_uniform_set(RID p_render_buffers) {
RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
if (rb->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->uniform_set)) {
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
u.binding = 5;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_buffers) : RID();
RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
}
if (!low_end) {
{
RD::Uniform u;
u.binding = 0;
u.binding = 6;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = false && rb->depth.is_valid() ? rb->depth : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 1;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID bbt = render_buffers_get_back_buffer_texture(p_render_buffers);
RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 2;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL);
RID texture = rb && rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 4;
u.binding = 7;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID aot = render_buffers_get_ao_texture(p_render_buffers);
RID aot = rb ? render_buffers_get_ao_texture(p_render_buffers) : RID();
RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
@ -2600,27 +2535,27 @@ void RendererSceneRenderForward::_update_render_buffers_uniform_set(RID p_render
{
RD::Uniform u;
u.binding = 5;
u.binding = 8;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = rb->ambient_buffer.is_valid() ? rb->ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
RID texture = rb && rb->ambient_buffer.is_valid() ? rb->ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 6;
u.binding = 9;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = rb->reflection_buffer.is_valid() ? rb->reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
RID texture = rb && rb->reflection_buffer.is_valid() ? rb->reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 7;
u.binding = 10;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID t;
if (render_buffers_is_sdfgi_enabled(p_render_buffers)) {
if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
t = render_buffers_get_sdfgi_irradiance_probes(p_render_buffers);
} else {
t = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
@ -2630,9 +2565,9 @@ void RendererSceneRenderForward::_update_render_buffers_uniform_set(RID p_render
}
{
RD::Uniform u;
u.binding = 8;
u.binding = 11;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
if (render_buffers_is_sdfgi_enabled(p_render_buffers)) {
if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_buffers));
} else {
u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
@ -2641,17 +2576,17 @@ void RendererSceneRenderForward::_update_render_buffers_uniform_set(RID p_render
}
{
RD::Uniform u;
u.binding = 9;
u.binding = 12;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.ids.push_back(render_buffers_get_gi_probe_buffer(p_render_buffers));
u.ids.push_back(rb ? render_buffers_get_default_gi_probe_buffer() : render_buffers_get_gi_probe_buffer(p_render_buffers));
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 10;
u.binding = 13;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID vfog = RID();
if (p_render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_buffers)) {
if (rb && render_buffers_has_volumetric_fog(p_render_buffers)) {
vfog = render_buffers_get_volumetric_fog_texture(p_render_buffers);
if (vfog.is_null()) {
vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
@ -2662,8 +2597,122 @@ void RendererSceneRenderForward::_update_render_buffers_uniform_set(RID p_render
u.ids.push_back(vfog);
uniforms.push_back(u);
}
rb->uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RENDER_BUFFERS_UNIFORM_SET);
}
render_pass_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RENDER_PASS_UNIFORM_SET);
return render_pass_uniform_set;
}
RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture) {
if (sdfgi_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_pass_uniform_set)) {
RD::get_singleton()->free(sdfgi_pass_uniform_set);
}
Vector<RD::Uniform> uniforms;
{
// No radiance texture.
RID radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK);
RD::Uniform u;
u.binding = 0;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(radiance_texture);
uniforms.push_back(u);
}
{
// No reflection atlas.
RID ref_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK);
RD::Uniform u;
u.binding = 1;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(ref_texture);
uniforms.push_back(u);
}
{
// No shadow atlas.
RD::Uniform u;
u.binding = 2;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
// No GIProbes
RD::Uniform u;
u.binding = 3;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.resize(MAX_GI_PROBES);
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
for (int i = 0; i < MAX_GI_PROBES; i++) {
u.ids.write[i] = default_tex;
}
uniforms.push_back(u);
}
// actual sdfgi stuff
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 4;
u.ids.push_back(p_albedo_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 5;
u.ids.push_back(p_emission_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 6;
u.ids.push_back(p_emission_aniso_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 7;
u.ids.push_back(p_geom_facing_texture);
uniforms.push_back(u);
}
sdfgi_pass_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RENDER_PASS_UNIFORM_SET);
return sdfgi_pass_uniform_set;
}
void RendererSceneRenderForward::_render_buffers_clear_uniform_set(RenderBufferDataForward *rb) {
}
void RendererSceneRenderForward::_render_buffers_uniform_set_changed(RID p_render_buffers) {
RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
_render_buffers_clear_uniform_set(rb);
}
RID RendererSceneRenderForward::_render_buffers_get_normal_texture(RID p_render_buffers) {
RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
return rb->normal_roughness_buffer;
}
RID RendererSceneRenderForward::_render_buffers_get_ambient_texture(RID p_render_buffers) {
RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
return rb->ambient_buffer;
}
RID RendererSceneRenderForward::_render_buffers_get_reflection_texture(RID p_render_buffers) {
RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
return rb->reflection_buffer;
}
RendererSceneRenderForward *RendererSceneRenderForward::singleton = nullptr;
@ -2676,12 +2725,17 @@ void RendererSceneRenderForward::set_time(double p_time, double p_step) {
RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_storage) :
RendererSceneRenderRD(p_storage) {
singleton = this;
low_end = is_low_end();
storage = p_storage;
/* SCENE SHADER */
{
String defines;
if (low_end) {
defines += "\n#define LOW_END_MODE \n";
}
defines += "\n#define MAX_ROUGHNESS_LOD " + itos(get_roughness_layers() - 1) + ".0\n";
if (is_using_radiance_cubemap_array()) {
defines += "\n#define USE_RADIANCE_CUBEMAP_ARRAY \n";
@ -2721,6 +2775,16 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor
shader_versions.push_back("\n#define USE_LIGHTMAP\n");
shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n#define USE_LIGHTMAP\n");
shader.scene_shader.initialize(shader_versions, defines);
if (is_low_end()) {
//disable the high end versions
shader.scene_shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS, false);
shader.scene_shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE, false);
shader.scene_shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_SDF, false);
shader.scene_shader.set_variant_enabled(SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI, false);
shader.scene_shader.set_variant_enabled(SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR, false);
shader.scene_shader.set_variant_enabled(SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR, false);
}
}
storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_shader_funcs);
@ -2924,7 +2988,9 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor
MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
default_shader_rd = shader.scene_shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS);
default_shader_sdfgi_rd = shader.scene_shader.version_get_shader(md->shader_data->version, SHADER_VERSION_DEPTH_PASS_WITH_SDF);
if (!low_end) {
default_shader_sdfgi_rd = shader.scene_shader.version_get_shader(md->shader_data->version, SHADER_VERSION_DEPTH_PASS_WITH_SDF);
}
}
{
@ -2958,74 +3024,20 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor
sampler.compare_op = RD::COMPARE_OP_LESS;
shadow_sampler = RD::get_singleton()->sampler_create(sampler);
}
{
Vector<RD::Uniform> uniforms;
RD::Uniform u;
u.binding = 0;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
default_radiance_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RADIANCE_UNIFORM_SET);
}
{ //render buffers
Vector<RD::Uniform> uniforms;
for (int i = 0; i < 7; i++) {
RD::Uniform u;
u.binding = i;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = storage->texture_rd_get_default(i == 0 ? RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE : (i == 2 ? RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL : RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK));
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 7;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 8;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 9;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.ids.push_back(render_buffers_get_default_gi_probe_buffer());
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 10;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
uniforms.push_back(u);
}
default_render_buffers_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RENDER_BUFFERS_UNIFORM_SET);
}
}
RendererSceneRenderForward::~RendererSceneRenderForward() {
directional_shadow_atlas_set_size(0);
//clear base uniform set if still valid
if (view_dependant_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(view_dependant_uniform_set)) {
RD::get_singleton()->free(view_dependant_uniform_set);
if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) {
RD::get_singleton()->free(render_pass_uniform_set);
}
if (sdfgi_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_pass_uniform_set)) {
RD::get_singleton()->free(sdfgi_pass_uniform_set);
}
RD::get_singleton()->free(default_render_buffers_uniform_set);
RD::get_singleton()->free(default_radiance_uniform_set);
RD::get_singleton()->free(default_vec4_xform_buffer);
RD::get_singleton()->free(shadow_sampler);

View file

@ -34,16 +34,14 @@
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/scene_high_end.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/scene_forward.glsl.gen.h"
class RendererSceneRenderForward : public RendererSceneRenderRD {
enum {
SCENE_UNIFORM_SET = 0,
RADIANCE_UNIFORM_SET = 1,
VIEW_DEPENDANT_UNIFORM_SET = 2,
RENDER_BUFFERS_UNIFORM_SET = 3,
TRANSFORMS_UNIFORM_SET = 4,
MATERIAL_UNIFORM_SET = 5
RENDER_PASS_UNIFORM_SET = 1,
TRANSFORMS_UNIFORM_SET = 2,
MATERIAL_UNIFORM_SET = 3
};
enum {
@ -69,7 +67,7 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
};
struct {
SceneHighEndShaderRD scene_shader;
SceneForwardShaderRD scene_shader;
ShaderCompilerRD compiler;
} shader;
@ -209,7 +207,7 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
/* Framebuffer */
struct RenderBufferDataHighEnd : public RenderBufferData {
struct RenderBufferDataForward : public RenderBufferData {
//for rendering, may be MSAAd
RID color;
@ -246,30 +244,29 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
void clear();
virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa);
RID uniform_set;
~RenderBufferDataHighEnd();
~RenderBufferDataForward();
};
virtual RenderBufferData *_create_render_buffer_data();
void _allocate_normal_roughness_texture(RenderBufferDataHighEnd *rb);
void _allocate_normal_roughness_texture(RenderBufferDataForward *rb);
RID shadow_sampler;
RID render_base_uniform_set;
RID view_dependant_uniform_set;
RID render_pass_uniform_set;
RID sdfgi_pass_uniform_set;
uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
virtual void _base_uniforms_changed();
void _render_buffers_clear_uniform_set(RenderBufferDataHighEnd *rb);
void _render_buffers_clear_uniform_set(RenderBufferDataForward *rb);
virtual void _render_buffers_uniform_set_changed(RID p_render_buffers);
virtual RID _render_buffers_get_normal_texture(RID p_render_buffers);
virtual RID _render_buffers_get_ambient_texture(RID p_render_buffers);
virtual RID _render_buffers_get_reflection_texture(RID p_render_buffers);
void _update_render_base_uniform_set();
void _setup_view_dependant_uniform_set(RID p_shadow_atlas, RID p_reflection_atlas, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count);
void _update_render_buffers_uniform_set(RID p_render_buffers);
RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture);
RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count);
struct LightmapData {
float normal_xform[12];
@ -552,8 +549,6 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
RID wireframe_material;
RID default_shader_rd;
RID default_shader_sdfgi_rd;
RID default_radiance_uniform_set;
RID default_render_buffers_uniform_set;
RID default_vec4_xform_buffer;
RID default_vec4_xform_uniform_set;
@ -575,7 +570,7 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
void _setup_lightmaps(InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, const Transform &p_cam_transform);
void _fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth, bool p_has_sdfgi = false, bool p_has_opaque_gi = false);
void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2());
void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2());
_FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
_FORCE_INLINE_ void _add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
@ -583,6 +578,8 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
Map<Size2i, RID> sdfgi_framebuffer_size_cache;
bool low_end = false;
protected:
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, int p_directional_light_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color);
virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake);

View file

@ -2971,6 +2971,10 @@ void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
if (low_end) {
return;
}
env->sdfgi_enabled = p_enable;
env->sdfgi_cascades = p_cascades;
env->sdfgi_min_cell_size = p_min_cell_size;
@ -3045,6 +3049,10 @@ void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_ena
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
if (low_end) {
return;
}
env->volumetric_fog_enabled = p_enable;
env->volumetric_fog_density = p_density;
env->volumetric_fog_light = p_light;
@ -3095,6 +3103,10 @@ void RendererSceneRenderRD::environment_set_ssr(RID p_env, bool p_enable, int p_
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
if (low_end) {
return;
}
env->ssr_enabled = p_enable;
env->ssr_max_steps = p_max_steps;
env->ssr_fade_in = p_fade_int;
@ -3114,6 +3126,10 @@ void RendererSceneRenderRD::environment_set_ssao(RID p_env, bool p_enable, float
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
if (low_end) {
return;
}
env->ssao_enabled = p_enable;
env->ssao_radius = p_radius;
env->ssao_intensity = p_intensity;
@ -4024,6 +4040,10 @@ bool RendererSceneRenderRD::gi_probe_needs_update(RID p_probe) const {
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
ERR_FAIL_COND_V(!gi_probe, false);
if (low_end) {
return false;
}
//return true;
return gi_probe->last_probe_version != storage->gi_probe_get_version(gi_probe->probe);
}
@ -4032,6 +4052,10 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
ERR_FAIL_COND(!gi_probe);
if (low_end) {
return;
}
uint32_t data_version = storage->gi_probe_get_data_version(gi_probe->probe);
// (RE)CREATE IF NEEDED
@ -7952,6 +7976,10 @@ int RendererSceneRenderRD::get_max_directional_lights() const {
return cluster.max_directional_lights;
}
bool RendererSceneRenderRD::is_low_end() const {
return low_end;
}
RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
storage = p_storage;
singleton = this;
@ -7961,9 +7989,15 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
sky_use_cubemap_array = GLOBAL_GET("rendering/quality/reflections/texture_array_reflections");
// sky_use_cubemap_array = false;
//uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
{
low_end = GLOBAL_GET("rendering/quality/rd_renderer/use_low_end_renderer");
if (textures_per_stage < 48) {
low_end = true;
}
if (!low_end) {
//kinda complicated to compute the amount of slots, we try to use as many as we can
gi_probe_max_lights = 32;
@ -7992,7 +8026,7 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
}
}
{
if (!low_end) {
String defines;
Vector<String> versions;
versions.push_back("\n#define MODE_DEBUG_COLOR\n");
@ -8208,121 +8242,125 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
sky_scene_state.fog_only_texture_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_TEXTURES);
}
{
Vector<String> preprocess_modes;
preprocess_modes.push_back("\n#define MODE_SCROLL\n");
preprocess_modes.push_back("\n#define MODE_SCROLL_OCCLUSION\n");
preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD\n");
preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD_HALF\n");
preprocess_modes.push_back("\n#define MODE_JUMPFLOOD\n");
preprocess_modes.push_back("\n#define MODE_JUMPFLOOD_OPTIMIZED\n");
preprocess_modes.push_back("\n#define MODE_UPSCALE_JUMP_FLOOD\n");
preprocess_modes.push_back("\n#define MODE_OCCLUSION\n");
preprocess_modes.push_back("\n#define MODE_STORE\n");
String defines = "\n#define OCCLUSION_SIZE " + itos(SDFGI::CASCADE_SIZE / SDFGI::PROBE_DIVISOR) + "\n";
sdfgi_shader.preprocess.initialize(preprocess_modes, defines);
sdfgi_shader.preprocess_shader = sdfgi_shader.preprocess.version_create();
for (int i = 0; i < SDGIShader::PRE_PROCESS_MAX; i++) {
sdfgi_shader.preprocess_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, i));
}
}
{
//calculate tables
String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
Vector<String> direct_light_modes;
direct_light_modes.push_back("\n#define MODE_PROCESS_STATIC\n");
direct_light_modes.push_back("\n#define MODE_PROCESS_DYNAMIC\n");
sdfgi_shader.direct_light.initialize(direct_light_modes, defines);
sdfgi_shader.direct_light_shader = sdfgi_shader.direct_light.version_create();
for (int i = 0; i < SDGIShader::DIRECT_LIGHT_MODE_MAX; i++) {
sdfgi_shader.direct_light_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.direct_light.version_get_shader(sdfgi_shader.direct_light_shader, i));
}
}
{
//calculate tables
String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
defines += "\n#define SH_SIZE " + itos(SDFGI::SH_SIZE) + "\n";
Vector<String> integrate_modes;
integrate_modes.push_back("\n#define MODE_PROCESS\n");
integrate_modes.push_back("\n#define MODE_STORE\n");
integrate_modes.push_back("\n#define MODE_SCROLL\n");
integrate_modes.push_back("\n#define MODE_SCROLL_STORE\n");
sdfgi_shader.integrate.initialize(integrate_modes, defines);
sdfgi_shader.integrate_shader = sdfgi_shader.integrate.version_create();
for (int i = 0; i < SDGIShader::INTEGRATE_MODE_MAX; i++) {
sdfgi_shader.integrate_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, i));
if (!low_end) {
//SDFGI
{
Vector<String> preprocess_modes;
preprocess_modes.push_back("\n#define MODE_SCROLL\n");
preprocess_modes.push_back("\n#define MODE_SCROLL_OCCLUSION\n");
preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD\n");
preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD_HALF\n");
preprocess_modes.push_back("\n#define MODE_JUMPFLOOD\n");
preprocess_modes.push_back("\n#define MODE_JUMPFLOOD_OPTIMIZED\n");
preprocess_modes.push_back("\n#define MODE_UPSCALE_JUMP_FLOOD\n");
preprocess_modes.push_back("\n#define MODE_OCCLUSION\n");
preprocess_modes.push_back("\n#define MODE_STORE\n");
String defines = "\n#define OCCLUSION_SIZE " + itos(SDFGI::CASCADE_SIZE / SDFGI::PROBE_DIVISOR) + "\n";
sdfgi_shader.preprocess.initialize(preprocess_modes, defines);
sdfgi_shader.preprocess_shader = sdfgi_shader.preprocess.version_create();
for (int i = 0; i < SDGIShader::PRE_PROCESS_MAX; i++) {
sdfgi_shader.preprocess_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, i));
}
}
{
Vector<RD::Uniform> uniforms;
//calculate tables
String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 0;
u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE));
uniforms.push_back(u);
Vector<String> direct_light_modes;
direct_light_modes.push_back("\n#define MODE_PROCESS_STATIC\n");
direct_light_modes.push_back("\n#define MODE_PROCESS_DYNAMIC\n");
sdfgi_shader.direct_light.initialize(direct_light_modes, defines);
sdfgi_shader.direct_light_shader = sdfgi_shader.direct_light.version_create();
for (int i = 0; i < SDGIShader::DIRECT_LIGHT_MODE_MAX; i++) {
sdfgi_shader.direct_light_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.direct_light.version_get_shader(sdfgi_shader.direct_light_shader, i));
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 1;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
}
sdfgi_shader.integrate_default_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, 0), 1);
}
}
{
//calculate tables
String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
Vector<String> gi_modes;
gi_modes.push_back("");
gi.shader.initialize(gi_modes, defines);
gi.shader_version = gi.shader.version_create();
for (int i = 0; i < GI::MODE_MAX; i++) {
gi.pipelines[i] = RD::get_singleton()->compute_pipeline_create(gi.shader.version_get_shader(gi.shader_version, i));
}
gi.sdfgi_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(GI::SDFGIData));
}
{
String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
Vector<String> debug_modes;
debug_modes.push_back("");
sdfgi_shader.debug.initialize(debug_modes, defines);
sdfgi_shader.debug_shader = sdfgi_shader.debug.version_create();
sdfgi_shader.debug_shader_version = sdfgi_shader.debug.version_get_shader(sdfgi_shader.debug_shader, 0);
sdfgi_shader.debug_pipeline = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.debug_shader_version);
}
{
String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
Vector<String> versions;
versions.push_back("\n#define MODE_PROBES\n");
versions.push_back("\n#define MODE_VISIBILITY\n");
sdfgi_shader.debug_probes.initialize(versions, defines);
sdfgi_shader.debug_probes_shader = sdfgi_shader.debug_probes.version_create();
{
RD::PipelineRasterizationState rs;
rs.cull_mode = RD::POLYGON_CULL_DISABLED;
RD::PipelineDepthStencilState ds;
ds.enable_depth_test = true;
ds.enable_depth_write = true;
ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
for (int i = 0; i < SDGIShader::PROBE_DEBUG_MAX; i++) {
RID debug_probes_shader_version = sdfgi_shader.debug_probes.version_get_shader(sdfgi_shader.debug_probes_shader, i);
sdfgi_shader.debug_probes_pipeline[i].setup(debug_probes_shader_version, RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0);
//calculate tables
String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
defines += "\n#define SH_SIZE " + itos(SDFGI::SH_SIZE) + "\n";
Vector<String> integrate_modes;
integrate_modes.push_back("\n#define MODE_PROCESS\n");
integrate_modes.push_back("\n#define MODE_STORE\n");
integrate_modes.push_back("\n#define MODE_SCROLL\n");
integrate_modes.push_back("\n#define MODE_SCROLL_STORE\n");
sdfgi_shader.integrate.initialize(integrate_modes, defines);
sdfgi_shader.integrate_shader = sdfgi_shader.integrate.version_create();
for (int i = 0; i < SDGIShader::INTEGRATE_MODE_MAX; i++) {
sdfgi_shader.integrate_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, i));
}
{
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 0;
u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE));
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 1;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
}
sdfgi_shader.integrate_default_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, 0), 1);
}
}
{
//calculate tables
String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
Vector<String> gi_modes;
gi_modes.push_back("");
gi.shader.initialize(gi_modes, defines);
gi.shader_version = gi.shader.version_create();
for (int i = 0; i < GI::MODE_MAX; i++) {
gi.pipelines[i] = RD::get_singleton()->compute_pipeline_create(gi.shader.version_get_shader(gi.shader_version, i));
}
gi.sdfgi_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(GI::SDFGIData));
}
{
String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
Vector<String> debug_modes;
debug_modes.push_back("");
sdfgi_shader.debug.initialize(debug_modes, defines);
sdfgi_shader.debug_shader = sdfgi_shader.debug.version_create();
sdfgi_shader.debug_shader_version = sdfgi_shader.debug.version_get_shader(sdfgi_shader.debug_shader, 0);
sdfgi_shader.debug_pipeline = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.debug_shader_version);
}
{
String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
Vector<String> versions;
versions.push_back("\n#define MODE_PROBES\n");
versions.push_back("\n#define MODE_VISIBILITY\n");
sdfgi_shader.debug_probes.initialize(versions, defines);
sdfgi_shader.debug_probes_shader = sdfgi_shader.debug_probes.version_create();
{
RD::PipelineRasterizationState rs;
rs.cull_mode = RD::POLYGON_CULL_DISABLED;
RD::PipelineDepthStencilState ds;
ds.enable_depth_test = true;
ds.enable_depth_write = true;
ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
for (int i = 0; i < SDGIShader::PROBE_DEBUG_MAX; i++) {
RID debug_probes_shader_version = sdfgi_shader.debug_probes.version_get_shader(sdfgi_shader.debug_probes_shader, i);
sdfgi_shader.debug_probes_pipeline[i].setup(debug_probes_shader_version, RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0);
}
}
}
default_giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GI::GIProbeData) * RenderBuffers::MAX_GIPROBES);
}
//cluster setup
@ -8366,7 +8404,7 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
cluster.builder.setup(16, 8, 24);
{
if (!low_end) {
String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(cluster.max_directional_lights) + "\n";
Vector<String> volumetric_fog_modes;
volumetric_fog_modes.push_back("\n#define MODE_DENSITY\n");
@ -8379,7 +8417,6 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
volumetric_fog.pipelines[i] = RD::get_singleton()->compute_pipeline_create(volumetric_fog.shader.version_get_shader(volumetric_fog.shader_version, i));
}
}
default_giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GI::GIProbeData) * RenderBuffers::MAX_GIPROBES);
{
RD::SamplerState sampler;
@ -8427,22 +8464,25 @@ RendererSceneRenderRD::~RendererSceneRenderRD() {
RD::get_singleton()->free(sky_scene_state.uniform_set);
}
RD::get_singleton()->free(default_giprobe_buffer);
RD::get_singleton()->free(gi_probe_lights_uniform);
RD::get_singleton()->free(gi.sdfgi_ubo);
if (!low_end) {
RD::get_singleton()->free(default_giprobe_buffer);
RD::get_singleton()->free(gi_probe_lights_uniform);
RD::get_singleton()->free(gi.sdfgi_ubo);
giprobe_debug_shader.version_free(giprobe_debug_shader_version);
giprobe_shader.version_free(giprobe_lighting_shader_version);
gi.shader.version_free(gi.shader_version);
sdfgi_shader.debug_probes.version_free(sdfgi_shader.debug_probes_shader);
sdfgi_shader.debug.version_free(sdfgi_shader.debug_shader);
sdfgi_shader.direct_light.version_free(sdfgi_shader.direct_light_shader);
sdfgi_shader.integrate.version_free(sdfgi_shader.integrate_shader);
sdfgi_shader.preprocess.version_free(sdfgi_shader.preprocess_shader);
giprobe_debug_shader.version_free(giprobe_debug_shader_version);
giprobe_shader.version_free(giprobe_lighting_shader_version);
gi.shader.version_free(gi.shader_version);
sdfgi_shader.debug_probes.version_free(sdfgi_shader.debug_probes_shader);
sdfgi_shader.debug.version_free(sdfgi_shader.debug_shader);
sdfgi_shader.direct_light.version_free(sdfgi_shader.direct_light_shader);
sdfgi_shader.integrate.version_free(sdfgi_shader.integrate_shader);
sdfgi_shader.preprocess.version_free(sdfgi_shader.preprocess_shader);
volumetric_fog.shader.version_free(volumetric_fog.shader_version);
volumetric_fog.shader.version_free(volumetric_fog.shader_version);
memdelete_arr(gi_probe_lights);
}
memdelete_arr(gi_probe_lights);
SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RendererStorageRD::SHADER_TYPE_SKY);
sky_shader.shader.version_free(md->shader_data->version);
RD::get_singleton()->free(sky_scene_state.directional_light_buffer);

View file

@ -1456,6 +1456,8 @@ private:
float weight;
};
bool low_end = false;
public:
/* SHADOW ATLAS API */
@ -1952,6 +1954,8 @@ public:
void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir);
bool is_low_end() const;
RendererSceneRenderRD(RendererStorageRD *p_storage);
~RendererSceneRenderRD();
};

View file

@ -199,6 +199,10 @@ void ShaderRD::_clear_version(Version *p_version) {
}
void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
if (!variants_enabled[p_variant]) {
return; //variant is disabled, return
}
Vector<RD::ShaderStageData> stages;
String error;
@ -365,6 +369,9 @@ void ShaderRD::_compile_version(Version *p_version) {
bool all_valid = true;
for (int i = 0; i < variant_defines.size(); i++) {
if (!variants_enabled[i]) {
continue; //disabled
}
if (p_version->variants[i].is_null()) {
all_valid = false;
break;
@ -374,6 +381,9 @@ void ShaderRD::_compile_version(Version *p_version) {
if (!all_valid) {
//clear versions if they exist
for (int i = 0; i < variant_defines.size(); i++) {
if (!variants_enabled[i]) {
continue; //disabled
}
if (!p_version->variants[i].is_null()) {
RD::get_singleton()->free(p_version->variants[i]);
}
@ -454,12 +464,26 @@ bool ShaderRD::version_free(RID p_version) {
return true;
}
void ShaderRD::set_variant_enabled(int p_variant, bool p_enabled) {
ERR_FAIL_COND(version_owner.get_rid_count() > 0); //versions exist
ERR_FAIL_INDEX(p_variant, variants_enabled.size());
variants_enabled.write[p_variant] = p_enabled;
}
bool ShaderRD::is_variant_enabled(int p_variant) const {
ERR_FAIL_INDEX_V(p_variant, variants_enabled.size(), false);
return variants_enabled[p_variant];
}
void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String &p_general_defines) {
ERR_FAIL_COND(variant_defines.size());
ERR_FAIL_COND(p_variant_defines.size() == 0);
general_defines = p_general_defines.utf8();
for (int i = 0; i < p_variant_defines.size(); i++) {
variant_defines.push_back(p_variant_defines[i].utf8());
variants_enabled.push_back(true);
}
}

View file

@ -46,6 +46,7 @@ class ShaderRD {
//versions
CharString general_defines;
Vector<CharString> variant_defines;
Vector<bool> variants_enabled;
struct Version {
CharString uniforms;
@ -109,6 +110,7 @@ public:
_FORCE_INLINE_ RID version_get_shader(RID p_version, int p_variant) {
ERR_FAIL_INDEX_V(p_variant, variant_defines.size(), RID());
ERR_FAIL_COND_V(!variants_enabled[p_variant], RID());
Version *version = version_owner.getornull(p_version);
ERR_FAIL_COND_V(!version, RID());
@ -128,6 +130,9 @@ public:
bool version_free(RID p_version);
void set_variant_enabled(int p_variant, bool p_enabled);
bool is_variant_enabled(int p_variant) const;
void initialize(const Vector<String> &p_variant_defines, const String &p_general_defines = "");
virtual ~ShaderRD();
};

View file

@ -11,7 +11,7 @@ if "RD_GLSL" in env["BUILDERS"]:
env.RD_GLSL("cubemap_roughness.glsl")
env.RD_GLSL("cubemap_downsampler.glsl")
env.RD_GLSL("cubemap_filter.glsl")
env.RD_GLSL("scene_high_end.glsl")
env.RD_GLSL("scene_forward.glsl")
env.RD_GLSL("sky.glsl")
env.RD_GLSL("tonemap.glsl")
env.RD_GLSL("cube_to_dp.glsl")

View file

@ -4,7 +4,7 @@
VERSION_DEFINES
#include "scene_high_end_inc.glsl"
#include "scene_forward_inc.glsl"
/* INPUT ATTRIBS */
@ -296,7 +296,7 @@ VERTEX_SHADER_CODE
VERSION_DEFINES
#include "scene_high_end_inc.glsl"
#include "scene_forward_inc.glsl"
/* Varyings */
@ -1548,8 +1548,6 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3
out_spec += vec4(irr_light.rgb * blend, blend);
}
#endif //USE_FORWARD_GI
vec2 octahedron_wrap(vec2 v) {
vec2 signVal;
signVal.x = v.x >= 0.0 ? 1.0 : -1.0;
@ -1683,10 +1681,14 @@ void sdfgi_process(uint cascade, vec3 cascade_pos, vec3 cam_pos, vec3 cam_normal
}
}
#endif //USE_FORWARD_GI
#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
#ifndef MODE_RENDER_DEPTH
#ifndef LOW_END_MODE
vec4 volumetric_fog_process(vec2 screen_uv, float z) {
vec3 fog_pos = vec3(screen_uv, z * scene_data.volumetric_fog_inv_length);
if (fog_pos.z < 0.0) {
@ -1697,6 +1699,7 @@ vec4 volumetric_fog_process(vec2 screen_uv, float z) {
return texture(sampler3D(volumetric_fog_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), fog_pos);
}
#endif
vec4 fog_process(vec3 vertex) {
vec3 fog_color = scene_data.fog_light_color;
@ -2221,30 +2224,13 @@ FRAGMENT_SHADER_CODE
specular_light = spec_accum.rgb;
ambient_light = amb_accum.rgb;
}
#else
#elif !defined(LOW_END_MODE)
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { //use GI buffers
ivec2 coord;
if (scene_data.gi_upscale_for_msaa) {
/*
//find the closest depth to upscale from, based on neighbours
ivec2 base_coord = ivec2(gl_FragCoord.xy);
float z_dist = gl_FragCoord.z;
ivec2 closest_coord = base_coord;
float closest_z_dist = abs(texelFetch(sampler2D(depth_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), base_coord,0).r-z_dist);
for(int i=0;i<4;i++) {
const ivec2 neighbours[4]=ivec2[](ivec2(-1,0),ivec2(1,0),ivec2(0,-1),ivec2(0,1));
ivec2 neighbour_coord = base_coord + neighbours[i];
float neighbour_z_dist = abs(texelFetch(sampler2D(depth_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), neighbour_coord,0).r-z_dist);
if (neighbour_z_dist < closest_z_dist) {
closest_z_dist = neighbour_z_dist;
closest_coord = neighbour_coord;
}
}
*/
ivec2 base_coord = ivec2(gl_FragCoord.xy);
ivec2 closest_coord = base_coord;
float closest_ang = dot(normal, texelFetch(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), base_coord, 0).xyz * 2.0 - 1.0);
@ -2823,11 +2809,13 @@ FRAGMENT_SHADER_CODE
//ambient occlusion
#if defined(AO_USED)
#ifndef LOW_END_MODE
if (scene_data.ssao_enabled && scene_data.ssao_ao_affect > 0.0) {
float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r;
ao = mix(ao, min(ao, ssao), scene_data.ssao_ao_affect);
ao_light_affect = mix(ao_light_affect, max(ao_light_affect, scene_data.ssao_light_affect), scene_data.ssao_ao_affect);
}
#endif //LOW_END_MODE
ambient_light = mix(scene_data.ao_color.rgb, ambient_light, ao);
ao_light_affect = mix(1.0, ao, ao_light_affect);
@ -2835,6 +2823,7 @@ FRAGMENT_SHADER_CODE
diffuse_light = mix(scene_data.ao_color.rgb, diffuse_light, ao_light_affect);
#else
#ifndef LOW_END_MODE
if (scene_data.ssao_enabled) {
float ao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r;
ambient_light = mix(scene_data.ao_color.rgb, ambient_light, ao);
@ -2842,6 +2831,7 @@ FRAGMENT_SHADER_CODE
specular_light = mix(scene_data.ao_color.rgb, specular_light, ao_light_affect);
diffuse_light = mix(scene_data.ao_color.rgb, diffuse_light, ao_light_affect);
}
#endif //LOW_END_MODE
#endif // AO_USED
@ -2871,11 +2861,13 @@ FRAGMENT_SHADER_CODE
specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a);
}
#ifndef LOW_END_MODE
if (scene_data.volumetric_fog_enabled) {
vec4 fog = volumetric_fog_process(screen_uv, -vertex.z);
diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a);
specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a);
}
#endif // LOW_END_MODE
#if defined(CUSTOM_FOG_USED)
diffuse_buffer.rgb = mix(diffuse_buffer.rgb, custom_fog.rgb, custom_fog.a);
@ -2896,11 +2888,12 @@ FRAGMENT_SHADER_CODE
vec4 fog = fog_process(vertex);
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
}
#ifndef LOW_END_MODE
if (scene_data.volumetric_fog_enabled) {
vec4 fog = volumetric_fog_process(screen_uv, -vertex.z);
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
}
#endif
#if defined(CUSTOM_FOG_USED)
frag_color.rgb = mix(frag_color.rgb, custom_fog.rgb, custom_fog.a);

View file

@ -204,6 +204,8 @@ layout(set = 0, binding = 19, std430) restrict readonly buffer GlobalVariableDat
}
global_variables;
#ifndef LOW_END_MODE
struct SDFGIProbeCascadeData {
vec3 position;
float to_probe;
@ -239,6 +241,8 @@ layout(set = 0, binding = 20, std140) uniform SDFGI {
}
sdfgi;
#endif //LOW_END_MODE
// decal atlas
/* Set 1, Radiance */
@ -255,20 +259,22 @@ layout(set = 1, binding = 0) uniform textureCube radiance_cubemap;
/* Set 2, Reflection and Shadow Atlases (view dependent) */
layout(set = 2, binding = 0) uniform textureCubeArray reflection_atlas;
layout(set = 1, binding = 1) uniform textureCubeArray reflection_atlas;
layout(set = 2, binding = 1) uniform texture2D shadow_atlas;
layout(set = 1, binding = 2) uniform texture2D shadow_atlas;
layout(set = 2, binding = 2) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
#ifndef LOW_END_MODE
layout(set = 1, binding = 3) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
#endif
/* Set 3, Render Buffers */
#ifdef MODE_RENDER_SDF
layout(r16ui, set = 3, binding = 0) uniform restrict writeonly uimage3D albedo_volume_grid;
layout(r32ui, set = 3, binding = 1) uniform restrict writeonly uimage3D emission_grid;
layout(r32ui, set = 3, binding = 2) uniform restrict writeonly uimage3D emission_aniso_grid;
layout(r32ui, set = 3, binding = 3) uniform restrict uimage3D geom_facing_grid;
layout(r16ui, set = 1, binding = 4) uniform restrict writeonly uimage3D albedo_volume_grid;
layout(r32ui, set = 1, binding = 5) uniform restrict writeonly uimage3D emission_grid;
layout(r32ui, set = 1, binding = 6) uniform restrict writeonly uimage3D emission_aniso_grid;
layout(r32ui, set = 1, binding = 7) uniform restrict uimage3D geom_facing_grid;
//still need to be present for shaders that use it, so remap them to something
#define depth_buffer shadow_atlas
@ -277,14 +283,17 @@ layout(r32ui, set = 3, binding = 3) uniform restrict uimage3D geom_facing_grid;
#else
layout(set = 3, binding = 0) uniform texture2D depth_buffer;
layout(set = 3, binding = 1) uniform texture2D color_buffer;
layout(set = 3, binding = 2) uniform texture2D normal_roughness_buffer;
layout(set = 3, binding = 4) uniform texture2D ao_buffer;
layout(set = 3, binding = 5) uniform texture2D ambient_buffer;
layout(set = 3, binding = 6) uniform texture2D reflection_buffer;
layout(set = 3, binding = 7) uniform texture2DArray sdfgi_lightprobe_texture;
layout(set = 3, binding = 8) uniform texture3D sdfgi_occlusion_cascades;
layout(set = 1, binding = 4) uniform texture2D depth_buffer;
layout(set = 1, binding = 5) uniform texture2D color_buffer;
#ifndef LOW_END_MODE
layout(set = 1, binding = 6) uniform texture2D normal_roughness_buffer;
layout(set = 1, binding = 7) uniform texture2D ao_buffer;
layout(set = 1, binding = 8) uniform texture2D ambient_buffer;
layout(set = 1, binding = 9) uniform texture2D reflection_buffer;
layout(set = 1, binding = 10) uniform texture2DArray sdfgi_lightprobe_texture;
layout(set = 1, binding = 11) uniform texture3D sdfgi_occlusion_cascades;
struct GIProbeData {
mat4 xform;
@ -302,18 +311,20 @@ struct GIProbeData {
uint mipmaps;
};
layout(set = 3, binding = 9, std140) uniform GIProbes {
layout(set = 1, binding = 12, std140) uniform GIProbes {
GIProbeData data[MAX_GI_PROBES];
}
gi_probes;
layout(set = 3, binding = 10) uniform texture3D volumetric_fog_texture;
layout(set = 1, binding = 13) uniform texture3D volumetric_fog_texture;
#endif // LOW_END_MODE
#endif
/* Set 4 Skeleton & Instancing (Multimesh) */
layout(set = 4, binding = 0, std430) restrict readonly buffer Transforms {
layout(set = 2, binding = 0, std430) restrict readonly buffer Transforms {
vec4 data[];
}
transforms;

View file

@ -260,6 +260,8 @@ public:
virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) = 0;
virtual bool is_low_end() const = 0;
virtual void update() = 0;
virtual ~RendererSceneRender() {}
};

View file

@ -2268,6 +2268,9 @@ RenderingServer::RenderingServer() {
GLOBAL_DEF("rendering/quality/2d_shadow_atlas/size", 2048);
GLOBAL_DEF("rendering/quality/rd_renderer/use_low_end_renderer", false);
GLOBAL_DEF("rendering/quality/rd_renderer/use_low_end_renderer.mobile", true);
GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096);
GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384"));