mirror of
https://github.com/godotengine/godot.git
synced 2024-11-10 14:12:51 +00:00
Several fixes to GIProbes
This commit is contained in:
parent
971ce680f2
commit
da0457fa29
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"; }
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user