Better GIProbe quality settings.

This commit is contained in:
Juan Linietsky 2019-10-03 20:15:38 -03:00
parent fa548b052e
commit 965185c765
8 changed files with 83 additions and 56 deletions

View file

@ -4684,46 +4684,7 @@ Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint
} }
_buffer_memory_barrier(buffer->buffer, p_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, p_sync_with_draw); _buffer_memory_barrier(buffer->buffer, p_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, p_sync_with_draw);
#if 0
if (p_sync_with_draw) {
VkMemoryBarrier memoryBarrier;
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.pNext = NULL;
memoryBarrier.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT |
VK_ACCESS_INDEX_READ_BIT |
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
VK_ACCESS_UNIFORM_READ_BIT |
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
VK_ACCESS_SHADER_READ_BIT |
VK_ACCESS_SHADER_WRITE_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_TRANSFER_READ_BIT |
VK_ACCESS_TRANSFER_WRITE_BIT |
VK_ACCESS_HOST_READ_BIT |
VK_ACCESS_HOST_WRITE_BIT;
memoryBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT |
VK_ACCESS_INDEX_READ_BIT |
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
VK_ACCESS_UNIFORM_READ_BIT |
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
VK_ACCESS_SHADER_READ_BIT |
VK_ACCESS_SHADER_WRITE_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_TRANSFER_READ_BIT |
VK_ACCESS_TRANSFER_WRITE_BIT |
VK_ACCESS_HOST_READ_BIT |
VK_ACCESS_HOST_WRITE_BIT;
vkCmdPipelineBarrier(p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 1, &memoryBarrier, 0, NULL, 0, NULL);
}
#endif
return err; return err;
} }
@ -6902,6 +6863,44 @@ void RenderingDeviceVulkan::capture_timestamp(const String &p_name, bool p_sync_
ERR_FAIL_COND(frames[frame].timestamp_count >= max_timestamp_query_elements); ERR_FAIL_COND(frames[frame].timestamp_count >= max_timestamp_query_elements);
{
VkMemoryBarrier memoryBarrier;
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.pNext = NULL;
memoryBarrier.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT |
VK_ACCESS_INDEX_READ_BIT |
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
VK_ACCESS_UNIFORM_READ_BIT |
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
VK_ACCESS_SHADER_READ_BIT |
VK_ACCESS_SHADER_WRITE_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_TRANSFER_READ_BIT |
VK_ACCESS_TRANSFER_WRITE_BIT |
VK_ACCESS_HOST_READ_BIT |
VK_ACCESS_HOST_WRITE_BIT;
memoryBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT |
VK_ACCESS_INDEX_READ_BIT |
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
VK_ACCESS_UNIFORM_READ_BIT |
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
VK_ACCESS_SHADER_READ_BIT |
VK_ACCESS_SHADER_WRITE_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_TRANSFER_READ_BIT |
VK_ACCESS_TRANSFER_WRITE_BIT |
VK_ACCESS_HOST_READ_BIT |
VK_ACCESS_HOST_WRITE_BIT;
vkCmdPipelineBarrier(p_sync_to_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 1, &memoryBarrier, 0, NULL, 0, NULL);
}
vkCmdWriteTimestamp(p_sync_to_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, frames[frame].timestamp_pool, frames[frame].timestamp_count); vkCmdWriteTimestamp(p_sync_to_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, frames[frame].timestamp_pool, frames[frame].timestamp_count);
frames[frame].timestamp_names[frames[frame].timestamp_count] = p_name; frames[frame].timestamp_names[frames[frame].timestamp_count] = p_name;
frames[frame].timestamp_cpu_values[frames[frame].timestamp_count] = OS::get_singleton()->get_ticks_usec(); frames[frame].timestamp_cpu_values[frames[frame].timestamp_count] = OS::get_singleton()->get_ticks_usec();
@ -6918,7 +6917,7 @@ uint64_t RenderingDeviceVulkan::get_captured_timestamps_frame() const {
uint64_t RenderingDeviceVulkan::get_captured_timestamp_gpu_time(uint32_t p_index) const { uint64_t RenderingDeviceVulkan::get_captured_timestamp_gpu_time(uint32_t p_index) const {
ERR_FAIL_INDEX_V(p_index, frames[frame].timestamp_result_count, 0); ERR_FAIL_INDEX_V(p_index, frames[frame].timestamp_result_count, 0);
return frames[frame].timestamp_result_values[p_index]; return frames[frame].timestamp_result_values[p_index] * limits.timestampPeriod;
} }
uint64_t RenderingDeviceVulkan::get_captured_timestamp_cpu_time(uint32_t p_index) const { uint64_t RenderingDeviceVulkan::get_captured_timestamp_cpu_time(uint32_t p_index) const {
ERR_FAIL_INDEX_V(p_index, frames[frame].timestamp_result_count, 0); ERR_FAIL_INDEX_V(p_index, frames[frame].timestamp_result_count, 0);

View file

@ -629,6 +629,11 @@ public:
Color get_default_clear_color() const { Color get_default_clear_color() const {
return default_clear_color; return default_clear_color;
} }
#define TIMESTAMP_BEGIN() \
{ \
if (VSG::storage->capturing_timestamps) VSG::storage->capture_timestamps_begin(); \
}
#define RENDER_TIMESTAMP(m_text) \ #define RENDER_TIMESTAMP(m_text) \
{ \ { \
if (VSG::storage->capturing_timestamps) VSG::storage->capture_timestamp(m_text); \ if (VSG::storage->capturing_timestamps) VSG::storage->capture_timestamp(m_text); \

View file

@ -1866,8 +1866,6 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
} }
} }
RENDER_TIMESTAMP("Render Opaque Pass");
_setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), radiance_cubemap, p_shadow_atlas, p_reflection_atlas); _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), radiance_cubemap, p_shadow_atlas, p_reflection_atlas);
render_list.sort_by_key(false); render_list.sort_by_key(false);
@ -1880,11 +1878,13 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
bool depth_pre_pass = depth_framebuffer.is_valid(); bool depth_pre_pass = depth_framebuffer.is_valid();
if (depth_pre_pass) { //depth pre pass 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); 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);
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(depth_framebuffer), render_list.elements, render_list.element_count, false, PASS_MODE_DEPTH, render_buffer == nullptr); _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(depth_framebuffer), render_list.elements, render_list.element_count, false, PASS_MODE_DEPTH, render_buffer == nullptr);
RD::get_singleton()->draw_list_end(); RD::get_singleton()->draw_list_end();
} }
RENDER_TIMESTAMP("Render Opaque Pass");
{ {
bool will_continue = (can_continue || draw_sky || debug_giprobes); bool will_continue = (can_continue || draw_sky || debug_giprobes);
@ -2365,9 +2365,13 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
slot_count *= 3; slot_count *= 3;
defines += "\n#define GI_PROBE_USE_ANISOTROPY\n"; defines += "\n#define GI_PROBE_USE_ANISOTROPY\n";
} }
if (gi_probe_is_high_quality()) {
if (gi_probe_get_quality() == GIPROBE_QUALITY_ULTRA_LOW) {
defines += "\n#define GI_PROBE_LOW_QUALITY\n";
} else if (gi_probe_get_quality() == GIPROBE_QUALITY_HIGH) {
defines += "\n#define GI_PROBE_HIGH_QUALITY\n"; defines += "\n#define GI_PROBE_HIGH_QUALITY\n";
} }
defines += "\n#define MAX_GI_PROBE_TEXTURES " + itos(slot_count) + "\n"; defines += "\n#define MAX_GI_PROBE_TEXTURES " + itos(slot_count) + "\n";
uint32_t giprobe_buffer_size; uint32_t giprobe_buffer_size;

View file

@ -1558,7 +1558,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, const Vector<RID> &p_light_
} }
gi_probe->last_probe_version = storage->gi_probe_get_version(gi_probe->probe); gi_probe->last_probe_version = storage->gi_probe_get_version(gi_probe->probe);
print_line("update GI");
} }
void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, float p_alpha) { void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, float p_alpha) {
@ -1651,8 +1650,8 @@ void RasterizerSceneRD::gi_probe_slots_make_not_dirty() {
gi_probe_slots_dirty = false; gi_probe_slots_dirty = false;
} }
bool RasterizerSceneRD::gi_probe_is_high_quality() const { RasterizerSceneRD::GIProbeQuality RasterizerSceneRD::gi_probe_get_quality() const {
return gi_probe_use_6_cones; return gi_probe_quality;
} }
//////////////////////////////// ////////////////////////////////
@ -1958,7 +1957,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
gi_probe_lights_uniform = RD::get_singleton()->uniform_buffer_create(gi_probe_max_lights * sizeof(GIProbeLight)); gi_probe_lights_uniform = RD::get_singleton()->uniform_buffer_create(gi_probe_max_lights * sizeof(GIProbeLight));
gi_probe_use_anisotropy = GLOBAL_GET("rendering/quality/gi_probes/anisotropic"); gi_probe_use_anisotropy = GLOBAL_GET("rendering/quality/gi_probes/anisotropic");
gi_probe_use_6_cones = GLOBAL_GET("rendering/quality/gi_probes/high_quality"); gi_probe_quality = GIProbeQuality(CLAMP(int(GLOBAL_GET("rendering/quality/gi_probes/quality")), 0, 2));
if (textures_per_stage <= 16) { if (textures_per_stage <= 16) {
gi_probe_slots.resize(2); //thats all you can get gi_probe_slots.resize(2); //thats all you can get

View file

@ -9,6 +9,13 @@
#include "servers/visual/rendering_device.h" #include "servers/visual/rendering_device.h"
class RasterizerSceneRD : public RasterizerScene { class RasterizerSceneRD : public RasterizerScene {
public:
enum GIProbeQuality {
GIPROBE_QUALITY_ULTRA_LOW,
GIPROBE_QUALITY_MEDIUM,
GIPROBE_QUALITY_HIGH,
};
protected: protected:
struct RenderBufferData { struct RenderBufferData {
@ -182,7 +189,7 @@ private:
RID gi_probe_lights_uniform; RID gi_probe_lights_uniform;
bool gi_probe_use_anisotropy = false; bool gi_probe_use_anisotropy = false;
bool gi_probe_use_6_cones = false; GIProbeQuality gi_probe_quality = GIPROBE_QUALITY_MEDIUM;
bool gi_probe_slots_dirty = true; bool gi_probe_slots_dirty = true;
Vector<RID> gi_probe_slots; Vector<RID> gi_probe_slots;
@ -709,7 +716,7 @@ public:
_FORCE_INLINE_ bool gi_probe_is_anisotropic() const { _FORCE_INLINE_ bool gi_probe_is_anisotropic() const {
return gi_probe_use_anisotropy; return gi_probe_use_anisotropy;
} }
bool gi_probe_is_high_quality() const; GIProbeQuality gi_probe_get_quality() const;
RID render_buffers_create(); RID render_buffers_create();
void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, VS::ViewportMSAA p_msaa); void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, VS::ViewportMSAA p_msaa);

View file

@ -887,7 +887,7 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal,float roughness
reflection_accum += reflection; reflection_accum += reflection;
} }
#ifndef USE_LIGHTMAP #if !defined(USE_LIGHTMAP) && !defined(USE_VOXEL_CONE_TRACING)
if (reflections.data[ref_index].ambient.a > 0.0) { //compute ambient using skybox if (reflections.data[ref_index].ambient.a > 0.0) { //compute ambient using skybox
vec3 local_amb_vec = (reflections.data[ref_index].local_matrix * vec4(normal, 0.0)).xyz; vec3 local_amb_vec = (reflections.data[ref_index].local_matrix * vec4(normal, 0.0)).xyz;
@ -915,7 +915,7 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal,float roughness
ambient_out.rgb *= ambient_out.a; ambient_out.rgb *= ambient_out.a;
ambient_accum += ambient_out; ambient_accum += ambient_out;
} }
#endif //USE_LIGHTMAP #endif //USE_LIGHTMAP or VCT
} }
#ifdef USE_VOXEL_CONE_TRACING #ifdef USE_VOXEL_CONE_TRACING
@ -1103,6 +1103,7 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal,vec3 ref_vec, mat3
vec3 cell_size = 1.0 / gi_probes.data[index].bounds; vec3 cell_size = 1.0 / gi_probes.data[index].bounds;
//radiance //radiance
#ifdef GI_PROBE_HIGH_QUALITY #ifdef GI_PROBE_HIGH_QUALITY
#define MAX_CONE_DIRS 6 #define MAX_CONE_DIRS 6
@ -1116,7 +1117,17 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal,vec3 ref_vec, mat3
float cone_weights[MAX_CONE_DIRS] = float[](0.25, 0.15, 0.15, 0.15, 0.15, 0.15); float cone_weights[MAX_CONE_DIRS] = float[](0.25, 0.15, 0.15, 0.15, 0.15, 0.15);
float cone_angle_tan = 0.577; float cone_angle_tan = 0.577;
#else
#elif defined(GI_PROBE_LOW_QUALITY)
#define MAX_CONE_DIRS 1
vec3 cone_dirs[MAX_CONE_DIRS] = vec3[](
vec3(0.0, 0.0, 1.0));
float cone_weights[MAX_CONE_DIRS] = float[](1.0);
float cone_angle_tan = 4; //~76 degrees
#else // MEDIUM QUALITY
#define MAX_CONE_DIRS 4 #define MAX_CONE_DIRS 4
@ -1136,7 +1147,7 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal,vec3 ref_vec, mat3
vec3 dir = normalize((gi_probes.data[index].xform * vec4(normal_xform * cone_dirs[i], 0.0)).xyz); vec3 dir = normalize((gi_probes.data[index].xform * vec4(normal_xform * cone_dirs[i], 0.0)).xyz);
#ifdef GI_PROBE_HIGH_QUALITY #if defined(GI_PROBE_HIGH_QUALITY) || defined(GI_PROBE_LOW_QUALITY)
#ifdef GI_PROBE_USE_ANISOTROPY #ifdef GI_PROBE_USE_ANISOTROPY
vec4 cone_light = voxel_cone_trace_anisotropic(gi_probe_textures[gi_probes.data[index].texture_slot],gi_probe_textures[gi_probes.data[index].texture_slot+1],gi_probe_textures[gi_probes.data[index].texture_slot+2],normalize(mix(dir,normal,gi_probes.data[index].anisotropy_strength)),cell_size, position, dir, cone_angle_tan, max_distance, gi_probes.data[index].bias); vec4 cone_light = voxel_cone_trace_anisotropic(gi_probe_textures[gi_probes.data[index].texture_slot],gi_probe_textures[gi_probes.data[index].texture_slot+1],gi_probe_textures[gi_probes.data[index].texture_slot+2],normalize(mix(dir,normal,gi_probes.data[index].anisotropy_strength)),cell_size, position, dir, cone_angle_tan, max_distance, gi_probes.data[index].bias);
@ -1164,7 +1175,7 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal,vec3 ref_vec, mat3
out_diff += vec4(light * blend, blend); out_diff += vec4(light * blend, blend);
//irradiance //irradiance
#ifndef GI_PROBE_LOW_QUALITY
vec4 irr_light = voxel_cone_trace(gi_probe_textures[gi_probes.data[index].texture_slot], cell_size, position, ref_vec, tan(roughness * 0.5 * M_PI * 0.99), max_distance, gi_probes.data[index].bias); vec4 irr_light = voxel_cone_trace(gi_probe_textures[gi_probes.data[index].texture_slot], cell_size, position, ref_vec, tan(roughness * 0.5 * M_PI * 0.99), max_distance, gi_probes.data[index].bias);
if (gi_probes.data[index].blend_ambient) { if (gi_probes.data[index].blend_ambient) {
irr_light.rgb = mix(environment,irr_light.rgb, min(1.0, irr_light.a / 0.95)); irr_light.rgb = mix(environment,irr_light.rgb, min(1.0, irr_light.a / 0.95));
@ -1173,6 +1184,7 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal,vec3 ref_vec, mat3
//irr_light=vec3(0.0); //irr_light=vec3(0.0);
out_spec += vec4(irr_light.rgb * blend, blend); out_spec += vec4(irr_light.rgb * blend, blend);
#endif
} }
#endif //USE_VOXEL_CONE_TRACING #endif //USE_VOXEL_CONE_TRACING

View file

@ -103,7 +103,7 @@ void VisualServerRaster::draw(bool p_swap_buffers, double frame_step) {
VSG::rasterizer->begin_frame(frame_step); VSG::rasterizer->begin_frame(frame_step);
VSG::storage->capture_timestamps_begin(); TIMESTAMP_BEGIN()
VSG::scene_render->update(); //update scenes stuff before updating instances VSG::scene_render->update(); //update scenes stuff before updating instances

View file

@ -2303,7 +2303,8 @@ VisualServer::VisualServer() {
GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_count", 64); GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_count", 64);
GLOBAL_DEF("rendering/quality/gi_probes/anisotropic", false); GLOBAL_DEF("rendering/quality/gi_probes/anisotropic", false);
GLOBAL_DEF("rendering/quality/gi_probes/high_quality", false); GLOBAL_DEF("rendering/quality/gi_probes/quality", 1);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/gi_probes/quality", PropertyInfo(Variant::INT, "rendering/quality/gi_probes/quality", PROPERTY_HINT_ENUM, "Ultra-Low (1 cone),Medium (4 cones), High (6 cones)"));
GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false); GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false);
GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true); GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true);