summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/image.cpp13
-rw-r--r--core/image.h8
-rw-r--r--core/math/vector3i.h2
-rw-r--r--drivers/png/png_driver_common.cpp1
-rw-r--r--drivers/png/resource_saver_png.cpp9
-rw-r--r--drivers/png/resource_saver_png.h1
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp58
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h1
-rw-r--r--editor/plugins/gi_probe_editor_plugin.cpp74
-rw-r--r--editor/plugins/gi_probe_editor_plugin.h7
-rw-r--r--scene/3d/gi_probe.cpp59
-rw-r--r--scene/3d/gi_probe.h1
-rw-r--r--scene/3d/mesh_instance.cpp1
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp9
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp1
-rw-r--r--servers/visual/rasterizer_rd/shaders/scene_forward.glsl2
-rw-r--r--servers/visual/visual_server_scene.cpp5
17 files changed, 234 insertions, 18 deletions
diff --git a/core/image.cpp b/core/image.cpp
index 7e7c8d1607..f2d78168f6 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -87,6 +87,8 @@ const char *Image::format_names[Image::FORMAT_MAX] = {
SavePNGFunc Image::save_png_func = NULL;
SaveEXRFunc Image::save_exr_func = NULL;
+SavePNGBufferFunc Image::save_png_buffer_func = NULL;
+
void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel) {
uint32_t ofs = (p_y * width + p_x) * p_pixelsize;
@@ -901,6 +903,7 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
ERR_FAIL_COND_MSG(p_height <= 0, "Image height must be greater than 0.");
ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, "Image width cannot be greater than " + itos(MAX_WIDTH) + ".");
ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, "Image height cannot be greater than " + itos(MAX_HEIGHT) + ".");
+ ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS, "Too many pixels for image, maximum is " + itos(MAX_PIXELS));
if (p_width == width && p_height == height)
return;
@@ -1593,6 +1596,7 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma
ERR_FAIL_INDEX(p_width - 1, MAX_WIDTH);
ERR_FAIL_INDEX(p_height - 1, MAX_HEIGHT);
+ ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS, "Too many pixels for image, maximum is " + itos(MAX_PIXELS));
int mm = 0;
int size = _get_dst_image_size(p_width, p_height, p_format, mm, p_use_mipmaps ? -1 : 0);
@@ -1612,6 +1616,7 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma
ERR_FAIL_INDEX(p_width - 1, MAX_WIDTH);
ERR_FAIL_INDEX(p_height - 1, MAX_HEIGHT);
+ ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS, "Too many pixels for image, maximum is " + itos(MAX_PIXELS));
int mm;
int size = _get_dst_image_size(p_width, p_height, p_format, mm, p_use_mipmaps ? -1 : 0);
@@ -1910,6 +1915,14 @@ Error Image::save_png(const String &p_path) const {
return save_png_func(p_path, Ref<Image>((Image *)this));
}
+PoolVector<uint8_t> Image::save_png_to_buffer() const {
+ if (save_png_buffer_func == NULL) {
+ return PoolVector<uint8_t>();
+ }
+
+ return save_png_buffer_func(Ref<Image>((Image *)this));
+}
+
Error Image::save_exr(const String &p_path, bool p_grayscale) const {
if (save_exr_func == NULL)
diff --git a/core/image.h b/core/image.h
index cf1ebfad9f..2f8b7fbe9c 100644
--- a/core/image.h
+++ b/core/image.h
@@ -47,6 +47,7 @@
class Image;
typedef Error (*SavePNGFunc)(const String &p_path, const Ref<Image> &p_img);
+typedef PoolVector<uint8_t> (*SavePNGBufferFunc)(const Ref<Image> &p_img);
typedef Ref<Image> (*ImageMemLoadFunc)(const uint8_t *p_png, int p_size);
typedef Error (*SaveEXRFunc)(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
@@ -57,10 +58,12 @@ class Image : public Resource {
public:
static SavePNGFunc save_png_func;
static SaveEXRFunc save_exr_func;
+ static SavePNGBufferFunc save_png_buffer_func;
enum {
- MAX_WIDTH = 16384, // force a limit somehow
- MAX_HEIGHT = 16384 // force a limit somehow
+ MAX_WIDTH = (1 << 24), // force a limit somehow
+ MAX_HEIGHT = (1 << 24), // force a limit somehow
+ MAX_PIXELS = 268435456
};
enum Format {
@@ -265,6 +268,7 @@ public:
Error load(const String &p_path);
Error save_png(const String &p_path) const;
+ PoolVector<uint8_t> save_png_to_buffer() const;
Error save_exr(const String &p_path, bool p_grayscale) const;
/**
diff --git a/core/math/vector3i.h b/core/math/vector3i.h
index cb2e2bdd2d..dac713502d 100644
--- a/core/math/vector3i.h
+++ b/core/math/vector3i.h
@@ -183,7 +183,7 @@ bool Vector3i::operator==(const Vector3i &p_v) const {
bool Vector3i::operator!=(const Vector3i &p_v) const {
- return (x != p_v.x || y == p_v.y || z == p_v.z);
+ return (x != p_v.x || y != p_v.y || z != p_v.z);
}
bool Vector3i::operator<(const Vector3i &p_v) const {
diff --git a/drivers/png/png_driver_common.cpp b/drivers/png/png_driver_common.cpp
index f4dbf135bb..750d00eb59 100644
--- a/drivers/png/png_driver_common.cpp
+++ b/drivers/png/png_driver_common.cpp
@@ -114,6 +114,7 @@ Error png_to_image(const uint8_t *p_source, size_t p_size, Ref<Image> p_image) {
ERR_FAIL_COND_V_MSG(check_error(png_img), ERR_FILE_CORRUPT, png_img.message);
ERR_FAIL_COND_V(!success, ERR_FILE_CORRUPT);
+ //print_line("png width: "+itos(png_img.width)+" height: "+itos(png_img.height));
p_image->create(png_img.width, png_img.height, 0, dest_format, buffer);
return OK;
diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp
index b15a84d3b9..566bfbcc1d 100644
--- a/drivers/png/resource_saver_png.cpp
+++ b/drivers/png/resource_saver_png.cpp
@@ -71,6 +71,14 @@ Error ResourceSaverPNG::save_image(const String &p_path, const Ref<Image> &p_img
return OK;
}
+PoolVector<uint8_t> ResourceSaverPNG::save_image_to_buffer(const Ref<Image> &p_img) {
+
+ PoolVector<uint8_t> buffer;
+ Error err = PNGDriverCommon::image_to_png(p_img, buffer);
+ ERR_FAIL_COND_V_MSG(err, PoolVector<uint8_t>(), "Can't convert image to PNG.");
+ return buffer;
+}
+
bool ResourceSaverPNG::recognize(const RES &p_resource) const {
return (p_resource.is_valid() && p_resource->is_class("ImageTexture"));
@@ -86,4 +94,5 @@ void ResourceSaverPNG::get_recognized_extensions(const RES &p_resource, List<Str
ResourceSaverPNG::ResourceSaverPNG() {
Image::save_png_func = &save_image;
+ Image::save_png_buffer_func = &save_image_to_buffer;
};
diff --git a/drivers/png/resource_saver_png.h b/drivers/png/resource_saver_png.h
index 6eb1db2004..2cac20991a 100644
--- a/drivers/png/resource_saver_png.h
+++ b/drivers/png/resource_saver_png.h
@@ -37,6 +37,7 @@
class ResourceSaverPNG : public ResourceFormatSaver {
public:
static Error save_image(const String &p_path, const Ref<Image> &p_img);
+ static PoolVector<uint8_t> save_image_to_buffer(const Ref<Image> &p_img);
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
virtual bool recognize(const RES &p_resource) const;
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index cc538593b5..98b1bc1115 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -36,6 +36,8 @@
#include "drivers/vulkan/vulkan_context.h"
#include "thirdparty/spirv-reflect/spirv_reflect.h"
+//#define FORCE_FULL_BARRIER
+
void RenderingDeviceVulkan::_add_dependency(RID p_id, RID p_depends_on) {
if (!dependency_map.has(p_depends_on)) {
@@ -1499,6 +1501,42 @@ void RenderingDeviceVulkan::_memory_barrier(VkPipelineStageFlags p_src_stage_mas
vkCmdPipelineBarrier(p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, p_src_stage_mask, p_dst_stage_mask, 0, 1, &mem_barrier, 0, NULL, 0, NULL);
}
+void RenderingDeviceVulkan::_full_barrier(bool p_sync_with_draw) {
+ //used for debug
+ _memory_barrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+ 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,
+ 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,
+ p_sync_with_draw);
+}
+
void RenderingDeviceVulkan::_buffer_memory_barrier(VkBuffer buffer, uint64_t p_from, uint64_t p_size, VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_sccess, bool p_sync_with_draw) {
VkBufferMemoryBarrier buffer_mem_barrier;
@@ -4643,7 +4681,11 @@ 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);
-
+#ifdef FORCE_FULL_BARRIER
+ _full_barrier(p_sync_with_draw);
+#else
+ _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);
+#endif
return err;
}
@@ -6038,7 +6080,12 @@ void RenderingDeviceVulkan::draw_list_end() {
// To ensure proper synchronization, we must make sure rendering is done before:
// * Some buffer is copied
// * Another render pass happens (since we may be done
+
+#ifdef FORCE_FULL_BARRIER
+ _full_barrier(true);
+#else
_memory_barrier(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, true);
+#endif
}
/***********************/
@@ -6298,7 +6345,11 @@ void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t
}
void RenderingDeviceVulkan::compute_list_add_barrier(ComputeListID p_list) {
+#ifdef FORCE_FULL_BARRIER
+ _full_barrier(true);
+#else
_memory_barrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, true);
+#endif
}
void RenderingDeviceVulkan::compute_list_end() {
@@ -6330,8 +6381,11 @@ void RenderingDeviceVulkan::compute_list_end() {
memdelete(compute_list);
compute_list = NULL;
-
+#ifdef FORCE_FULL_BARRIER
+ _full_barrier(true);
+#else
_memory_barrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT, true);
+#endif
}
#if 0
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index 0dc3cc702b..3c387a7d52 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -216,6 +216,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
Error _buffer_free(Buffer *p_buffer);
Error _buffer_update(Buffer *p_buffer, size_t p_offset, const uint8_t *p_data, size_t p_data_size, bool p_use_draw_command_buffer = false, uint32_t p_required_align = 32);
+ void _full_barrier(bool p_sync_with_draw);
void _memory_barrier(VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_sccess, bool p_sync_with_draw);
void _buffer_memory_barrier(VkBuffer buffer, uint64_t p_from, uint64_t p_size, VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_sccess, bool p_sync_with_draw);
diff --git a/editor/plugins/gi_probe_editor_plugin.cpp b/editor/plugins/gi_probe_editor_plugin.cpp
index 8914e0ed01..429d13990e 100644
--- a/editor/plugins/gi_probe_editor_plugin.cpp
+++ b/editor/plugins/gi_probe_editor_plugin.cpp
@@ -33,6 +33,18 @@
void GIProbeEditorPlugin::_bake() {
if (gi_probe) {
+ if (gi_probe->get_probe_data().is_null()) {
+ String path = get_tree()->get_edited_scene_root()->get_filename();
+ if (path==String()) {
+ path="res://"+gi_probe->get_name()+"_data.res";
+ } else {
+ String ext = path.get_extension();
+ path = path.get_basename()+"."+gi_probe->get_name()+"_data.res";
+ }
+ probe_file->set_current_path(path);
+ probe_file->popup_centered_ratio();
+ return;
+ }
gi_probe->bake();
}
}
@@ -51,13 +63,42 @@ bool GIProbeEditorPlugin::handles(Object *p_object) const {
return p_object->is_class("GIProbe");
}
+void GIProbeEditorPlugin::_notification(int p_what) {
+
+ if (p_what==NOTIFICATION_PROCESS) {
+ if (!gi_probe) {
+ return;
+ }
+
+ String text;
+
+ Vector3i size = gi_probe->get_estimated_cell_size();
+ text = itos(size.x)+", "+itos(size.y)+", "+itos(size.z);
+ int data_size = 4;
+ if (GLOBAL_GET("rendering/quality/gi_probes/anisotropic")) {
+ data_size+=4;
+ }
+ text += " - VRAM Size: " + String::num(size.x*size.y*size.z*data_size/(1024.0*1024.0),2)+" Mb.";
+
+ if (bake_info->get_text()==text) {
+ return;
+ }
+
+ bake_info->add_color_override("font_color", bake_info->get_color("success_color", "Editor"));
+
+ bake_info->set_text(text);
+ }
+}
+
void GIProbeEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
- bake->show();
+ bake_hb->show();
+ set_process(true);
} else {
- bake->hide();
+ bake_hb->hide();
+ set_process(false);
}
}
@@ -82,21 +123,46 @@ void GIProbeEditorPlugin::bake_func_end() {
tmp_progress = NULL;
}
+void GIProbeEditorPlugin::_giprobe_save_path_and_bake(const String& p_path) {
+ probe_file->hide();
+ if (gi_probe) {
+ gi_probe->bake();
+ ERR_FAIL_COND( gi_probe->get_probe_data().is_null() );
+ ResourceSaver::save(p_path,gi_probe->get_probe_data(),ResourceSaver::FLAG_CHANGE_PATH);
+ }
+}
+
void GIProbeEditorPlugin::_bind_methods() {
ClassDB::bind_method("_bake", &GIProbeEditorPlugin::_bake);
+ ClassDB::bind_method("_giprobe_save_path_and_bake", &GIProbeEditorPlugin::_giprobe_save_path_and_bake);
+
}
GIProbeEditorPlugin::GIProbeEditorPlugin(EditorNode *p_node) {
editor = p_node;
+ bake_hb = memnew( HBoxContainer );
+ bake_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ bake_hb->hide();
bake = memnew(ToolButton);
bake->set_icon(editor->get_gui_base()->get_icon("Bake", "EditorIcons"));
bake->set_text(TTR("Bake GI Probe"));
- bake->hide();
bake->connect("pressed", this, "_bake");
- add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, bake);
+ bake_hb->add_child(bake);
+ bake_info = memnew( Label );
+ bake_info->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ bake_info->set_clip_text(true);
+ bake_hb->add_child(bake_info);
+
+ add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, bake_hb);
gi_probe = NULL;
+ probe_file = memnew( EditorFileDialog );
+ probe_file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
+ probe_file->add_filter("*.res");
+ probe_file->connect("file_selected",this,"_giprobe_save_path_and_bake");
+ get_editor_interface()->get_base_control()->add_child(probe_file);
+ probe_file->set_title(TTR("Select path for GIProbe Data File"));
GIProbe::bake_begin_function = bake_func_begin;
GIProbe::bake_step_function = bake_func_step;
diff --git a/editor/plugins/gi_probe_editor_plugin.h b/editor/plugins/gi_probe_editor_plugin.h
index 5db682835d..63b14ca15a 100644
--- a/editor/plugins/gi_probe_editor_plugin.h
+++ b/editor/plugins/gi_probe_editor_plugin.h
@@ -42,18 +42,25 @@ class GIProbeEditorPlugin : public EditorPlugin {
GIProbe *gi_probe;
+ HBoxContainer *bake_hb;
+ Label *bake_info;
ToolButton *bake;
EditorNode *editor;
+ EditorFileDialog *probe_file;
+
static EditorProgress *tmp_progress;
static void bake_func_begin(int p_steps);
static void bake_func_step(int p_step, const String &p_description);
static void bake_func_end();
void _bake();
+ void _giprobe_save_path_and_bake(const String& p_path);
+
protected:
static void _bind_methods();
+ void _notification(int p_what);
public:
virtual String get_name() const { return "GIProbe"; }
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index 404185f3e7..8d343f03b6 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -41,7 +41,7 @@ void GIProbeData::_set_data(const Dictionary &p_data) {
ERR_FAIL_COND(!p_data.has("octree_size"));
ERR_FAIL_COND(!p_data.has("octree_cells"));
ERR_FAIL_COND(!p_data.has("octree_data"));
- ERR_FAIL_COND(!p_data.has("octree_df"));
+ ERR_FAIL_COND(!p_data.has("octree_df") && !p_data.has("octree_df_png"));
ERR_FAIL_COND(!p_data.has("level_counts"));
ERR_FAIL_COND(!p_data.has("to_cell_xform"));
@@ -49,7 +49,19 @@ void GIProbeData::_set_data(const Dictionary &p_data) {
Vector3 octree_size = p_data["octree_size"];
PoolVector<uint8_t> octree_cells = p_data["octree_cells"];
PoolVector<uint8_t> octree_data = p_data["octree_data"];
- PoolVector<uint8_t> octree_df = p_data["octree_df"];
+
+ PoolVector<uint8_t> octree_df;
+ if (p_data.has("octree_df")) {
+ octree_df = p_data["octree_df"];
+ } else if (p_data.has("octree_df_png")) {
+ PoolVector<uint8_t> octree_df_png = p_data["octree_df_png"];
+ Ref<Image> img;
+ img.instance();
+ Error err = img->load_png_from_buffer(octree_df_png);
+ ERR_FAIL_COND(err != OK);
+ ERR_FAIL_COND(img->get_format() != Image::FORMAT_L8);
+ octree_df = img->get_data();
+ }
PoolVector<int> octree_levels = p_data["level_counts"];
Transform to_cell_xform = p_data["to_cell_xform"];
@@ -59,10 +71,21 @@ void GIProbeData::_set_data(const Dictionary &p_data) {
Dictionary GIProbeData::_get_data() const {
Dictionary d;
d["bounds"] = get_bounds();
- d["octree_size"] = get_octree_size();
+ Vector3i otsize = get_octree_size();
+ d["octree_size"] = Vector3(otsize);
d["octree_cells"] = get_octree_cells();
d["octree_data"] = get_data_cells();
- d["octree_df"] = get_distance_field();
+ if (otsize != Vector3i()) {
+ Ref<Image> img;
+ img.instance();
+ img->create(otsize.x * otsize.y, otsize.z, false, Image::FORMAT_L8, get_distance_field());
+ PoolVector<uint8_t> df_png = img->save_png_to_buffer();
+ ERR_FAIL_COND_V(df_png.size() == 0, Dictionary());
+ d["octree_df_png"] = df_png;
+ } else {
+ d["octree_df"] = PoolVector<uint8_t>();
+ }
+
d["level_counts"] = get_level_counts();
d["to_cell_xform"] = get_to_cell_xform();
return d;
@@ -384,6 +407,32 @@ GIProbe::BakeBeginFunc GIProbe::bake_begin_function = NULL;
GIProbe::BakeStepFunc GIProbe::bake_step_function = NULL;
GIProbe::BakeEndFunc GIProbe::bake_end_function = NULL;
+Vector3i GIProbe::get_estimated_cell_size() const {
+ static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 };
+ int cell_subdiv = subdiv_value[subdiv];
+ int axis_cell_size[3];
+ AABB bounds = AABB(-extents, extents * 2.0);
+ int longest_axis = bounds.get_longest_axis_index();
+ axis_cell_size[longest_axis] = 1 << cell_subdiv;
+
+
+ for (int i = 0; i < 3; i++) {
+
+ if (i == longest_axis)
+ continue;
+
+ axis_cell_size[i] = axis_cell_size[longest_axis];
+ float axis_size = bounds.size[longest_axis];
+
+ //shrink until fit subdiv
+ while (axis_size / 2.0 >= bounds.size[i]) {
+ axis_size /= 2.0;
+ axis_cell_size[i] >>= 1;
+ }
+ }
+
+ return Vector3i(axis_cell_size[0],axis_cell_size[1],axis_cell_size[2]);
+}
void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 };
@@ -458,6 +507,8 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
if (bake_end_function) {
bake_end_function();
}
+
+ _change_notify(); //bake property may have changed
}
void GIProbe::_debug_bake() {
diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h
index ac309e82c7..efb526b435 100644
--- a/scene/3d/gi_probe.h
+++ b/scene/3d/gi_probe.h
@@ -159,6 +159,7 @@ public:
void set_extents(const Vector3 &p_extents);
Vector3 get_extents() const;
+ Vector3i get_estimated_cell_size() const;
void bake(Node *p_from_node = NULL, bool p_create_visual_debug = false);
diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp
index 4731210768..08290fe6c3 100644
--- a/scene/3d/mesh_instance.cpp
+++ b/scene/3d/mesh_instance.cpp
@@ -409,6 +409,7 @@ void MeshInstance::_bind_methods() {
ClassDB::set_method_flags("MeshInstance", "create_debug_tangents", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
+ ADD_GROUP("Skeleton", "");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skin", PROPERTY_HINT_RESOURCE_TYPE, "Skin"), "set_skin", "get_skin");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton"), "set_skeleton_path", "get_skeleton_path");
}
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp
index 279cb88660..d57c62b629 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp
@@ -2363,11 +2363,14 @@ void RasterizerSceneForwardRD::_setup_render_pass_uniform_set(RID p_depth_buffer
RD::Uniform u;
u.binding = 6;
u.type = RD::UNIFORM_TYPE_TEXTURE;
+ RID texture;
if (p_shadow_atlas.is_valid()) {
- u.ids.push_back(shadow_atlas_get_texture(p_shadow_atlas));
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
+ texture = shadow_atlas_get_texture(p_shadow_atlas);
}
+ if (!texture.is_valid()) {
+ texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE);
+ }
+ u.ids.push_back(texture);
uniforms.push_back(u);
}
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
index b2e90c7f59..05624e5279 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
@@ -2334,6 +2334,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
}
} else {
//render shadow
+
_render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip);
//copy to atlas
diff --git a/servers/visual/rasterizer_rd/shaders/scene_forward.glsl b/servers/visual/rasterizer_rd/shaders/scene_forward.glsl
index 8c122e6fcb..f567970e4a 100644
--- a/servers/visual/rasterizer_rd/shaders/scene_forward.glsl
+++ b/servers/visual/rasterizer_rd/shaders/scene_forward.glsl
@@ -266,7 +266,7 @@ VERTEX_SHADER_CODE
#else
float z_ofs = scene_data.z_offset;
- z_ofs += (1.0 - abs(normal_interp.z)) * scene_data.z_slope_scale;
+ z_ofs += max(0.0,1.0 - abs(normalize(normal_interp).z)) * scene_data.z_slope_scale;
vertex_interp.z -= z_ofs;
#endif
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 1ce4f47d75..61e6755ee2 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -851,7 +851,7 @@ void VisualServerScene::instance_geometry_set_flag(RID p_instance, VS::InstanceF
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
- ERR_FAIL_COND(((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK));
+ //ERR_FAIL_COND(((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK));
switch (p_flags) {
@@ -2526,6 +2526,9 @@ void VisualServerScene::render_probes() {
for (List<InstanceGIProbeData::PairInfo>::Element *E = probe->dynamic_geometries.front(); E; E = E->next()) {
if (instance_cull_count < MAX_INSTANCE_CULL) {
Instance *ins = E->get().geometry;
+ if (!ins->visible) {
+ continue;
+ }
InstanceGeometryData *geom = (InstanceGeometryData *)ins->base_data;
if (geom->gi_probes_dirty) {