diff options
Diffstat (limited to 'servers/rendering')
68 files changed, 2111 insertions, 2502 deletions
diff --git a/servers/rendering/rasterizer.cpp b/servers/rendering/rasterizer.cpp index f62e0a43a6..566a14b655 100644 --- a/servers/rendering/rasterizer.cpp +++ b/servers/rendering/rasterizer.cpp @@ -40,6 +40,7 @@ void RasterizerScene::InstanceDependency::instance_notify_changed(bool p_aabb, b E->key()->dependency_changed(p_aabb, p_dependencies); } } + void RasterizerScene::InstanceDependency::instance_notify_deleted(RID p_deleted) { for (Map<InstanceBase *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { E->key()->dependency_deleted(p_deleted); @@ -63,7 +64,6 @@ RasterizerScene::InstanceDependency::~InstanceDependency() { } Rasterizer *Rasterizer::create() { - return _create_func(); } @@ -72,6 +72,5 @@ RasterizerCanvas *RasterizerCanvas::singleton = nullptr; RasterizerStorage *RasterizerStorage::base_singleton = nullptr; RasterizerStorage::RasterizerStorage() { - base_singleton = this; } diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h index 099e155553..e0d4432fd5 100644 --- a/servers/rendering/rasterizer.h +++ b/servers/rendering/rasterizer.h @@ -38,7 +38,6 @@ #include "core/self_list.h" class RasterizerScene { - public: /* SHADOW ATLAS API */ @@ -57,6 +56,7 @@ public: virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0; virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0; virtual void sky_set_material(RID p_sky, RID p_material) = 0; + virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0; /* ENVIRONMENT API */ @@ -94,6 +94,8 @@ public: virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0; virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0; + virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0; + virtual bool is_environment(RID p_env) const = 0; virtual RS::EnvironmentBG environment_get_background(RID p_env) const = 0; virtual int environment_get_canvas_max_layer(RID p_env) const = 0; @@ -160,9 +162,11 @@ public: SelfList<InstanceBase> dependency_item; - InstanceBase *lightmap_capture; - RID lightmap; - Vector<Color> lightmap_capture_data; //in a array (12 values) to avoid wasting space if unused. Alpha is unused, but needed to send to shader + InstanceBase *lightmap; + Rect2 lightmap_uv_scale; + int lightmap_slice_index; + uint32_t lightmap_cull_index; + Vector<Color> lightmap_sh; //spherical harmonic AABB aabb; AABB transformed_aabb; @@ -178,8 +182,8 @@ public: bool instance_allocated_shader_parameters = false; int32_t instance_allocated_shader_parameters_offset = -1; - virtual void dependency_deleted(RID p_dependency) = 0; - virtual void dependency_changed(bool p_aabb, bool p_dependencies) = 0; + virtual void dependency_deleted(RID p_dependency) {} + virtual void dependency_changed(bool p_aabb, bool p_dependencies) {} Set<InstanceDependency *> dependencies; @@ -222,7 +226,6 @@ public: InstanceBase() : dependency_item(this) { - base_type = RS::INSTANCE_NONE; cast_shadows = RS::SHADOW_CASTING_SETTING_ON; receive_shadows = true; @@ -233,7 +236,9 @@ public: baked_light = false; dynamic_gi = false; redraw_if_visible = false; - lightmap_capture = nullptr; + lightmap_slice_index = 0; + lightmap = nullptr; + lightmap_cull_index = 0; } virtual ~InstanceBase() { @@ -268,7 +273,7 @@ public: virtual bool gi_probe_needs_update(RID p_probe) const = 0; virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) = 0; - virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_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) = 0; + virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_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) = 0; virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) = 0; virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0; @@ -286,6 +291,8 @@ public: virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) = 0; virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) = 0; + virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0; + virtual bool free(RID p_rid) = 0; virtual void update() = 0; @@ -293,7 +300,6 @@ public: }; class RasterizerStorage { - Color default_clear_color; public: @@ -311,7 +317,7 @@ public: //these two APIs can be used together or in combination with the others. virtual RID texture_2d_placeholder_create() = 0; - virtual RID texture_2d_layered_placeholder_create() = 0; + virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) = 0; virtual RID texture_3d_placeholder_create() = 0; virtual Ref<Image> texture_2d_get(RID p_texture) const = 0; @@ -593,29 +599,21 @@ public: /* LIGHTMAP CAPTURE */ - struct LightmapCaptureOctree { - - enum { - CHILD_EMPTY = 0xFFFFFFFF - }; - - uint16_t light[6][3]; //anisotropic light - float alpha; - uint32_t children[8]; - }; - - virtual RID lightmap_capture_create() = 0; - virtual void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) = 0; - virtual AABB lightmap_capture_get_bounds(RID p_capture) const = 0; - virtual void lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) = 0; - virtual Vector<uint8_t> lightmap_capture_get_octree(RID p_capture) const = 0; - virtual void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) = 0; - virtual Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const = 0; - virtual void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) = 0; - virtual int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const = 0; - virtual void lightmap_capture_set_energy(RID p_capture, float p_energy) = 0; - virtual float lightmap_capture_get_energy(RID p_capture) const = 0; - virtual const Vector<LightmapCaptureOctree> *lightmap_capture_get_octree_ptr(RID p_capture) const = 0; + virtual RID lightmap_create() = 0; + + virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) = 0; + virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) = 0; + virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) = 0; + virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) = 0; + virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const = 0; + virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const = 0; + virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const = 0; + virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const = 0; + virtual AABB lightmap_get_aabb(RID p_lightmap) const = 0; + virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) = 0; + virtual bool lightmap_is_interior(RID p_lightmap) const = 0; + virtual void lightmap_set_probe_capture_update_speed(float p_speed) = 0; + virtual float lightmap_get_probe_capture_update_speed() const = 0; /* PARTICLES */ @@ -762,7 +760,6 @@ public: }; struct Light { - bool enabled; Color color; Transform2D xform; @@ -841,7 +838,6 @@ public: struct Item; struct TextureBinding { - TextureBindingID binding_id; _FORCE_INLINE_ void create(RS::CanvasItemTextureFilter p_item_filter, RS::CanvasItemTextureRepeat p_item_repeat, RID p_texture, RID p_normalmap, RID p_specular, RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat, RID p_multimesh) { @@ -859,8 +855,9 @@ public: _FORCE_INLINE_ TextureBinding() { binding_id = 0; } _FORCE_INLINE_ ~TextureBinding() { - if (binding_id) + if (binding_id) { singleton->free_texture_binding(binding_id); + } } }; @@ -870,7 +867,6 @@ public: //also easier to wrap to avoid mistakes struct Polygon { - PolygonID polygon_id; Rect2 rect_cache; @@ -889,15 +885,15 @@ public: _FORCE_INLINE_ Polygon() { polygon_id = 0; } _FORCE_INLINE_ ~Polygon() { - if (polygon_id) + if (polygon_id) { singleton->free_polygon(polygon_id); + } } }; //item struct Item { - //commands are allocated in blocks of 4k to improve performance //and cache coherence. //blocks always grow but never shrink. @@ -911,7 +907,6 @@ public: }; struct Command { - enum Type { TYPE_RECT, @@ -931,7 +926,6 @@ public: }; struct CommandRect : public Command { - Rect2 rect; Color modulate; Rect2 source; @@ -947,7 +941,6 @@ public: }; struct CommandNinePatch : public Command { - Rect2 rect; Rect2 source; float margin[4]; @@ -964,7 +957,6 @@ public: }; struct CommandPolygon : public Command { - RS::PrimitiveType primitive; Polygon polygon; Color specular_shininess; @@ -975,7 +967,6 @@ public: }; struct CommandPrimitive : public Command { - uint32_t point_count; Vector2 points[4]; Vector2 uvs[4]; @@ -988,7 +979,6 @@ public: }; struct CommandMesh : public Command { - RID mesh; Transform2D transform; Color modulate; @@ -998,7 +988,6 @@ public: }; struct CommandMultiMesh : public Command { - RID multimesh; Color specular_shininess; TextureBinding texture_binding; @@ -1006,7 +995,6 @@ public: }; struct CommandParticles : public Command { - RID particles; Color specular_shininess; TextureBinding texture_binding; @@ -1014,13 +1002,11 @@ public: }; struct CommandTransform : public Command { - Transform2D xform; CommandTransform() { type = TYPE_TRANSFORM; } }; struct CommandClipIgnore : public Command { - bool ignore; CommandClipIgnore() { type = TYPE_CLIP_IGNORE; @@ -1070,13 +1056,13 @@ public: Rect2 global_rect_cache; const Rect2 &get_rect() const { - if (custom_rect || (!rect_dirty && !update_when_visible)) + if (custom_rect || (!rect_dirty && !update_when_visible)) { return rect; + } //must update rect if (commands == nullptr) { - rect = Rect2(); rect_dirty = false; return rect; @@ -1089,29 +1075,24 @@ public: const Item::Command *c = commands; while (c) { - Rect2 r; switch (c->type) { case Item::Command::TYPE_RECT: { - const Item::CommandRect *crect = static_cast<const Item::CommandRect *>(c); r = crect->rect; } break; case Item::Command::TYPE_NINEPATCH: { - const Item::CommandNinePatch *style = static_cast<const Item::CommandNinePatch *>(c); r = style->rect; } break; case Item::Command::TYPE_POLYGON: { - const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c); r = polygon->polygon.rect_cache; } break; case Item::Command::TYPE_PRIMITIVE: { - const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c); for (uint32_t j = 0; j < primitive->point_count; j++) { if (j == 0) { @@ -1122,7 +1103,6 @@ public: } } break; case Item::Command::TYPE_MESH: { - const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c); AABB aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, RID()); @@ -1130,7 +1110,6 @@ public: } break; case Item::Command::TYPE_MULTIMESH: { - const Item::CommandMultiMesh *multimesh = static_cast<const Item::CommandMultiMesh *>(c); AABB aabb = RasterizerStorage::base_singleton->multimesh_get_aabb(multimesh->multimesh); @@ -1138,7 +1117,6 @@ public: } break; case Item::Command::TYPE_PARTICLES: { - const Item::CommandParticles *particles_cmd = static_cast<const Item::CommandParticles *>(c); if (particles_cmd->particles.is_valid()) { AABB aabb = RasterizerStorage::base_singleton->particles_get_aabb(particles_cmd->particles); @@ -1147,7 +1125,6 @@ public: } break; case Item::Command::TYPE_TRANSFORM: { - const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c); xf = transform->xform; found_xform = true; @@ -1230,7 +1207,6 @@ public: } struct CustomData { - virtual ~CustomData() {} }; @@ -1292,8 +1268,9 @@ public: for (int i = 0; i < blocks.size(); i++) { memfree(blocks[i].memory); } - if (copy_back_buffer) + if (copy_back_buffer) { memdelete(copy_back_buffer); + } if (custom_data) { memdelete(custom_data); } @@ -1304,7 +1281,6 @@ public: virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) = 0; struct LightOccluderInstance { - bool enabled; RID canvas; RID polygon; @@ -1370,6 +1346,8 @@ public: virtual void end_frame(bool p_swap_buffers) = 0; virtual void finalize() = 0; + virtual uint64_t get_frame_number() const = 0; + virtual float get_frame_delta_time() const = 0; virtual bool is_low_end() const = 0; diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.cpp b/servers/rendering/rasterizer_rd/light_cluster_builder.cpp index f75308a975..efb48e6df7 100644 --- a/servers/rendering/rasterizer_rd/light_cluster_builder.cpp +++ b/servers/rendering/rasterizer_rd/light_cluster_builder.cpp @@ -45,7 +45,6 @@ void LightClusterBuilder::begin(const Transform &p_view_transform, const CameraM } void LightClusterBuilder::bake_cluster() { - float slice_depth = (z_near - z_far) / depth; uint8_t *cluster_dataw = cluster_data.ptrw(); @@ -56,7 +55,6 @@ void LightClusterBuilder::bake_cluster() { /* Step 1, create cell positions and count them */ for (uint32_t i = 0; i < item_count; i++) { - const Item &item = items[i]; int from_slice = Math::floor((z_near - (item.aabb.position.z + item.aabb.size.z)) / slice_depth); @@ -70,7 +68,6 @@ void LightClusterBuilder::bake_cluster() { to_slice = MIN((int)depth - 1, to_slice); for (int j = from_slice; j <= to_slice; j++) { - Vector3 min = item.aabb.position; Vector3 max = item.aabb.position + item.aabb.size; @@ -126,7 +123,6 @@ void LightClusterBuilder::bake_cluster() { sort_id_max = nearest_power_of_2_templated(sort_id_max + 1); sort_ids = (SortID *)memrealloc(sort_ids, sizeof(SortID) * sort_id_max); if (ids.size()) { - ids.resize(sort_id_max); RD::get_singleton()->free(items_buffer); items_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * sort_id_max); @@ -178,7 +174,6 @@ void LightClusterBuilder::bake_cluster() { } void LightClusterBuilder::setup(uint32_t p_width, uint32_t p_height, uint32_t p_depth) { - if (width == p_width && height == p_height && depth == p_depth) { return; } @@ -208,6 +203,7 @@ void LightClusterBuilder::setup(uint32_t p_width, uint32_t p_height, uint32_t p_ RID LightClusterBuilder::get_cluster_texture() const { return cluster_texture; } + RID LightClusterBuilder::get_cluster_indices_buffer() const { return items_buffer; } @@ -231,8 +227,8 @@ LightClusterBuilder::LightClusterBuilder() { items_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 1024); item_max = 1024; } -LightClusterBuilder::~LightClusterBuilder() { +LightClusterBuilder::~LightClusterBuilder() { if (cluster_data.size()) { RD::get_singleton()->free(cluster_texture); } diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.h b/servers/rendering/rasterizer_rd/light_cluster_builder.h index 78288dc620..b1da083dad 100644 --- a/servers/rendering/rasterizer_rd/light_cluster_builder.h +++ b/servers/rendering/rasterizer_rd/light_cluster_builder.h @@ -170,7 +170,6 @@ public: _add_item(aabb, ITEM_TYPE_OMNI_LIGHT, light_count); } break; case LIGHT_TYPE_SPOT: { - float r = ld.radius; real_t len = Math::tan(Math::deg2rad(ld.spot_aperture)) * r; @@ -187,7 +186,6 @@ public: } _FORCE_INLINE_ void add_reflection_probe(const Transform &p_transform, const Vector3 &p_half_extents) { - if (unlikely(refprobe_count == refprobe_max)) { refprobe_max = nearest_power_of_2_templated(refprobe_max + 1); refprobes = (OrientedBoxData *)memrealloc(refprobes, sizeof(OrientedBoxData) * refprobe_max); @@ -233,7 +231,6 @@ public: } _FORCE_INLINE_ void add_decal(const Transform &p_transform, const Vector3 &p_half_extents) { - if (unlikely(decal_count == decal_max)) { decal_max = nearest_power_of_2_templated(decal_max + 1); decals = (OrientedBoxData *)memrealloc(decals, sizeof(OrientedBoxData) * decal_max); diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp index 956bf54d01..4c477ca5f4 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp @@ -34,7 +34,6 @@ #include "rasterizer_rd.h" void RasterizerCanvasRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) { - p_mat4[0] = p_transform.elements[0][0]; p_mat4[1] = p_transform.elements[0][1]; p_mat4[2] = 0; @@ -54,7 +53,6 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat4(const Transform2D &p_trans } void RasterizerCanvasRD::_update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4) { - p_mat2x4[0] = p_transform.elements[0][0]; p_mat2x4[1] = p_transform.elements[1][0]; p_mat2x4[2] = 0; @@ -67,7 +65,6 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat2x4(const Transform2D &p_tra } void RasterizerCanvasRD::_update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3) { - p_mat2x3[0] = p_transform.elements[0][0]; p_mat2x3[1] = p_transform.elements[0][1]; p_mat2x3[2] = p_transform.elements[1][0]; @@ -77,7 +74,6 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat2x3(const Transform2D &p_tra } void RasterizerCanvasRD::_update_transform_to_mat4(const Transform &p_transform, float *p_mat4) { - p_mat4[0] = p_transform.basis.elements[0][0]; p_mat4[1] = p_transform.basis.elements[1][0]; p_mat4[2] = p_transform.basis.elements[2][0]; @@ -97,7 +93,6 @@ void RasterizerCanvasRD::_update_transform_to_mat4(const Transform &p_transform, } void RasterizerCanvasRD::_update_specular_shininess(const Color &p_transform, uint32_t *r_ss) { - *r_ss = uint32_t(CLAMP(p_transform.a * 255.0, 0, 255)) << 24; *r_ss |= uint32_t(CLAMP(p_transform.b * 255.0, 0, 255)) << 16; *r_ss |= uint32_t(CLAMP(p_transform.g * 255.0, 0, 255)) << 8; @@ -105,7 +100,6 @@ void RasterizerCanvasRD::_update_specular_shininess(const Color &p_transform, ui } RID RasterizerCanvasRD::_create_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat, RID p_multimesh) { - Vector<RD::Uniform> uniform_set; { // COLOR TEXTURE @@ -169,7 +163,6 @@ RID RasterizerCanvasRD::_create_texture_binding(RID p_texture, RID p_normalmap, } RasterizerCanvas::TextureBindingID RasterizerCanvasRD::request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat, RID p_multimesh) { - if (p_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) { p_filter = default_samplers.default_filter; } @@ -221,7 +214,6 @@ RasterizerCanvas::TextureBindingID RasterizerCanvasRD::request_texture_binding(R } void RasterizerCanvasRD::free_texture_binding(TextureBindingID p_binding) { - TextureBinding **binding_ptr = bindings.texture_bindings.getptr(p_binding); ERR_FAIL_COND(!binding_ptr); TextureBinding *binding = *binding_ptr; @@ -233,7 +225,6 @@ void RasterizerCanvasRD::free_texture_binding(TextureBindingID p_binding) { } void RasterizerCanvasRD::_dispose_bindings() { - while (bindings.to_dispose_list.first()) { TextureBinding *binding = bindings.to_dispose_list.first()->self(); if (binding->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(binding->uniform_set)) { @@ -248,7 +239,6 @@ void RasterizerCanvasRD::_dispose_bindings() { } RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights) { - // Care must be taken to generate array formats // in ways where they could be reused, so we will // put single-occuring elements first, and repeated @@ -384,7 +374,6 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int const float *weight_ptr = p_weights.ptr(); for (uint32_t i = 0; i < vertex_count; i++) { - uint16_t *bone16w = (uint16_t *)&uptr[base_offset + i * stride]; uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride + 2]; @@ -450,7 +439,6 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int } void RasterizerCanvasRD::free_polygon(PolygonID p_polygon) { - PolygonBuffers *pb_ptr = polygon_buffers.polygons.getptr(p_polygon); ERR_FAIL_COND(!pb_ptr); @@ -470,7 +458,6 @@ void RasterizerCanvasRD::free_polygon(PolygonID p_polygon) { } Size2i RasterizerCanvasRD::_bind_texture_binding(TextureBindingID p_binding, RD::DrawListID p_draw_list, uint32_t &flags) { - TextureBinding **texture_binding_ptr = bindings.texture_bindings.getptr(p_binding); ERR_FAIL_COND_V(!texture_binding_ptr, Size2i()); TextureBinding *texture_binding = *texture_binding_ptr; @@ -498,7 +485,6 @@ Size2i RasterizerCanvasRD::_bind_texture_binding(TextureBindingID p_binding, RD: //////////////////// void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants) { - //create an empty push constant PushConstant push_constant; @@ -541,13 +527,10 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ PipelineLightMode light_mode; { - Light *light = p_lights; while (light) { - if (light->render_index_cache >= 0 && p_item->light_mask & light->item_mask && p_item->z_final >= light->z_min && p_item->z_final <= light->z_max && p_item->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) { - uint32_t light_index = light->render_index_cache; push_constant.lights[light_count >> 2] |= light_index << ((light_count & 3) * 8); @@ -575,7 +558,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } { - RID &canvas_item_state = light_count ? state_data->state_uniform_set_with_light : state_data->state_uniform_set; bool invalid_uniform = canvas_item_state.is_valid() && !RD::get_singleton()->uniform_set_is_valid(canvas_item_state); @@ -640,7 +622,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } { - RD::Uniform u_lights; u_lights.type = RD::UNIFORM_TYPE_TEXTURE; u_lights.binding = 4; @@ -652,7 +633,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ //lights for (uint32_t i = 0; i < state.max_lights_per_item; i++) { if (i < light_count) { - CanvasLight *cl = canvas_light_owner.getornull(light_cache[i]->light_internal); ERR_CONTINUE(!cl); @@ -711,7 +691,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ switch (c->type) { case Item::Command::TYPE_RECT: { - const Item::CommandRect *rect = static_cast<const Item::CommandRect *>(c); //bind pipeline @@ -811,7 +790,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } break; case Item::Command::TYPE_NINEPATCH: { - const Item::CommandNinePatch *np = static_cast<const Item::CommandNinePatch *>(c); //bind pipeline @@ -839,12 +817,10 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ Rect2 dst_rect(np->rect.position.x, np->rect.position.y, np->rect.size.x, np->rect.size.y); if (texpixel_size == Size2()) { - texpixel_size = Size2(1, 1); src_rect = Rect2(0, 0, 1, 1); } else { - if (np->source != Rect2()) { src_rect = Rect2(np->source.position.x * texpixel_size.width, np->source.position.y * texpixel_size.height, np->source.size.x * texpixel_size.width, np->source.size.y * texpixel_size.height); texpixel_size = Size2(1.0 / np->source.size.width, 1.0 / np->source.size.height); @@ -889,7 +865,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } break; case Item::Command::TYPE_POLYGON: { - const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c); PolygonBuffers *pb = polygon_buffers.polygons.getptr(polygon->polygon.polygon_id); @@ -945,7 +920,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } break; case Item::Command::TYPE_PRIMITIVE: { - const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c); //bind pipeline @@ -1291,23 +1265,18 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } break; #endif case Item::Command::TYPE_TRANSFORM: { - const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c); _update_transform_2d_to_mat2x3(base_transform * transform->xform, push_constant.world); } break; case Item::Command::TYPE_CLIP_IGNORE: { - const Item::CommandClipIgnore *ci = static_cast<const Item::CommandClipIgnore *>(c); if (current_clip) { - if (ci->ignore != reclip) { - if (ci->ignore) { RD::get_singleton()->draw_list_disable_scissor(p_draw_list); reclip = true; } else { - RD::get_singleton()->draw_list_enable_scissor(p_draw_list, current_clip->final_clip_rect); reclip = false; } @@ -1327,7 +1296,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, RID p_screen_uniform_set) { - Item *current_clip = nullptr; Transform2D canvas_transform_inverse = p_canvas_transform_inverse; @@ -1357,33 +1325,27 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, PipelineVariants *pipeline_variants = &shader.pipeline_variants; for (int i = 0; i < p_item_count; i++) { - Item *ci = items[i]; if (current_clip != ci->final_clip_owner) { - current_clip = ci->final_clip_owner; //setup clip if (current_clip) { - RD::get_singleton()->draw_list_enable_scissor(draw_list, current_clip->final_clip_rect); } else { - RD::get_singleton()->draw_list_disable_scissor(draw_list); } } if (ci->material != prev_material) { - MaterialData *material_data = nullptr; if (ci->material.is_valid()) { material_data = (MaterialData *)storage->material_get_data(ci->material, RasterizerStorageRD::SHADER_TYPE_2D); } if (material_data) { - if (material_data->shader_data->version.is_valid() && material_data->shader_data->valid) { pipeline_variants = &material_data->shader_data->pipeline_variants; if (material_data->uniform_set.is_valid()) { @@ -1406,7 +1368,6 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, } void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform) { - int item_count = 0; //setup canvas state uniforms if needed @@ -1447,12 +1408,10 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite //setup lights if exist { - Light *l = p_light_list; uint32_t index = 0; while (l) { - if (index == state.max_lights_per_render) { l->render_index_cache = -1; l = l->next_ptr; @@ -1513,7 +1472,6 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite RID screen_uniform_set; while (ci) { - if (ci->copy_back_buffer) { backbuffer_copy = true; @@ -1527,7 +1485,6 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite if (ci->material.is_valid()) { MaterialData *md = (MaterialData *)storage->material_get_data(ci->material, RasterizerStorageRD::SHADER_TYPE_2D); if (md && md->shader_data->valid) { - if (md->shader_data->uses_screen_texture) { if (!material_screen_texture_found) { backbuffer_copy = true; @@ -1539,8 +1496,8 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite } } - if (md->last_frame != RasterizerRD::get_frame_number()) { - md->last_frame = RasterizerRD::get_frame_number(); + if (md->last_frame != RasterizerRD::singleton->get_frame_number()) { + md->last_frame = RasterizerRD::singleton->get_frame_number(); if (!RD::get_singleton()->uniform_set_is_valid(md->uniform_set)) { // uniform set may be gone because a dependency was erased. In this case, it will happen // if a texture is deleted, so just re-create it. @@ -1574,7 +1531,6 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite } RID RasterizerCanvasRD::light_create() { - CanvasLight canvas_light; canvas_light.shadow.size = 0; return canvas_light_owner.make_rid(canvas_light); @@ -1589,6 +1545,7 @@ void RasterizerCanvasRD::light_set_texture(RID p_rid, RID p_texture) { cl->texture = p_texture; } + void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_resolution) { CanvasLight *cl = canvas_light_owner.getornull(p_rid); ERR_FAIL_COND(!cl); @@ -1598,7 +1555,6 @@ void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_re } if (cl->shadow.texture.is_valid()) { - RD::get_singleton()->free(cl->shadow.fb); RD::get_singleton()->free(cl->shadow.depth); RD::get_singleton()->free(cl->shadow.texture); @@ -1608,7 +1564,6 @@ void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_re } if (p_enable) { - Vector<RID> fb_textures; { //texture @@ -1641,12 +1596,10 @@ void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_re } void RasterizerCanvasRD::light_update_shadow(RID p_rid, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) { - CanvasLight *cl = canvas_light_owner.getornull(p_rid); ERR_FAIL_COND(cl->shadow.texture.is_null()); for (int i = 0; i < 4; i++) { - //make sure it remains orthogonal, makes easy to read angle later //light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1)); @@ -1691,11 +1644,9 @@ void RasterizerCanvasRD::light_update_shadow(RID p_rid, const Transform2D &p_lig LightOccluderInstance *instance = p_occluders; while (instance) { - OccluderPolygon *co = occluder_polygon_owner.getornull(instance->occluder); if (!co || co->index_array.is_null() || !(p_light_mask & instance->light_mask)) { - instance = instance->next; continue; } @@ -1717,7 +1668,6 @@ void RasterizerCanvasRD::light_update_shadow(RID p_rid, const Transform2D &p_lig } RID RasterizerCanvasRD::occluder_polygon_create() { - OccluderPolygon occluder; occluder.point_count = 0; occluder.cull_mode = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; @@ -1725,12 +1675,10 @@ RID RasterizerCanvasRD::occluder_polygon_create() { } void RasterizerCanvasRD::occluder_polygon_set_shape_as_lines(RID p_occluder, const Vector<Vector2> &p_lines) { - OccluderPolygon *oc = occluder_polygon_owner.getornull(p_occluder); ERR_FAIL_COND(!oc); if (oc->point_count != p_lines.size() && oc->vertex_array.is_valid()) { - RD::get_singleton()->free(oc->vertex_array); RD::get_singleton()->free(oc->vertex_buffer); RD::get_singleton()->free(oc->index_array); @@ -1743,7 +1691,6 @@ void RasterizerCanvasRD::occluder_polygon_set_shape_as_lines(RID p_occluder, con } if (p_lines.size()) { - Vector<uint8_t> geometry; Vector<uint8_t> indices; int lc = p_lines.size(); @@ -1762,7 +1709,6 @@ void RasterizerCanvasRD::occluder_polygon_set_shape_as_lines(RID p_occluder, con const int POLY_HEIGHT = 16384; for (int i = 0; i < lc / 2; i++) { - vwptr[i * 12 + 0] = lr[i * 2 + 0].x; vwptr[i * 12 + 1] = lr[i * 2 + 0].y; vwptr[i * 12 + 2] = POLY_HEIGHT; @@ -1813,6 +1759,7 @@ void RasterizerCanvasRD::occluder_polygon_set_shape_as_lines(RID p_occluder, con } } } + void RasterizerCanvasRD::occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) { OccluderPolygon *oc = occluder_polygon_owner.getornull(p_occluder); ERR_FAIL_COND(!oc); @@ -1895,12 +1842,10 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) { switch (blend_mode) { case BLEND_MODE_DISABLED: { - // nothing to do here, disabled by default } break; case BLEND_MODE_MIX: { - attachment.enable_blend = true; attachment.alpha_blend_op = RD::BLEND_OP_ADD; attachment.color_blend_op = RD::BLEND_OP_ADD; @@ -1911,7 +1856,6 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) { } break; case BLEND_MODE_ADD: { - attachment.enable_blend = true; attachment.alpha_blend_op = RD::BLEND_OP_ADD; attachment.color_blend_op = RD::BLEND_OP_ADD; @@ -1922,7 +1866,6 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) { } break; case BLEND_MODE_SUB: { - attachment.enable_blend = true; attachment.alpha_blend_op = RD::BLEND_OP_SUBTRACT; attachment.color_blend_op = RD::BLEND_OP_SUBTRACT; @@ -2014,12 +1957,11 @@ void RasterizerCanvasRD::ShaderData::set_default_texture_param(const StringName default_texture_params[p_name] = p_texture; } } -void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { Map<int, StringName> order; for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { continue; } @@ -2031,7 +1973,6 @@ void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_ } for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]); pi.name = E->get(); p_param_list->push_back(pi); @@ -2039,9 +1980,7 @@ void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_ } void RasterizerCanvasRD::ShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const { - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } @@ -2066,9 +2005,11 @@ bool RasterizerCanvasRD::ShaderData::is_param_texture(const StringName &p_param) bool RasterizerCanvasRD::ShaderData::is_animated() const { return false; } + bool RasterizerCanvasRD::ShaderData::casts_shadows() const { return false; } + Variant RasterizerCanvasRD::ShaderData::get_default_parameter(const StringName &p_parameter) const { if (uniforms.has(p_parameter)) { ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; @@ -2097,8 +2038,8 @@ RasterizerStorageRD::ShaderData *RasterizerCanvasRD::_create_shader_func() { ShaderData *shader_data = memnew(ShaderData); return shader_data; } -void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { +void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { RasterizerCanvasRD *canvas_singleton = (RasterizerCanvasRD *)RasterizerCanvas::singleton; if ((uint32_t)ubo_data.size() != shader_data->ubo_size) { @@ -2123,7 +2064,6 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V //check whether buffer changed if (p_uniform_dirty && ubo_data.size()) { - update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false); RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw()); } @@ -2142,7 +2082,6 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V } if (p_textures_dirty && tex_uniform_count) { - update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), false); } @@ -2201,6 +2140,7 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V uniform_set = RD::get_singleton()->uniform_set_create(uniforms, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), 1); } + RasterizerCanvasRD::MaterialData::~MaterialData() { if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) { RD::get_singleton()->free(uniform_set); @@ -2514,7 +2454,6 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { } bool RasterizerCanvasRD::free(RID p_rid) { - if (canvas_light_owner.owns(p_rid)) { CanvasLight *cl = canvas_light_owner.getornull(p_rid); ERR_FAIL_COND_V(!cl, false); @@ -2531,7 +2470,6 @@ bool RasterizerCanvasRD::free(RID p_rid) { } RasterizerCanvasRD::~RasterizerCanvasRD() { - //canvas state { @@ -2547,14 +2485,12 @@ RasterizerCanvasRD::~RasterizerCanvasRD() { //shadow rendering { - shadow_render.shader.version_free(shadow_render.shader_version); //this will also automatically clear all pipelines RD::get_singleton()->free(state.shadow_sampler); } //bindings { - free_texture_binding(bindings.default_empty); //dispose pending diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h index 4d47b3e13b..bfe4e61f47 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h @@ -40,7 +40,6 @@ #include "servers/rendering/rendering_device.h" class RasterizerCanvasRD : public RasterizerCanvas { - RasterizerStorageRD *storage; enum ShaderVariant { @@ -149,7 +148,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { } shader; struct ShaderData : public RasterizerStorageRD::ShaderData { - enum BlendMode { //used internally BLEND_MODE_MIX, BLEND_MODE_ADD, @@ -313,7 +311,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { /******************/ struct CanvasLight { - RID texture; struct { int size; @@ -333,7 +330,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { }; struct OccluderPolygon { - RS::CanvasOccluderPolygonCullMode cull_mode; int point_count; RID vertex_buffer; @@ -371,7 +367,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { //state that does not vary across rendering all items struct ItemStateData : public Item::CustomData { - struct LightCache { uint64_t light_version; Light *light; @@ -382,7 +377,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { RID state_uniform_set_with_light; RID state_uniform_set; ItemStateData() { - for (int i = 0; i < DEFAULT_MAX_LIGHTS_PER_ITEM; i++) { light_cache[i].light_version = 0; light_cache[i].light = nullptr; @@ -401,7 +395,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { }; struct State { - //state buffer struct Buffer { float canvas_transform[16]; @@ -489,7 +482,7 @@ public: void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform); - void canvas_debug_viewport_shadows(Light *p_lights_with_shadow){}; + void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {} void draw_window_margins(int *p_margins, RID *p_margin_textures) {} diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp index d469dd97ca..303cb7ad42 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp @@ -51,17 +51,14 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar } static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) { - for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - p_array[i * 4 + j] = p_mtx.matrix[i][j]; } } } RID RasterizerEffectsRD::_get_uniform_set_from_image(RID p_image) { - if (image_to_uniform_set_cache.has(p_image)) { RID uniform_set = image_to_uniform_set_cache[p_image]; if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) { @@ -83,7 +80,6 @@ RID RasterizerEffectsRD::_get_uniform_set_from_image(RID p_image) { } RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) { - if (texture_to_uniform_set_cache.has(p_texture)) { RID uniform_set = texture_to_uniform_set_cache[p_texture]; if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) { @@ -107,7 +103,6 @@ RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use } RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) { - if (texture_to_compute_uniform_set_cache.has(p_texture)) { RID uniform_set = texture_to_compute_uniform_set_cache[p_texture]; if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) { @@ -131,7 +126,6 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bo } RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_texture1, RID p_texture2, bool p_use_mipmaps) { - TexturePair tp; tp.texture1 = p_texture1; tp.texture2 = p_texture2; @@ -169,7 +163,6 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_textur } RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1, RID p_texture2) { - TexturePair tp; tp.texture1 = p_texture1; tp.texture2 = p_texture2; @@ -205,7 +198,6 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1 } void RasterizerEffectsRD::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y, bool p_panorama) { - zeromem(©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); copy_to_fb.push_constant.use_section = true; @@ -249,7 +241,6 @@ void RasterizerEffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_fr } void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst) { - zeromem(©.push_constant, sizeof(CopyPushConstant)); if (p_flip_y) { copy.push_constant.flags |= COPY_FLAG_FLIP_Y; @@ -282,8 +273,30 @@ void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_textu RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) { +void RasterizerEffectsRD::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array) { + zeromem(©.push_constant, sizeof(CopyPushConstant)); + + copy.push_constant.section[0] = 0; + copy.push_constant.section[1] = 0; + copy.push_constant.section[2] = p_panorama_size.width; + copy.push_constant.section[3] = p_panorama_size.height; + copy.push_constant.target[0] = 0; + copy.push_constant.target[1] = 0; + copy.push_constant.camera_z_far = p_lod; + + int32_t x_groups = (p_panorama_size.width - 1) / 8 + 1; + int32_t y_groups = (p_panorama_size.height - 1) / 8 + 1; + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_is_array ? COPY_MODE_CUBE_ARRAY_TO_PANORAMA : COPY_MODE_CUBE_TO_PANORAMA]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_cube), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_panorama), 3); + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_end(); +} + +void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) { zeromem(©.push_constant, sizeof(CopyPushConstant)); if (p_flip_y) { copy.push_constant.flags |= COPY_FLAG_FLIP_Y; @@ -311,7 +324,6 @@ void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_textu } void RasterizerEffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y) { - zeromem(©.push_constant, sizeof(CopyPushConstant)); if (p_flip_y) { copy.push_constant.flags |= COPY_FLAG_FLIP_Y; @@ -337,7 +349,6 @@ void RasterizerEffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest } void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst) { - zeromem(©.push_constant, sizeof(CopyPushConstant)); uint32_t base_flags = 0; @@ -373,7 +384,6 @@ void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, } void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) { - zeromem(©.push_constant, sizeof(CopyPushConstant)); CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW; @@ -425,7 +435,6 @@ void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture, } void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_roughness, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) { - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); int32_t x_groups = (p_screen_size.width - 1) / 8 + 1; @@ -454,7 +463,6 @@ void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, R } { - ssr.push_constant.camera_z_far = p_camera.get_z_far(); ssr.push_constant.camera_z_near = p_camera.get_z_near(); ssr.push_constant.orthogonal = p_camera.is_orthogonal(); @@ -494,7 +502,6 @@ void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, R } if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) { - //blurr RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -551,7 +558,6 @@ void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, R } void RasterizerEffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) { - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); int32_t x_groups = (p_screen_size.width - 1) / 8 + 1; @@ -598,11 +604,9 @@ void RasterizerEffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, } void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection) { - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>()); if (p_reflection.is_valid()) { - if (p_base.is_valid()) { RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_SSR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base), 2); @@ -614,7 +618,6 @@ void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_reflection), 1); } else { - if (p_base.is_valid()) { RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADD].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base), 2); @@ -631,7 +634,6 @@ void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, } void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) { - zeromem(©.push_constant, sizeof(CopyPushConstant)); copy.push_constant.section[0] = 0; @@ -652,7 +654,6 @@ void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_textur } void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) { - CopyToDPPushConstant push_constant; push_constant.screen_size[0] = p_rect.size.x; push_constant.screen_size[1] = p_rect.size.y; @@ -676,7 +677,6 @@ void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest } void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) { - zeromem(&tonemap.push_constant, sizeof(TonemapPushConstant)); tonemap.push_constant.use_bcs = p_settings.use_bcs; @@ -719,7 +719,6 @@ void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, } void RasterizerEffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) { - luminance_reduce.push_constant.source_size[0] = p_source_size.x; luminance_reduce.push_constant.source_size[1] = p_source_size.y; luminance_reduce.push_constant.max_luminance = p_max_luminance; @@ -729,12 +728,10 @@ void RasterizerEffectsRD::luminance_reduction(RID p_source_texture, const Size2i RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); for (int i = 0; i < p_reduce.size(); i++) { - if (i == 0) { RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, luminance_reduce.pipelines[LUMINANCE_REDUCE_READ]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_texture), 0); } else { - RD::get_singleton()->compute_list_add_barrier(compute_list); //needs barrier, wait until previous is done if (i == p_reduce.size() - 1 && !p_set) { @@ -764,7 +761,6 @@ void RasterizerEffectsRD::luminance_reduction(RID p_source_texture, const Size2i } void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_halfsize_texture1, RID p_halfsize_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RenderingServer::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal) { - bokeh.push_constant.blur_far_active = p_dof_far; bokeh.push_constant.blur_far_begin = p_dof_far_begin; bokeh.push_constant.blur_far_end = p_dof_far_begin + p_dof_far_size; @@ -807,7 +803,6 @@ void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, con RD::get_singleton()->compute_list_add_barrier(compute_list); if (p_bokeh_shape == RS::DOF_BOKEH_BOX || p_bokeh_shape == RS::DOF_BOKEH_HEXAGON) { - //second pass RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.pipelines[p_bokeh_shape == RS::DOF_BOKEH_BOX ? BOKEH_GEN_BOKEH_BOX : BOKEH_GEN_BOKEH_HEXAGONAL]); @@ -843,7 +838,6 @@ void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, con bokeh.push_constant.second_pass = true; if (p_quality == RS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == RS::DOF_BLUR_QUALITY_LOW) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_halfsize_texture2), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_halfsize_texture1), 1); } else { @@ -927,7 +921,6 @@ void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, con } void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, const Size2i &p_depth_buffer_size, RID p_depth_mipmaps_texture, const Vector<RID> &depth_mipmaps, RID p_ao1, bool p_half_size, RID p_ao2, RID p_upscale_buffer, float p_intensity, float p_radius, float p_bias, const CameraMatrix &p_projection, RS::EnvironmentSSAOQuality p_quality, RS::EnvironmentSSAOBlur p_blur, float p_edge_sharpness) { - //minify first ssao.minify_push_constant.orthogonal = p_projection.is_orthogonal(); ssao.minify_push_constant.z_near = p_projection.get_z_near(); @@ -943,7 +936,6 @@ void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, // Minify the depth buffer. for (int i = 0; i < depth_mipmaps.size(); i++) { - if (i == 0) { RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_MINIFY_FIRST]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_buffer), 0); @@ -1027,7 +1019,6 @@ void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, ssao.blur_push_constant.axis[1] = 0; if (p_blur != RS::ENV_SSAO_BLUR_DISABLED) { - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[p_half_size ? SSAO_BLUR_PASS_HALF : SSAO_BLUR_PASS]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao1), 0); if (p_half_size) { @@ -1083,7 +1074,6 @@ void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, } void RasterizerEffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve) { - roughness_limiter.push_constant.screen_size[0] = p_size.x; roughness_limiter.push_constant.screen_size[1] = p_size.y; roughness_limiter.push_constant.curve = p_curve; @@ -1104,7 +1094,6 @@ void RasterizerEffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, } void RasterizerEffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) { - zeromem(&roughness.push_constant, sizeof(CubemapRoughnessPushConstant)); roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id; @@ -1130,7 +1119,6 @@ void RasterizerEffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_ } void RasterizerEffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size) { - cubemap_downsampler.push_constant.face_size = p_size.x; RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); @@ -1149,7 +1137,6 @@ void RasterizerEffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cu } void RasterizerEffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array) { - Vector<RD::Uniform> uniforms; for (int i = 0; i < p_dest_cubemap.size(); i++) { RD::Uniform u; @@ -1179,7 +1166,6 @@ void RasterizerEffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_des } void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_lights, RenderPipelineVertexFormatCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position) { - SkyPushConstant sky_push_constant; zeromem(&sky_push_constant, sizeof(SkyPushConstant)); @@ -1202,7 +1188,9 @@ void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, p_pipeline->get_render_pipeline(RD::INVALID_ID, fb_format)); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_samplers, 0); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_uniform_set, 1); + if (p_uniform_set.is_valid()) { //material may not have uniform set + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_uniform_set, 1); + } RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_texture_set, 2); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_lights, 3); @@ -1214,7 +1202,6 @@ void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_ } RasterizerEffectsRD::RasterizerEffectsRD() { - { // Initialize copy Vector<String> copy_modes; copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); @@ -1226,6 +1213,8 @@ RasterizerEffectsRD::RasterizerEffectsRD() { copy_modes.push_back("\n#define MODE_SIMPLE_COPY_DEPTH\n"); copy_modes.push_back("\n#define MODE_MIPMAP\n"); copy_modes.push_back("\n#define MODE_LINEARIZE_DEPTH_COPY\n"); + copy_modes.push_back("\n#define MODE_CUBEMAP_TO_PANORAMA\n"); + copy_modes.push_back("\n#define MODE_CUBEMAP_ARRAY_TO_PANORAMA\n"); copy.shader.initialize(copy_modes); zeromem(©.push_constant, sizeof(CopyPushConstant)); @@ -1464,7 +1453,6 @@ RasterizerEffectsRD::RasterizerEffectsRD() { blend_additive.attachments.push_back(ba); for (int i = 0; i < SPECULAR_MERGE_MAX; i++) { - RD::PipelineColorBlendState blend_state; if (i == SPECULAR_MERGE_ADDITIVE_ADD || i == SPECULAR_MERGE_ADDITIVE_SSR) { blend_state = blend_additive; diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h index 531591442b..8a55d2d13c 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h @@ -55,7 +55,6 @@ #include "servers/rendering_server.h" class RasterizerEffectsRD { - enum CopyMode { COPY_MODE_GAUSSIAN_COPY, COPY_MODE_GAUSSIAN_COPY_8BIT, @@ -66,6 +65,8 @@ class RasterizerEffectsRD { COPY_MODE_SIMPLY_COPY_DEPTH, COPY_MODE_MIPMAP, COPY_MODE_LINEARIZE_DEPTH, + COPY_MODE_CUBE_TO_PANORAMA, + COPY_MODE_CUBE_ARRAY_TO_PANORAMA, COPY_MODE_MAX, }; @@ -82,7 +83,6 @@ class RasterizerEffectsRD { }; struct CopyPushConstant { - int32_t section[4]; int32_t target[2]; uint32_t flags; @@ -119,7 +119,6 @@ class RasterizerEffectsRD { }; struct CopyToFbPushConstant { - float section[4]; float pixel_size[2]; uint32_t flip_y; @@ -148,7 +147,6 @@ class RasterizerEffectsRD { }; struct CubemapRoughness { - CubemapRoughnessPushConstant push_constant; CubemapRoughnessShaderRD shader; RID shader_version; @@ -212,7 +210,6 @@ class RasterizerEffectsRD { }; struct LuminanceReduce { - LuminanceReducePushConstant push_constant; LuminanceReduceShaderRD shader; RID shader_version; @@ -229,7 +226,6 @@ class RasterizerEffectsRD { }; struct CoptToDP { - CubeToDpShaderRD shader; RID shader_version; RID pipeline; @@ -270,7 +266,6 @@ class RasterizerEffectsRD { }; struct Bokeh { - BokehPushConstant push_constant; BokehDofShaderRD shader; RID shader_version; @@ -331,7 +326,6 @@ class RasterizerEffectsRD { }; struct SSAO { - SSAOMinifyPushConstant minify_push_constant; SsaoMinifyShaderRD minify_shader; RID minify_shader_version; @@ -354,7 +348,6 @@ class RasterizerEffectsRD { }; struct RoughnessLimiter { - RoughnessLimiterPushConstant push_constant; RoughnessLimiterShaderRD shader; RID shader_version; @@ -368,7 +361,6 @@ class RasterizerEffectsRD { }; struct CubemapDownsampler { - CubemapDownsamplerPushConstant push_constant; CubemapDownsamplerShaderRD shader; RID shader_version; @@ -385,7 +377,6 @@ class RasterizerEffectsRD { }; struct CubemapFilter { - CubemapFilterShaderRD shader; RID shader_version; RID pipelines[FILTER_MODE_MAX]; @@ -418,7 +409,6 @@ class RasterizerEffectsRD { */ struct SpecularMerge { - SpecularMergeShaderRD shader; RID shader_version; RenderPipelineVertexFormatCacheRD pipelines[SPECULAR_MERGE_MAX]; @@ -432,7 +422,6 @@ class RasterizerEffectsRD { }; struct ScreenSpaceReflectionPushConstant { - float proj_info[4]; int32_t screen_size[2]; @@ -453,7 +442,6 @@ class RasterizerEffectsRD { }; struct ScreenSpaceReflection { - ScreenSpaceReflectionPushConstant push_constant; ScreenSpaceReflectionShaderRD shader; RID shader_version; @@ -462,7 +450,6 @@ class RasterizerEffectsRD { } ssr; struct ScreenSpaceReflectionFilterPushConstant { - float proj_info[4]; uint32_t orthogonal; @@ -481,7 +468,6 @@ class RasterizerEffectsRD { }; struct ScreenSpaceReflectionFilter { - ScreenSpaceReflectionFilterPushConstant push_constant; ScreenSpaceReflectionFilterShaderRD shader; RID shader_version; @@ -489,7 +475,6 @@ class RasterizerEffectsRD { } ssr_filter; struct ScreenSpaceReflectionScalePushConstant { - int32_t screen_size[2]; float camera_z_near; float camera_z_far; @@ -500,7 +485,6 @@ class RasterizerEffectsRD { }; struct ScreenSpaceReflectionScale { - ScreenSpaceReflectionScalePushConstant push_constant; ScreenSpaceReflectionScaleShaderRD shader; RID shader_version; @@ -508,7 +492,6 @@ class RasterizerEffectsRD { } ssr_scale; struct SubSurfaceScatteringPushConstant { - int32_t screen_size[2]; float camera_z_far; float camera_z_near; @@ -523,7 +506,6 @@ class RasterizerEffectsRD { }; struct SubSurfaceScattering { - SubSurfaceScatteringPushConstant push_constant; SubsurfaceScatteringShaderRD shader; RID shader_version; @@ -564,6 +546,7 @@ class RasterizerEffectsRD { public: void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false); void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false); + void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array); void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false); void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far); void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false); @@ -577,7 +560,6 @@ public: void bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_bokeh_texture1, RID p_bokeh_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RS::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal); struct TonemapSettings { - bool use_glow = false; enum GlowMode { GLOW_MODE_ADD, diff --git a/servers/rendering/rasterizer_rd/rasterizer_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_rd.cpp index 4c92912e9c..18cf4fa340 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_rd.cpp @@ -37,7 +37,6 @@ void RasterizerRD::prepare_for_blitting_render_targets() { } void RasterizerRD::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) { - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(p_screen); for (int i = 0; i < p_amount; i++) { @@ -79,6 +78,7 @@ void RasterizerRD::blit_render_targets_to_screen(DisplayServer::WindowID p_scree void RasterizerRD::begin_frame(double frame_step) { frame++; + delta = frame_step; time += frame_step; double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs"); @@ -89,7 +89,6 @@ void RasterizerRD::begin_frame(double frame_step) { } void RasterizerRD::end_frame(bool p_swap_buffers) { - #ifndef _MSC_VER #warning TODO: likely passa bool to swap buffers to avoid display? #endif @@ -97,7 +96,6 @@ void RasterizerRD::end_frame(bool p_swap_buffers) { } void RasterizerRD::initialize() { - { //create framebuffer copy shader RenderingDevice::ShaderStageData vert; vert.shader_stage = RenderingDevice::SHADER_STAGE_VERTEX; @@ -157,10 +155,9 @@ void RasterizerRD::initialize() { } ThreadWorkPool RasterizerRD::thread_work_pool; -uint32_t RasterizerRD::frame = 1; +uint64_t RasterizerRD::frame = 1; void RasterizerRD::finalize() { - thread_work_pool.finish(); memdelete(scene); @@ -173,7 +170,10 @@ void RasterizerRD::finalize() { RD::get_singleton()->free(copy_viewports_sampler); } +RasterizerRD *RasterizerRD::singleton = nullptr; + RasterizerRD::RasterizerRD() { + singleton = this; thread_work_pool.init(); time = 0; diff --git a/servers/rendering/rasterizer_rd/rasterizer_rd.h b/servers/rendering/rasterizer_rd/rasterizer_rd.h index 756b9499ca..cb53a531ac 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_rd.h @@ -53,8 +53,9 @@ protected: Map<RID, RID> render_target_descriptors; double time; + float delta; - static uint32_t frame; + static uint64_t frame; public: RasterizerStorage *get_storage() { return storage; } @@ -71,7 +72,8 @@ public: void end_frame(bool p_swap_buffers); void finalize(); - static _ALWAYS_INLINE_ uint64_t get_frame_number() { return frame; } + _ALWAYS_INLINE_ uint64_t get_frame_number() const { return frame; } + _ALWAYS_INLINE_ float get_frame_delta_time() const { return delta; } static Error is_viable() { return OK; @@ -89,6 +91,7 @@ public: static ThreadWorkPool thread_work_pool; + static RasterizerRD *singleton; RasterizerRD(); ~RasterizerRD() {} }; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp index 6986f82065..7d351f249a 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp @@ -67,33 +67,30 @@ static _FORCE_INLINE_ void store_basis_3x4(const Basis &p_mtx, float *p_array) { p_array[11] = 0; } -static _FORCE_INLINE_ void store_transform_3x3(const Transform &p_mtx, float *p_array) { - p_array[0] = p_mtx.basis.elements[0][0]; - p_array[1] = p_mtx.basis.elements[1][0]; - p_array[2] = p_mtx.basis.elements[2][0]; +static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_mtx, float *p_array) { + p_array[0] = p_mtx.elements[0][0]; + p_array[1] = p_mtx.elements[1][0]; + p_array[2] = p_mtx.elements[2][0]; p_array[3] = 0; - p_array[4] = p_mtx.basis.elements[0][1]; - p_array[5] = p_mtx.basis.elements[1][1]; - p_array[6] = p_mtx.basis.elements[2][1]; + p_array[4] = p_mtx.elements[0][1]; + p_array[5] = p_mtx.elements[1][1]; + p_array[6] = p_mtx.elements[2][1]; p_array[7] = 0; - p_array[8] = p_mtx.basis.elements[0][2]; - p_array[9] = p_mtx.basis.elements[1][2]; - p_array[10] = p_mtx.basis.elements[2][2]; + p_array[8] = p_mtx.elements[0][2]; + p_array[9] = p_mtx.elements[1][2]; + p_array[10] = p_mtx.elements[2][2]; p_array[11] = 0; } static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) { - for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - p_array[i * 4 + j] = p_mtx.matrix[i][j]; } } } static _FORCE_INLINE_ void store_soft_shadow_kernel(const float *p_kernel, float *p_array) { - for (int i = 0; i < 128; i++) { p_array[i] = p_kernel[i]; } @@ -224,7 +221,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { switch (blend_mode) { case BLEND_MODE_MIX: { - blend_attachment.enable_blend = true; blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD; blend_attachment.color_blend_op = RD::BLEND_OP_ADD; @@ -235,7 +231,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { } break; case BLEND_MODE_ADD: { - blend_attachment.enable_blend = true; blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD; blend_attachment.color_blend_op = RD::BLEND_OP_ADD; @@ -247,7 +242,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { } break; case BLEND_MODE_SUB: { - blend_attachment.enable_blend = true; blend_attachment.alpha_blend_op = RD::BLEND_OP_SUBTRACT; blend_attachment.color_blend_op = RD::BLEND_OP_SUBTRACT; @@ -288,7 +282,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { } for (int i = 0; i < CULL_VARIANT_MAX; i++) { - RD::PolygonCullMode cull_mode_rd_table[CULL_VARIANT_MAX][3] = { { RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_FRONT, RD::POLYGON_CULL_BACK }, { RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_BACK, RD::POLYGON_CULL_FRONT }, @@ -298,7 +291,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { RD::PolygonCullMode cull_mode_rd = cull_mode_rd_table[i][cull]; for (int j = 0; j < RS::PRIMITIVE_MAX; j++) { - RD::RenderPrimitive primitive_rd_table[RS::PRIMITIVE_MAX] = { RD::RENDER_PRIMITIVE_POINTS, RD::RENDER_PRIMITIVE_LINES, @@ -310,7 +302,6 @@ void RasterizerSceneHighEndRD::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++) { - RD::PipelineRasterizationState raster_state; raster_state.cull_mode = cull_mode_rd; raster_state.wireframe = wireframe; @@ -337,7 +328,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { continue; // do not use this version (will error if using it is attempted) } } else { - if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_VCT_COLOR_PASS || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) { blend_state = blend_state_opaque; } else if (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) { @@ -373,11 +363,9 @@ void RasterizerSceneHighEndRD::ShaderData::set_default_texture_param(const Strin } void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { - Map<int, StringName> order; for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { continue; } @@ -390,7 +378,6 @@ void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_ } for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]); pi.name = E->get(); p_param_list->push_back(pi); @@ -398,9 +385,7 @@ void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_ } void RasterizerSceneHighEndRD::ShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const { - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } @@ -429,6 +414,7 @@ bool RasterizerSceneHighEndRD::ShaderData::is_animated() const { bool RasterizerSceneHighEndRD::ShaderData::casts_shadows() const { return false; } + Variant RasterizerSceneHighEndRD::ShaderData::get_default_parameter(const StringName &p_parameter) const { if (uniforms.has(p_parameter)) { ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; @@ -466,7 +452,6 @@ void RasterizerSceneHighEndRD::MaterialData::set_next_pass(RID p_pass) { } void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { - RasterizerSceneHighEndRD *scene_singleton = (RasterizerSceneHighEndRD *)RasterizerSceneHighEndRD::singleton; if ((uint32_t)ubo_data.size() != shader_data->ubo_size) { @@ -491,7 +476,6 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN //check whether buffer changed if (p_uniform_dirty && ubo_data.size()) { - update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false); RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw()); } @@ -510,7 +494,6 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN } if (p_textures_dirty && tex_uniform_count) { - update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true); } @@ -527,7 +510,6 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN Vector<RD::Uniform> uniforms; { - if (shader_data->ubo_size) { RD::Uniform u; u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; @@ -572,7 +554,6 @@ RasterizerSceneHighEndRD::RenderBufferDataHighEnd::~RenderBufferDataHighEnd() { } void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() { - if (!specular.is_valid()) { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; @@ -588,7 +569,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() { specular = RD::get_singleton()->texture_create(tf, RD::TextureView()); if (msaa == RS::VIEWPORT_MSAA_DISABLED) { - { Vector<RID> fb; fb.push_back(color); @@ -605,7 +585,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() { } } else { - tf.samples = texture_samples; tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; specular_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView()); @@ -629,7 +608,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() { } void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::clear() { - if (color_msaa.is_valid()) { RD::get_singleton()->free(color_msaa); color_msaa = RID(); @@ -689,7 +667,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::configure(RID p_color_bu depth = p_depth_buffer; if (p_msaa == RS::VIEWPORT_MSAA_DISABLED) { - { Vector<RID> fb; fb.push_back(p_color_buffer); @@ -704,7 +681,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::configure(RID p_color_bu depth_fb = RD::get_singleton()->framebuffer_create(fb); } } else { - RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.width = p_width; @@ -785,7 +761,6 @@ void RasterizerSceneHighEndRD::_allocate_normal_texture(RenderBufferDataHighEnd } void RasterizerSceneHighEndRD::_allocate_roughness_texture(RenderBufferDataHighEnd *rb) { - if (rb->roughness_buffer.is_valid()) { return; } @@ -807,7 +782,6 @@ void RasterizerSceneHighEndRD::_allocate_roughness_texture(RenderBufferDataHighE rb->roughness_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); if (rb->msaa == RS::VIEWPORT_MSAA_DISABLED) { - Vector<RID> fb; fb.push_back(rb->depth); fb.push_back(rb->normal_buffer); @@ -840,9 +814,9 @@ bool RasterizerSceneHighEndRD::free(RID p_rid) { } void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth) { + uint32_t lightmap_captures_used = 0; for (int i = 0; i < p_element_count; i++) { - const RenderList::Element *e = p_elements[i]; InstanceData &id = scene_state.instances[i]; store_transform(e->instance->transform, id.transform); @@ -898,6 +872,7 @@ void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements, if (written == 0) { id.gi_offset = index; + id.flags |= INSTANCE_DATA_FLAG_USE_GIPROBE; written = 1; } else { id.gi_offset = index << 16; @@ -910,18 +885,51 @@ void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements, } else if (written == 1) { id.gi_offset |= 0xFFFF0000; } + } else if (e->instance->lightmap) { + int32_t lightmap_index = storage->lightmap_get_array_index(e->instance->lightmap->base); + if (lightmap_index >= 0) { + id.gi_offset = lightmap_index; + id.gi_offset |= e->instance->lightmap_slice_index << 12; + id.gi_offset |= e->instance->lightmap_cull_index << 20; + id.lightmap_uv_scale[0] = e->instance->lightmap_uv_scale.position.x; + id.lightmap_uv_scale[1] = e->instance->lightmap_uv_scale.position.y; + id.lightmap_uv_scale[2] = e->instance->lightmap_uv_scale.size.width; + id.lightmap_uv_scale[3] = e->instance->lightmap_uv_scale.size.height; + id.flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP; + if (storage->lightmap_uses_spherical_harmonics(e->instance->lightmap->base)) { + id.flags |= INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP; + } + } else { + id.gi_offset = 0xFFFFFFFF; + } + } else if (!e->instance->lightmap_sh.empty()) { + if (lightmap_captures_used < scene_state.max_lightmap_captures) { + const Color *src_capture = e->instance->lightmap_sh.ptr(); + LightmapCaptureData &lcd = scene_state.lightmap_captures[lightmap_captures_used]; + for (int j = 0; j < 9; j++) { + lcd.sh[j * 4 + 0] = src_capture[j].r; + lcd.sh[j * 4 + 1] = src_capture[j].g; + lcd.sh[j * 4 + 2] = src_capture[j].b; + lcd.sh[j * 4 + 3] = src_capture[j].a; + } + id.flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE; + id.gi_offset = lightmap_captures_used; + lightmap_captures_used++; + } } else { id.gi_offset = 0xFFFFFFFF; } } RD::get_singleton()->buffer_update(scene_state.instance_buffer, 0, sizeof(InstanceData) * p_element_count, scene_state.instances, true); + if (lightmap_captures_used) { + RD::get_singleton()->buffer_update(scene_state.lightmap_capture_buffer, 0, sizeof(LightmapCaptureData) * lightmap_captures_used, scene_state.lightmap_captures, true); + } } /// RENDERING /// -void RasterizerSceneHighEndRD::_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) { - +void RasterizerSceneHighEndRD::_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) { RD::DrawListID draw_list = p_draw_list; RD::FramebufferFormatID framebuffer_format = p_framebuffer_Format; @@ -949,9 +957,10 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l PushConstant push_constant; zeromem(&push_constant, sizeof(PushConstant)); + push_constant.bake_uv2_offset[0] = p_uv_offset.x; + push_constant.bake_uv2_offset[1] = p_uv_offset.y; for (int i = 0; i < p_element_count; i++) { - const RenderList::Element *e = p_elements[i]; MaterialData *material = e->material; @@ -961,7 +970,7 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l //find cull variant ShaderData::CullVariant cull_variant; - if ((p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) && e->instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) { + if (p_pass_mode == PASS_MODE_DEPTH_MATERIAL || ((p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) && e->instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED)) { cull_variant = ShaderData::CULL_VARIANT_DOUBLE_SIDED; } else { bool mirror = e->instance->mirror; @@ -1080,7 +1089,7 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l prev_index_array_rd = index_array_rd; } - RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format); + RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_force_wireframe); if (pipeline_rd != prev_pipeline_rd) { // checking with prev shader does not make so much sense, as @@ -1115,10 +1124,8 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instances); } break; case RS::INSTANCE_IMMEDIATE: { - } break; case RS::INSTANCE_PARTICLES: { - } break; default: { ERR_CONTINUE(true); //should be a bug @@ -1128,7 +1135,6 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l } void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows) { - //CameraMatrix projection = p_cam_projection; //projection.flip_y(); // Vulkan and modern APIs use Y-Down CameraMatrix correction; @@ -1173,7 +1179,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer scene_state.ubo.time = time; if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { - scene_state.ubo.use_ambient_light = true; scene_state.ubo.ambient_light_color_energy[0] = 1; scene_state.ubo.ambient_light_color_energy[1] = 1; @@ -1184,7 +1189,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer scene_state.ubo.ssao_enabled = false; } else if (is_environment(p_environment)) { - RS::EnvironmentBG env_bg = environment_get_background(p_environment); RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_environment); @@ -1195,7 +1199,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer //ambient if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) { - Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_environment); color = color.to_linear(); @@ -1205,7 +1208,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer scene_state.ubo.use_ambient_light = true; scene_state.ubo.use_ambient_cubemap = false; } else { - float energy = environment_get_ambient_light_energy(p_environment); Color color = environment_get_ambient_light_color(p_environment); color = color.to_linear(); @@ -1240,7 +1242,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer scene_state.ubo.ao_color[3] = ao_color.a; } else { - if (p_reflection_probe.is_valid() && storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_reflection_probe))) { scene_state.ubo.use_ambient_light = false; } else { @@ -1255,6 +1256,7 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer scene_state.ubo.use_ambient_cubemap = false; scene_state.ubo.use_reflection_cubemap = false; + scene_state.ubo.ssao_enabled = false; } scene_state.ubo.roughness_limiter_enabled = p_opaque_render_buffers && screen_space_roughness_limiter_is_active(); @@ -1263,7 +1265,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer } void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index) { - RID m_src; m_src = p_instance->material_override.is_valid() ? p_instance->material_override : p_material; @@ -1271,8 +1272,6 @@ void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t if (unlikely(get_debug_draw_mode() != RS::VIEWPORT_DEBUG_DRAW_DISABLED)) { if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { m_src = overdraw_material; - } else if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME) { - m_src = wireframe_material; } else if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING) { m_src = default_material; } @@ -1297,16 +1296,15 @@ void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t _add_geometry_with_material(p_instance, p_surface, material, m_src, p_pass_mode, p_geometry_index); while (material->next_pass.is_valid()) { - material = (MaterialData *)storage->material_get_data(material->next_pass, RasterizerStorageRD::SHADER_TYPE_3D); - if (!material || !material->shader_data->valid) + if (!material || !material->shader_data->valid) { break; + } _add_geometry_with_material(p_instance, p_surface, material, material->next_pass, p_pass_mode, p_geometry_index); } } void RasterizerSceneHighEndRD::_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 has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture; bool has_base_alpha = (p_material->shader_data->uses_alpha || has_read_screen_alpha); bool has_blend_alpha = p_material->shader_data->uses_blend_alpha; @@ -1329,7 +1327,6 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta } if (p_pass_mode != PASS_MODE_COLOR && p_pass_mode != PASS_MODE_COLOR_SPECULAR) { - if (has_blend_alpha || has_read_screen_alpha || (has_base_alpha && !p_material->shader_data->uses_depth_pre_pass) || p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED || p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) { //conditions in which no depth pass should be processed return; @@ -1351,8 +1348,9 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta RenderList::Element *e = (has_alpha || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED) ? render_list.add_alpha_element() : render_list.add_element(); - if (!e) + if (!e) { return; + } e->instance = p_instance; e->material = p_material; @@ -1374,7 +1372,7 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta e->geometry_index = p_geometry_index; e->material_index = e->material->index; e->uses_instancing = e->instance->base_type == RS::INSTANCE_MULTIMESH; - e->uses_lightmap = e->instance->lightmap.is_valid(); + e->uses_lightmap = e->instance->lightmap != nullptr || !e->instance->lightmap_sh.empty(); e->uses_vct = e->instance->gi_probe_instances.size(); e->shader_index = e->shader_index; e->depth_layer = e->instance->depth_layer; @@ -1386,7 +1384,6 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta } void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_no_gi) { - scene_state.current_shader_index = 0; scene_state.current_material_index = 0; scene_state.used_sss = false; @@ -1399,14 +1396,11 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i //fill list for (int i = 0; i < p_cull_count; i++) { - InstanceBase *inst = p_cull_result[i]; //add geometry for drawing switch (inst->base_type) { - case RS::INSTANCE_MESH: { - const RID *materials = nullptr; uint32_t surface_count; @@ -1418,7 +1412,6 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i const RID *inst_materials = inst->materials.ptr(); for (uint32_t j = 0; j < surface_count; j++) { - RID material = inst_materials[j].is_valid() ? inst_materials[j] : materials[j]; uint32_t surface_index = storage->mesh_surface_get_render_pass_index(inst->base, j, render_pass, &geometry_index); @@ -1430,7 +1423,6 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i } break; case RS::INSTANCE_MULTIMESH: { - if (storage->multimesh_get_instances_to_draw(inst->base) == 0) { //not visible, 0 instances continue; @@ -1450,7 +1442,6 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i } for (uint32_t j = 0; j < surface_count; j++) { - uint32_t surface_index = storage->mesh_surface_get_multimesh_render_pass_index(mesh, j, render_pass, &geometry_index); _add_geometry(inst, j, materials[j], p_pass_mode, surface_index); } @@ -1497,9 +1488,7 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i } void RasterizerSceneHighEndRD::_setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment) { - for (int i = 0; i < p_reflection_probe_cull_count; i++) { - RID rpi = p_reflection_probe_cull_result[i]; if (i >= (int)scene_state.max_reflections) { @@ -1575,12 +1564,29 @@ void RasterizerSceneHighEndRD::_setup_reflections(RID *p_reflection_probe_cull_r } } -void RasterizerSceneHighEndRD::_setup_gi_probes(RID *p_gi_probe_probe_cull_result, int p_gi_probe_probe_cull_count, const Transform &p_camera_transform) { +void RasterizerSceneHighEndRD::_setup_lightmaps(InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, const Transform &p_cam_transform) { + uint32_t lightmaps_used = 0; + for (int i = 0; i < p_lightmap_cull_count; i++) { + if (i >= (int)scene_state.max_lightmaps) { + break; + } + InstanceBase *lm = p_lightmap_cull_result[i]; + Basis to_lm = lm->transform.basis.inverse() * p_cam_transform.basis; + to_lm = to_lm.inverse().transposed(); //will transform normals + store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform); + lm->lightmap_cull_index = i; + lightmaps_used++; + } + if (lightmaps_used > 0) { + RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * lightmaps_used, scene_state.lightmaps, true); + } +} + +void RasterizerSceneHighEndRD::_setup_gi_probes(RID *p_gi_probe_probe_cull_result, int p_gi_probe_probe_cull_count, const Transform &p_camera_transform) { int index = 0; for (int i = 0; i < p_gi_probe_probe_cull_count; i++) { - RID rpi = p_gi_probe_probe_cull_result[i]; if (index >= (int)scene_state.max_gi_probes) { @@ -1631,13 +1637,11 @@ void RasterizerSceneHighEndRD::_setup_gi_probes(RID *p_gi_probe_probe_cull_resul } void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows) { - uint32_t light_count = 0; scene_state.ubo.directional_light_count = 0; sky_scene_state.directional_light_count = 0; for (int i = 0; i < p_light_cull_count; i++) { - RID li = p_light_cull_result[i]; RID base = light_instance_get_base_light(li); @@ -1645,9 +1649,7 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig RS::LightType type = storage->light_get_type(base); switch (type) { - case RS::LIGHT_DIRECTIONAL: { - if (scene_state.ubo.directional_light_count >= scene_state.max_directional_lights) { continue; } @@ -1699,7 +1701,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig light_data.shadow_color4[3] = 1.0; } else { - light_data.shadow_color1[0] = shadow_col.r; light_data.shadow_color1[1] = shadow_col.g; light_data.shadow_color1[2] = shadow_col.b; @@ -1731,7 +1732,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig } if (light_data.shadow_enabled) { - RS::LightDirectionalShadowMode smode = storage->light_directional_get_shadow_mode(base); int limit = smode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (smode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3); @@ -1794,7 +1794,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig // Copy to SkyDirectionalLightData if (sky_scene_state.directional_light_count < sky_scene_state.max_directional_lights) { - SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[sky_scene_state.directional_light_count]; Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized(); @@ -1818,7 +1817,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig } break; case RS::LIGHT_SPOT: case RS::LIGHT_OMNI: { - if (light_count >= scene_state.max_lights) { continue; } @@ -1874,7 +1872,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig Rect2 rect = storage->decal_atlas_get_texture_rect(projector); if (type == RS::LIGHT_SPOT) { - light_data.projector_rect[0] = rect.position.x; light_data.projector_rect[1] = rect.position.y + rect.size.height; //flip because shadow is flipped light_data.projector_rect[2] = rect.size.width; @@ -1927,14 +1924,12 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR); if (type == RS::LIGHT_OMNI) { - light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another Transform proj = (p_camera_inverse_transform * light_transform).inverse(); store_transform(proj, light_data.shadow_matrix); if (size > 0.0) { - light_data.soft_shadow_size = size; } else { light_data.soft_shadow_size = 0.0; @@ -1942,7 +1937,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig } } else if (type == RS::LIGHT_SPOT) { - Transform modelview = (p_camera_inverse_transform * light_transform).inverse(); CameraMatrix bias; bias.set_light_bias(); @@ -1986,7 +1980,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig } void RasterizerSceneHighEndRD::_setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform) { - Transform uv_xform; uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0)); uv_xform.origin = Vector3(-1.0, 0.0, -1.0); @@ -1994,7 +1987,6 @@ void RasterizerSceneHighEndRD::_setup_decals(const RID *p_decal_instances, int p p_decal_count = MIN((uint32_t)p_decal_count, scene_state.max_decals); int idx = 0; for (int i = 0; i < p_decal_count; i++) { - RID di = p_decal_instances[i]; RID decal = decal_instance_get_base(di); @@ -2042,7 +2034,6 @@ void RasterizerSceneHighEndRD::_setup_decals(const RID *p_decal_instances, int p dd.albedo_rect[2] = rect.size.x; dd.albedo_rect[3] = rect.size.y; } else { - if (!emission_tex.is_valid()) { continue; //no albedo, no emission, no decal. } @@ -2118,8 +2109,7 @@ void RasterizerSceneHighEndRD::_setup_decals(const RID *p_decal_instances, int p } } -void RasterizerSceneHighEndRD::_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, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_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) { - +void RasterizerSceneHighEndRD::_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, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_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; if (p_render_buffer.is_valid()) { render_buffer = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffer); @@ -2168,7 +2158,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor bool using_ssr = false; if (render_buffer) { - screen_pixel_size.width = 1.0 / render_buffer->width; screen_pixel_size.height = 1.0 / render_buffer->height; screen_size.x = render_buffer->width; @@ -2238,6 +2227,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor _setup_decals(p_decal_cull_result, p_decal_cull_count, p_cam_transform.affine_inverse()); _setup_reflections(p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_cam_transform.affine_inverse(), p_environment); _setup_gi_probes(p_gi_probe_cull_result, p_gi_probe_cull_count, p_cam_transform); + _setup_lightmaps(p_lightmap_cull_result, p_lightmap_cull_count, p_cam_transform); _setup_environment(p_environment, 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(), false); cluster_builder.bake_cluster(); //bake to cluster @@ -2289,7 +2279,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor keep_color = true; } break; case RS::ENV_BG_CAMERA_FEED: { - } break; default: { } @@ -2298,7 +2287,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor if (draw_sky || environment_get_reflection_source(p_environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_environment) == RS::ENV_AMBIENT_SOURCE_SKY) { RID sky = environment_get_sky(p_environment); if (sky.is_valid()) { - RENDER_TIMESTAMP("Setup Sky"); CameraMatrix projection = p_cam_projection; if (p_reflection_probe.is_valid()) { @@ -2316,7 +2304,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor } } } else { - clear_color = p_default_bg_color; } @@ -2338,7 +2325,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor bool finish_depth = using_ssao; 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()); + _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); RD::get_singleton()->draw_list_end(); if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { @@ -2377,7 +2364,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss; { - bool will_continue_color = (can_continue_color || draw_sky || debug_giprobes); bool will_continue_depth = (can_continue_depth || draw_sky || debug_giprobes); @@ -2394,7 +2380,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer; RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (using_ssao ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CONTINUE) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); - _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(framebuffer), render_list.elements, render_list.element_count, false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set); + _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); RD::get_singleton()->draw_list_end(); if (will_continue_color && using_separate_specular) { @@ -2433,7 +2419,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor } if (render_buffer && !can_continue_color && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color, true); if (using_separate_specular) { RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa, render_buffer->specular, true); @@ -2441,12 +2426,10 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor } if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth, true); } if (using_separate_specular) { - if (using_sss) { RENDER_TIMESTAMP("Sub Surface Scattering"); _process_sss(p_render_buffer, p_cam_projection); @@ -2472,18 +2455,16 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor { 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); + _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); RD::get_singleton()->draw_list_end(); } if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color, true); } } void RasterizerSceneHighEndRD::_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) { - RENDER_TIMESTAMP("Setup Rendering Shadow"); _update_render_base_uniform_set(); @@ -2517,13 +2498,14 @@ void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase ** } void RasterizerSceneHighEndRD::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) { - RENDER_TIMESTAMP("Setup Rendering Shadow"); + RENDER_TIMESTAMP("Setup Rendering Material"); _update_render_base_uniform_set(); render_pass++; scene_state.ubo.dual_paraboloid_side = 0; + scene_state.ubo.material_uv2_mode = true; _setup_environment(RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0); @@ -2554,8 +2536,68 @@ void RasterizerSceneHighEndRD::_render_material(const Transform &p_cam_transform } } -void RasterizerSceneHighEndRD::_base_uniforms_changed() { +void RasterizerSceneHighEndRD::_render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) { + RENDER_TIMESTAMP("Setup Rendering UV2"); + + _update_render_base_uniform_set(); + + render_pass++; + + scene_state.ubo.dual_paraboloid_side = 0; + scene_state.ubo.material_uv2_mode = true; + + _setup_environment(RID(), CameraMatrix(), Transform(), RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0); + + render_list.clear(); + + PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL; + _fill_render_list(p_cull_result, p_cull_count, pass_mode, true); + + _setup_view_dependant_uniform_set(RID(), RID()); + + RENDER_TIMESTAMP("Render Material"); + + render_list.sort_by_key(false); + + _fill_instances(render_list.elements, render_list.element_count, true); + + { + //regular forward for now + Vector<Color> clear; + clear.push_back(Color(0, 0, 0, 0)); + clear.push_back(Color(0, 0, 0, 0)); + clear.push_back(Color(0, 0, 0, 0)); + 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); + + const int uv_offset_count = 9; + static const Vector2 uv_offsets[uv_offset_count] = { + Vector2(-1, 1), + Vector2(1, 1), + Vector2(1, -1), + Vector2(-1, -1), + Vector2(-1, 0), + Vector2(1, 0), + Vector2(0, -1), + Vector2(0, 1), + Vector2(0, 0), + + }; + + for (int i = 0; i < uv_offset_count; i++) { + 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, RID(), RID(), false); //second regular triangles + + RD::get_singleton()->draw_list_end(); + } +} +void RasterizerSceneHighEndRD::_base_uniforms_changed() { if (!render_base_uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) { RD::get_singleton()->free(render_base_uniform_set); } @@ -2563,13 +2605,13 @@ void RasterizerSceneHighEndRD::_base_uniforms_changed() { } void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { - - if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) { - + if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != storage->lightmap_array_get_version())) { if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) { RD::get_singleton()->free(render_base_uniform_set); } + lightmap_texture_array_version = storage->lightmap_array_get_version(); + Vector<RD::Uniform> uniforms; { @@ -2657,7 +2699,6 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { } for (int i = 0; i < slot_count; i++) { - RID probe = gi_probe_get_slots()[i]; if (gi_probe_is_anisotropic()) { @@ -2685,6 +2726,27 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; u.binding = 10; + u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.ids.push_back(scene_state.lightmap_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 11; + u.type = RD::UNIFORM_TYPE_TEXTURE; + u.ids = storage->lightmap_array_get_textures(); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 12; + u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.ids.push_back(scene_state.lightmap_capture_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 13; u.type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture(); u.ids.push_back(decal_atlas); @@ -2692,7 +2754,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { } { RD::Uniform u; - u.binding = 11; + u.binding = 14; u.type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture_srgb(); u.ids.push_back(decal_atlas); @@ -2700,7 +2762,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { } { RD::Uniform u; - u.binding = 12; + u.binding = 15; u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(scene_state.decal_buffer); uniforms.push_back(u); @@ -2708,14 +2770,14 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; - u.binding = 13; + u.binding = 16; u.type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(cluster_builder.get_cluster_texture()); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 14; + u.binding = 17; u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(cluster_builder.get_cluster_indices_buffer()); uniforms.push_back(u); @@ -2723,7 +2785,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; - u.binding = 15; + u.binding = 18; u.type = RD::UNIFORM_TYPE_TEXTURE; if (directional_shadow_get_texture().is_valid()) { u.ids.push_back(directional_shadow_get_texture()); @@ -2736,7 +2798,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 16; + u.binding = 19; u.ids.push_back(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -2746,7 +2808,6 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { } void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_atlas, RID p_reflection_atlas) { - 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); } @@ -2756,7 +2817,6 @@ void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_at Vector<RD::Uniform> uniforms; { - RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID(); RD::Uniform u; u.binding = 0; @@ -2788,7 +2848,6 @@ void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_at } void RasterizerSceneHighEndRD::_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); } @@ -2796,7 +2855,6 @@ void RasterizerSceneHighEndRD::_render_buffers_clear_uniform_set(RenderBufferDat } void RasterizerSceneHighEndRD::_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); @@ -2815,11 +2873,9 @@ RID RasterizerSceneHighEndRD::_render_buffers_get_normal_texture(RID p_render_bu } void RasterizerSceneHighEndRD::_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; @@ -2951,7 +3007,21 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag scene_state.gi_probe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GIProbeData) * scene_state.max_gi_probes); defines += "\n#define MAX_GI_PROBES " + itos(scene_state.max_gi_probes) + "\n"; } + { + //lightmaps + scene_state.max_lightmaps = storage->lightmap_array_get_size(); + defines += "\n#define MAX_LIGHTMAP_TEXTURES " + itos(scene_state.max_lightmaps) + "\n"; + defines += "\n#define MAX_LIGHTMAPS " + itos(scene_state.max_lightmaps) + "\n"; + scene_state.lightmaps = memnew_arr(LightmapData, scene_state.max_lightmaps); + scene_state.lightmap_buffer = RD::get_singleton()->storage_buffer_create(sizeof(LightmapData) * scene_state.max_lightmaps); + } + { + //captures + scene_state.max_lightmap_captures = 2048; + scene_state.lightmap_captures = memnew_arr(LightmapCaptureData, scene_state.max_lightmap_captures); + scene_state.lightmap_capture_buffer = RD::get_singleton()->storage_buffer_create(sizeof(LightmapCaptureData) * scene_state.max_lightmap_captures); + } { //decals scene_state.max_decals = MIN(1024 * 1024, uniform_max_size) / sizeof(DecalData); //1mb of decals uint32_t decal_buffer_size = scene_state.max_decals * sizeof(DecalData); @@ -2959,6 +3029,10 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag scene_state.decal_buffer = RD::get_singleton()->storage_buffer_create(decal_buffer_size); } + { + defines += "\n#define MATERIAL_UNIFORM_SET " + itos(MATERIAL_UNIFORM_SET) + "\n"; + } + Vector<String> shader_versions; shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n"); shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n"); @@ -3129,7 +3203,6 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag render_pass = 0; { - scene_state.max_instances = render_list.max_elements; scene_state.instances = memnew_arr(InstanceData, scene_state.max_instances); scene_state.instance_buffer = RD::get_singleton()->storage_buffer_create(sizeof(InstanceData) * scene_state.max_instances); @@ -3149,7 +3222,6 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag } { - overdraw_material_shader = storage->shader_create(); storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.2; }"); overdraw_material = storage->material_create(); @@ -3173,7 +3245,6 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag default_vec4_xform_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, TRANSFORMS_UNIFORM_SET); } { - RD::SamplerState sampler; sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR; sampler.min_filter = RD::SAMPLER_FILTER_LINEAR; @@ -3239,12 +3310,16 @@ RasterizerSceneHighEndRD::~RasterizerSceneHighEndRD() { RD::get_singleton()->free(scene_state.gi_probe_buffer); RD::get_singleton()->free(scene_state.directional_light_buffer); RD::get_singleton()->free(scene_state.light_buffer); + RD::get_singleton()->free(scene_state.lightmap_buffer); + RD::get_singleton()->free(scene_state.lightmap_capture_buffer); RD::get_singleton()->free(scene_state.reflection_buffer); RD::get_singleton()->free(scene_state.decal_buffer); memdelete_arr(scene_state.instances); memdelete_arr(scene_state.gi_probes); memdelete_arr(scene_state.directional_lights); memdelete_arr(scene_state.lights); + memdelete_arr(scene_state.lightmaps); + memdelete_arr(scene_state.lightmap_captures); memdelete_arr(scene_state.reflections); memdelete_arr(scene_state.decals); } diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h index a48e2e2259..8438a4f730 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h @@ -38,7 +38,6 @@ #include "servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl.gen.h" class RasterizerSceneHighEndRD : public RasterizerSceneRD { - enum { SCENE_UNIFORM_SET = 0, RADIANCE_UNIFORM_SET = 1, @@ -75,7 +74,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { /* Material */ struct ShaderData : public RasterizerStorageRD::ShaderData { - enum BlendMode { //used internally BLEND_MODE_MIX, BLEND_MODE_ADD, @@ -193,7 +191,8 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { struct PushConstant { uint32_t index; - uint32_t pad[3]; + uint32_t pad; + float bake_uv2_offset[2]; }; /* Framebuffer */ @@ -241,6 +240,8 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { RID render_base_uniform_set; RID view_dependant_uniform_set; + uint64_t lightmap_texture_array_version = 0xFFFFFFFF; + virtual void _base_uniforms_changed(); void _render_buffers_clear_uniform_set(RenderBufferDataHighEnd *rb); virtual void _render_buffers_uniform_set_changed(RID p_render_buffers); @@ -285,7 +286,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { }; struct DirectionalLightData { - float direction[3]; float energy; float color[3]; @@ -331,6 +331,10 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { uint32_t pad[1]; }; + struct LightmapData { + float normal_xform[12]; + }; + struct DecalData { float xform[16]; float inv_extents[3]; @@ -349,7 +353,15 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { float normal_fade; }; + struct LightmapCaptureData { + float sh[9 * 4]; + }; + enum { + INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8, + INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9, + INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10, + INSTANCE_DATA_FLAG_USE_GIPROBE = 1 << 11, INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12, INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13, INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14, @@ -366,6 +378,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { uint32_t instance_uniforms_ofs; //instance_offset in instancing/skeleton buffer uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap) uint32_t mask; + float lightmap_uv_scale[4]; }; struct SceneState { @@ -418,6 +431,9 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { uint32_t roughness_limiter_enabled; float ao_color[4]; + + uint32_t material_uv2_mode; + uint32_t pad_material[3]; }; UBO ubo; @@ -434,6 +450,10 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { RID gi_probe_buffer; uint32_t max_gi_probe_probes_per_instance; + LightmapData *lightmaps; + uint32_t max_lightmaps; + RID lightmap_buffer; + DecalData *decals; uint32_t max_decals; RID decal_buffer; @@ -446,6 +466,10 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { uint32_t max_directional_lights; RID directional_light_buffer; + LightmapCaptureData *lightmap_captures; + uint32_t max_lightmap_captures; + RID lightmap_capture_buffer; + RID instance_buffer; InstanceData *instances; uint32_t max_instances; @@ -456,12 +480,12 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { bool used_sss = false; uint32_t current_shader_index = 0; uint32_t current_material_index = 0; + } scene_state; /* Render List */ struct RenderList { - int max_elements; struct Element { @@ -492,7 +516,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { int alpha_element_count; void clear() { - element_count = 0; alpha_element_count = 0; } @@ -500,14 +523,12 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { //should eventually be replaced by radix struct SortByKey { - _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { return A->sort_key < B->sort_key; } }; void sort_by_key(bool p_alpha) { - SortArray<Element *, SortByKey> sorter; if (p_alpha) { sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); @@ -517,7 +538,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { } struct SortByDepth { - _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { return A->instance->depth < B->instance->depth; } @@ -534,7 +554,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { } struct SortByReverseDepthAndPriority { - _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { uint32_t layer_A = uint32_t(A->priority); uint32_t layer_B = uint32_t(B->priority); @@ -557,17 +576,17 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { } _FORCE_INLINE_ Element *add_element() { - - if (element_count + alpha_element_count >= max_elements) + if (element_count + alpha_element_count >= max_elements) { return nullptr; + } elements[element_count] = &base_elements[element_count]; return elements[element_count++]; } _FORCE_INLINE_ Element *add_alpha_element() { - - if (element_count + alpha_element_count >= max_elements) + if (element_count + alpha_element_count >= max_elements) { return nullptr; + } int idx = max_elements - alpha_element_count - 1; elements[idx] = &base_elements[idx]; alpha_element_count++; @@ -575,17 +594,16 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { } void init() { - element_count = 0; alpha_element_count = 0; elements = memnew_arr(Element *, max_elements); base_elements = memnew_arr(Element, max_elements); - for (int i = 0; i < max_elements; i++) + for (int i = 0; i < max_elements; i++) { elements[i] = &base_elements[i]; // assign elements + } } RenderList() { - max_elements = 0; } @@ -632,18 +650,20 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { void _setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform); void _setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment); void _setup_gi_probes(RID *p_gi_probe_probe_cull_result, int p_gi_probe_probe_cull_count, const Transform &p_camera_transform); + 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); - 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); + 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()); _FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index); _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); void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_no_gi); 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, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_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_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, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_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); virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region); + virtual void _render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region); public: virtual void set_time(double p_time, double p_step); diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp index ab669e7647..689552be2f 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp @@ -49,7 +49,6 @@ void get_vogel_disk(float *r_kernel, int p_sample_count) { } void RasterizerSceneRD::_clear_reflection_data(ReflectionData &rd) { - rd.layers.clear(); rd.radiance_base_cubemap = RID(); if (rd.downsampled_radiance_cubemap.is_valid()) { @@ -152,7 +151,6 @@ void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size, } void RasterizerSceneRD::_create_reflection_fast_filter(ReflectionData &rd, bool p_use_arrays) { - storage->get_effects()->cubemap_downsample(rd.radiance_base_cubemap, rd.downsampled_layer.mipmaps[0].view, rd.downsampled_layer.mipmaps[0].size); for (int i = 1; i < rd.downsampled_layer.mipmaps.size(); i++) { @@ -174,21 +172,16 @@ void RasterizerSceneRD::_create_reflection_fast_filter(ReflectionData &rd, bool } void RasterizerSceneRD::_create_reflection_importance_sample(ReflectionData &rd, bool p_use_arrays, int p_cube_side, int p_base_layer) { - if (p_use_arrays) { - //render directly to the layers storage->get_effects()->cubemap_roughness(rd.radiance_base_cubemap, rd.layers[p_base_layer].views[0], p_cube_side, sky_ggx_samples_quality, float(p_base_layer) / (rd.layers.size() - 1.0), rd.layers[p_base_layer].mipmaps[0].size.x); } else { - storage->get_effects()->cubemap_roughness(rd.layers[0].views[p_base_layer - 1], rd.layers[0].views[p_base_layer], p_cube_side, sky_ggx_samples_quality, float(p_base_layer) / (rd.layers[0].mipmaps.size() - 1.0), rd.layers[0].mipmaps[p_base_layer].size.x); } } void RasterizerSceneRD::_update_reflection_mipmaps(ReflectionData &rd) { - if (sky_use_cubemap_array) { - for (int i = 0; i < rd.layers.size(); i++) { for (int j = 0; j < rd.layers[i].mipmaps.size() - 1; j++) { for (int k = 0; k < 6; k++) { @@ -263,13 +256,49 @@ void RasterizerSceneRD::sky_set_material(RID p_sky, RID p_material) { Sky *sky = sky_owner.getornull(p_sky); ERR_FAIL_COND(!sky); sky->material = p_material; + _sky_invalidate(sky); } -void RasterizerSceneRD::_update_dirty_skys() { +Ref<Image> RasterizerSceneRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) { + Sky *sky = sky_owner.getornull(p_sky); + ERR_FAIL_COND_V(!sky, Ref<Image>()); + + _update_dirty_skys(); + + if (sky->radiance.is_valid()) { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; + tf.width = p_size.width; + tf.height = p_size.height; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + + RID rad_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); + storage->get_effects()->copy_cubemap_to_panorama(sky->radiance, rad_tex, p_size, p_bake_irradiance ? roughness_layers : 0, sky->reflection.layers.size() > 1); + Vector<uint8_t> data = RD::get_singleton()->texture_get_data(rad_tex, 0); + RD::get_singleton()->free(rad_tex); + + Ref<Image> img; + img.instance(); + img->create(p_size.width, p_size.height, false, Image::FORMAT_RGBAF, data); + for (int i = 0; i < p_size.width; i++) { + for (int j = 0; j < p_size.height; j++) { + Color c = img->get_pixel(i, j); + c.r *= p_energy; + c.g *= p_energy; + c.b *= p_energy; + img->set_pixel(i, j, c); + } + } + return img; + } + + return Ref<Image>(); +} + +void RasterizerSceneRD::_update_dirty_skys() { Sky *sky = dirty_sky_list; while (sky) { - bool texture_set_dirty = false; //update sky configuration if texture is missing @@ -381,7 +410,6 @@ RID RasterizerSceneRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, ERR_FAIL_COND_V(!sky, RID()); if (sky->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(sky->uniform_set)) { - sky->uniform_set = RID(); if (sky->radiance.is_valid()) { Vector<RD::Uniform> uniforms; @@ -401,7 +429,6 @@ RID RasterizerSceneRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, } RID RasterizerSceneRD::_get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_version) { - if (p_sky->texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(p_sky->texture_uniform_sets[p_version])) { return p_sky->texture_uniform_sets[p_version]; } @@ -468,7 +495,6 @@ RID RasterizerSceneRD::sky_get_material(RID p_sky) const { } void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) { - ERR_FAIL_COND(!is_environment(p_environment)); Sky *sky = sky_owner.getornull(environment_get_sky(p_environment)); @@ -505,7 +531,6 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue CameraMatrix camera; if (custom_fov) { - float near_plane = p_projection.get_z_near(); float far_plane = p_projection.get_z_far(); float aspect = p_projection.get_aspect(); @@ -554,7 +579,6 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue } void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position, const Size2i p_screen_size) { - ERR_FAIL_COND(!is_environment(p_environment)); Sky *sky = sky_owner.getornull(environment_get_sky(p_environment)); @@ -612,26 +636,22 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position, } if (shader_data->uses_time && time - sky->prev_time > 0.00001) { - sky->prev_time = time; sky->reflection.dirty = true; RenderingServerRaster::redraw_request(); } if (material != sky->prev_material) { - sky->prev_material = material; sky->reflection.dirty = true; } if (material->uniform_set_updated) { - material->uniform_set_updated = false; sky->reflection.dirty = true; } if (!p_position.is_equal_approx(sky->prev_position) && shader_data->uses_position) { - sky->prev_position = p_position; sky->reflection.dirty = true; } @@ -664,7 +684,6 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position, } if (light_data_dirty || sky_scene_state.light_uniform_set.is_null()) { - RD::get_singleton()->buffer_update(sky_scene_state.directional_light_buffer, 0, sizeof(SkyDirectionalLightData) * sky_scene_state.max_directional_lights, sky_scene_state.directional_lights, true); if (sky_scene_state.light_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky_scene_state.light_uniform_set)) { @@ -692,7 +711,6 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position, } void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) { - ERR_FAIL_COND(!is_environment(p_environment)); Sky *sky = sky_owner.getornull(environment_get_sky(p_environment)); @@ -724,7 +742,6 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro // Update radiance cubemap if (sky->reflection.dirty) { - static const Vector3 view_normals[6] = { Vector3(+1, 0, 0), Vector3(-1, 0, 0), @@ -905,7 +922,6 @@ void RasterizerSceneRD::SkyShaderData::set_code(const String &p_code) { //update pipelines for (int i = 0; i < SKY_VERSION_MAX; i++) { - RD::PipelineDepthStencilState depth_stencil_state; depth_stencil_state.enable_depth_test = true; depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL; @@ -926,11 +942,9 @@ void RasterizerSceneRD::SkyShaderData::set_default_texture_param(const StringNam } void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { - Map<int, StringName> order; for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } @@ -943,7 +957,6 @@ void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_para } for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]); pi.name = E->get(); p_param_list->push_back(pi); @@ -951,9 +964,7 @@ void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_para } void RasterizerSceneRD::SkyShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const { - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } @@ -1011,7 +1022,6 @@ RasterizerStorageRD::ShaderData *RasterizerSceneRD::_create_sky_shader_func() { } void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { - RasterizerSceneRD *scene_singleton = (RasterizerSceneRD *)RasterizerSceneRD::singleton; uniform_set_updated = true; @@ -1038,7 +1048,6 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName, //check whether buffer changed if (p_uniform_dirty && ubo_data.size()) { - update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false); RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw()); } @@ -1057,7 +1066,6 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName, } if (p_textures_dirty && tex_uniform_count) { - update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true); } @@ -1074,7 +1082,6 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName, Vector<RD::Uniform> uniforms; { - if (shader_data->ubo_size) { RD::Uniform u; u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; @@ -1115,7 +1122,6 @@ RasterizerStorageRD::MaterialData *RasterizerSceneRD::_create_sky_material_func( } RID RasterizerSceneRD::environment_create() { - return environment_owner.make_rid(Environent()); } @@ -1124,36 +1130,43 @@ void RasterizerSceneRD::environment_set_background(RID p_env, RS::EnvironmentBG ERR_FAIL_COND(!env); env->background = p_bg; } + void RasterizerSceneRD::environment_set_sky(RID p_env, RID p_sky) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->sky = p_sky; } + void RasterizerSceneRD::environment_set_sky_custom_fov(RID p_env, float p_scale) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->sky_custom_fov = p_scale; } + void RasterizerSceneRD::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->sky_orientation = p_orientation; } + void RasterizerSceneRD::environment_set_bg_color(RID p_env, const Color &p_color) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->bg_color = p_color; } + void RasterizerSceneRD::environment_set_bg_energy(RID p_env, float p_energy) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->bg_energy = p_energy; } + void RasterizerSceneRD::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->canvas_max_layer = p_max_layer; } + void RasterizerSceneRD::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source, const Color &p_ao_color) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -1170,56 +1183,67 @@ RS::EnvironmentBG RasterizerSceneRD::environment_get_background(RID p_env) const ERR_FAIL_COND_V(!env, RS::ENV_BG_MAX); return env->background; } + RID RasterizerSceneRD::environment_get_sky(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, RID()); return env->sky; } + float RasterizerSceneRD::environment_get_sky_custom_fov(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->sky_custom_fov; } + Basis RasterizerSceneRD::environment_get_sky_orientation(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, Basis()); return env->sky_orientation; } + Color RasterizerSceneRD::environment_get_bg_color(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, Color()); return env->bg_color; } + float RasterizerSceneRD::environment_get_bg_energy(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->bg_energy; } + int RasterizerSceneRD::environment_get_canvas_max_layer(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->canvas_max_layer; } + Color RasterizerSceneRD::environment_get_ambient_light_color(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, Color()); return env->ambient_light; } + RS::EnvironmentAmbientSource RasterizerSceneRD::environment_get_ambient_source(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, RS::ENV_AMBIENT_SOURCE_BG); return env->ambient_source; } + float RasterizerSceneRD::environment_get_ambient_light_energy(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->ambient_light_energy; } + float RasterizerSceneRD::environment_get_ambient_sky_contribution(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->ambient_sky_contribution; } + RS::EnvironmentReflectionSource RasterizerSceneRD::environment_get_reflection_source(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, RS::ENV_REFLECTION_SOURCE_DISABLED); @@ -1249,7 +1273,6 @@ void RasterizerSceneRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMa } void RasterizerSceneRD::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) { - Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->glow_enabled = p_enable; @@ -1269,7 +1292,6 @@ void RasterizerSceneRD::environment_glow_set_use_bicubic_upscale(bool p_enable) } void RasterizerSceneRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) { - Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -1289,7 +1311,6 @@ RS::EnvironmentSSRRoughnessQuality RasterizerSceneRD::environment_get_ssr_roughn } void RasterizerSceneRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) { - Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -1308,7 +1329,6 @@ void RasterizerSceneRD::environment_set_ssao_quality(RS::EnvironmentSSAOQuality } bool RasterizerSceneRD::environment_is_ssao_enabled(RID p_env) const { - Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, false); return env->ssao_enabled; @@ -1319,6 +1339,7 @@ float RasterizerSceneRD::environment_get_ssao_ao_affect(RID p_env) const { ERR_FAIL_COND_V(!env, false); return env->ssao_ao_channel_affect; } + float RasterizerSceneRD::environment_get_ssao_light_affect(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, false); @@ -1326,7 +1347,6 @@ float RasterizerSceneRD::environment_get_ssao_light_affect(RID p_env) const { } bool RasterizerSceneRD::environment_is_ssr_enabled(RID p_env) const { - Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, false); return env->ssr_enabled; @@ -1336,10 +1356,46 @@ bool RasterizerSceneRD::is_environment(RID p_env) const { return environment_owner.owns(p_env); } +Ref<Image> RasterizerSceneRD::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) { + Environent *env = environment_owner.getornull(p_env); + ERR_FAIL_COND_V(!env, Ref<Image>()); + + if (env->background == RS::ENV_BG_CAMERA_FEED || env->background == RS::ENV_BG_CANVAS || env->background == RS::ENV_BG_KEEP) { + return Ref<Image>(); //nothing to bake + } + + if (env->background == RS::ENV_BG_CLEAR_COLOR || env->background == RS::ENV_BG_COLOR) { + Color color; + if (env->background == RS::ENV_BG_CLEAR_COLOR) { + color = storage->get_default_clear_color(); + } else { + color = env->bg_color; + } + color.r *= env->bg_energy; + color.g *= env->bg_energy; + color.b *= env->bg_energy; + + Ref<Image> ret; + ret.instance(); + ret->create(p_size.width, p_size.height, false, Image::FORMAT_RGBAF); + for (int i = 0; i < p_size.width; i++) { + for (int j = 0; j < p_size.height; j++) { + ret->set_pixel(i, j, color); + } + } + return ret; + } + + if (env->background == RS::ENV_BG_SKY && env->sky.is_valid()) { + return sky_bake_panorama(env->sky, env->bg_energy, p_bake_irradiance, p_size); + } + + return Ref<Image>(); +} + //////////////////////////////////////////////////////////// RID RasterizerSceneRD::reflection_atlas_create() { - ReflectionAtlas ra; ra.count = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_count"); ra.size = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_size"); @@ -1348,7 +1404,6 @@ RID RasterizerSceneRD::reflection_atlas_create() { } void RasterizerSceneRD::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) { - ReflectionAtlas *ra = reflection_atlas_owner.getornull(p_ref_atlas); ERR_FAIL_COND(!ra); @@ -1395,7 +1450,6 @@ void RasterizerSceneRD::reflection_probe_instance_set_transform(RID p_instance, } void RasterizerSceneRD::reflection_probe_release_atlas_index(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND(!rpi); @@ -1411,7 +1465,6 @@ void RasterizerSceneRD::reflection_probe_release_atlas_index(RID p_instance) { } bool RasterizerSceneRD::reflection_probe_instance_needs_redraw(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!rpi, false); @@ -1431,7 +1484,6 @@ bool RasterizerSceneRD::reflection_probe_instance_needs_redraw(RID p_instance) { } bool RasterizerSceneRD::reflection_probe_instance_has_reflection(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!rpi, false); @@ -1439,7 +1491,6 @@ bool RasterizerSceneRD::reflection_probe_instance_has_reflection(RID p_instance) } bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) { - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(p_reflection_atlas); ERR_FAIL_COND_V(!atlas, false); @@ -1484,7 +1535,6 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R atlas->reflection = RD::get_singleton()->texture_create(tf, RD::TextureView()); } { - RD::TextureFormat tf; tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32; tf.width = atlas->size; @@ -1540,7 +1590,6 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R } bool RasterizerSceneRD::reflection_probe_instance_postprocess_step(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!rpi, false); ERR_FAIL_COND_V(!rpi->rendering, false); @@ -1618,19 +1667,18 @@ RID RasterizerSceneRD::reflection_probe_instance_get_depth_framebuffer(RID p_ins /////////////////////////////////////////////////////////// RID RasterizerSceneRD::shadow_atlas_create() { - return shadow_atlas_owner.make_rid(ShadowAtlas()); } void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_COND(p_size < 0); p_size = next_power_of_2(p_size); - if (p_size == shadow_atlas->size) + if (p_size == shadow_atlas->size) { return; + } // erasing atlas if (shadow_atlas->depth.is_valid()) { @@ -1656,7 +1704,6 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) { shadow_atlas->size = p_size; if (shadow_atlas->size) { - RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R32_SFLOAT; tf.width = shadow_atlas->size; @@ -1668,7 +1715,6 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) { } void RasterizerSceneRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_INDEX(p_quadrant, 4); @@ -1683,12 +1729,12 @@ void RasterizerSceneRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p //obtain the number that will be x*x - if (shadow_atlas->quadrants[p_quadrant].subdivision == subdiv) + if (shadow_atlas->quadrants[p_quadrant].subdivision == subdiv) { return; + } //erase all data from quadrant for (int i = 0; i < shadow_atlas->quadrants[p_quadrant].shadows.size(); i++) { - if (shadow_atlas->quadrants[p_quadrant].shadows[i].owner.is_valid()) { shadow_atlas->shadow_owners.erase(shadow_atlas->quadrants[p_quadrant].shadows[i].owner); LightInstance *li = light_instance_owner.getornull(shadow_atlas->quadrants[p_quadrant].shadows[i].owner); @@ -1731,9 +1777,7 @@ void RasterizerSceneRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p } bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow) { - for (int i = p_quadrant_count - 1; i >= 0; i--) { - int qidx = p_in_quadrants[i]; if (shadow_atlas->quadrants[qidx].subdivision == (uint32_t)p_current_subdiv) { @@ -1758,10 +1802,10 @@ bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int ERR_CONTINUE(!sli); if (sli->last_scene_pass != scene_pass) { - //was just allocated, don't kill it so soon, wait a bit.. - if (p_tick - sarr[j].alloc_tick < shadow_atlas_realloc_tolerance_msec) + if (p_tick - sarr[j].alloc_tick < shadow_atlas_realloc_tolerance_msec) { continue; + } if (found_used_idx == -1 || sli->last_scene_pass < min_pass) { found_used_idx = j; @@ -1770,8 +1814,9 @@ bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int } } - if (found_free_idx == -1 && found_used_idx == -1) + if (found_free_idx == -1 && found_used_idx == -1) { continue; //nothing found + } if (found_free_idx == -1 && found_used_idx != -1) { found_free_idx = found_used_idx; @@ -1787,7 +1832,6 @@ bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int } bool RasterizerSceneRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); ERR_FAIL_COND_V(!shadow_atlas, false); @@ -1810,13 +1854,15 @@ bool RasterizerSceneRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intan for (int i = 0; i < 4; i++) { int q = shadow_atlas->size_order[i]; int sd = shadow_atlas->quadrants[q].subdivision; - if (sd == 0) + if (sd == 0) { continue; //unused + } int max_fit = quad_size / sd; - if (best_size != -1 && max_fit > best_size) + if (best_size != -1 && max_fit > best_size) { break; //too large + } valid_quadrants[valid_quadrant_count++] = q; best_subdiv = sd; @@ -1921,7 +1967,6 @@ bool RasterizerSceneRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intan } void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) { - p_size = nearest_power_of_2_templated(p_size); if (directional_shadow.size == p_size) { @@ -1936,7 +1981,6 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) { } if (p_size > 0) { - RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R32_SFLOAT; tf.width = p_size; @@ -1950,13 +1994,11 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) { } void RasterizerSceneRD::set_directional_shadow_count(int p_count) { - directional_shadow.light_count = p_count; directional_shadow.current_light = 0; } static Rect2i _get_directional_shadow_rect(int p_size, int p_shadow_count, int p_shadow_index) { - int split_h = 1; int split_v = 1; @@ -1979,7 +2021,6 @@ static Rect2i _get_directional_shadow_rect(int p_size, int p_shadow_count, int p } int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) { - ERR_FAIL_COND_V(directional_shadow.light_count == 0, 0); Rect2i r = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, 0); @@ -2004,18 +2045,15 @@ int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) { ////////////////////////////////////////////////// RID RasterizerSceneRD::camera_effects_create() { - return camera_effects_owner.make_rid(CameraEffects()); } void RasterizerSceneRD::camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) { - dof_blur_quality = p_quality; dof_blur_use_jitter = p_use_jitter; } void RasterizerSceneRD::camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) { - dof_blur_bokeh_shape = p_shape; } @@ -2035,7 +2073,6 @@ void RasterizerSceneRD::camera_effects_set_dof_blur(RID p_camera_effects, bool p } void RasterizerSceneRD::camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) { - CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects); ERR_FAIL_COND(!camfx); @@ -2044,7 +2081,6 @@ void RasterizerSceneRD::camera_effects_set_custom_exposure(RID p_camera_effects, } RID RasterizerSceneRD::light_instance_create(RID p_light) { - RID li = light_instance_owner.make_rid(LightInstance()); LightInstance *light_instance = light_instance_owner.getornull(li); @@ -2057,7 +2093,6 @@ RID RasterizerSceneRD::light_instance_create(RID p_light) { } void RasterizerSceneRD::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) { - LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); @@ -2065,7 +2100,6 @@ void RasterizerSceneRD::light_instance_set_transform(RID p_light_instance, const } void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { - LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); @@ -2086,7 +2120,6 @@ void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance } void RasterizerSceneRD::light_instance_mark_visible(RID p_light_instance) { - LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); @@ -2094,9 +2127,7 @@ void RasterizerSceneRD::light_instance_mark_visible(RID p_light_instance) { } RasterizerSceneRD::ShadowCubemap *RasterizerSceneRD::_get_shadow_cubemap(int p_size) { - if (!shadow_cubemaps.has(p_size)) { - ShadowCubemap sc; { RD::TextureFormat tf; @@ -2123,9 +2154,7 @@ RasterizerSceneRD::ShadowCubemap *RasterizerSceneRD::_get_shadow_cubemap(int p_s } RasterizerSceneRD::ShadowMap *RasterizerSceneRD::_get_shadow_map(const Size2i &p_size) { - if (!shadow_maps.has(p_size)) { - ShadowMap sm; { RD::TextureFormat tf; @@ -2185,7 +2214,6 @@ RID RasterizerSceneRD::gi_probe_instance_create(RID p_base) { } void RasterizerSceneRD::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) { - GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe); ERR_FAIL_COND(!gi_probe); @@ -2201,7 +2229,6 @@ bool RasterizerSceneRD::gi_probe_needs_update(RID p_probe) const { } void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) { - GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe); ERR_FAIL_COND(!gi_probe); @@ -2453,7 +2480,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc dmap.depth = RD::get_singleton()->texture_create(dtf, RD::TextureView()); if (gi_probe->dynamic_maps.size() == 0) { - dtf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; dmap.albedo = RD::get_singleton()->texture_create(dtf, RD::TextureView()); @@ -2561,7 +2587,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc } if (write) { - { RD::Uniform u; u.type = RD::UNIFORM_TYPE_IMAGE; @@ -2594,7 +2619,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc } if (plot) { - { RD::Uniform u; u.type = RD::UNIFORM_TYPE_IMAGE; @@ -2648,7 +2672,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc uint32_t light_count = 0; if (p_update_light_instances || p_dynamic_object_count > 0) { - light_count = MIN(gi_probe_max_lights, (uint32_t)p_light_instances.size()); { @@ -2728,9 +2751,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc int wg_limit_x = RD::get_singleton()->limit_get(RD::LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X); for (int pass = 0; pass < passes; pass++) { - if (p_update_light_instances) { - for (int i = 0; i < gi_probe->mipmaps.size(); i++) { if (i == 0) { RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_lighting_shader_version_pipelines[pass == 0 ? GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT : GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE]); @@ -2766,7 +2787,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_WRITE_TEXTURE]); for (int i = 0; i < gi_probe->mipmaps.size(); i++) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi_probe->mipmaps[i].write_uniform_set, 0); push_constant.cell_offset = gi_probe->mipmaps[i].cell_offset; @@ -2790,7 +2810,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc gi_probe->has_dynamic_object_data = false; //clear until dynamic object data is used again if (p_dynamic_object_count && gi_probe->dynamic_maps.size()) { - Vector3i octree_size = storage->gi_probe_get_octree_size(gi_probe->probe); int multiplier = gi_probe->dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z); @@ -2805,7 +2824,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc //this could probably be better parallelized in compute.. for (int i = 0; i < p_dynamic_object_count; i++) { - InstanceBase *instance = p_dynamic_objects[i]; //not used, so clear instance->depth_layer = 0; @@ -2834,7 +2852,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc //print_line("aabb: " + aabb); for (int j = 0; j < 6; j++) { - //if (j != 0 && j != 3) { // continue; //} @@ -2923,7 +2940,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc //print_line("rect: " + itos(i) + ": " + rect); for (int k = 1; k < gi_probe->dynamic_maps.size(); k++) { - // enlarge the rect if needed so all pixels fit when downscaled, // this ensures downsampling is smooth and optimal because no pixels are left behind @@ -3021,7 +3037,6 @@ void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_lis for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - push_constant.projection[i * 4 + j] = transform.matrix[i][j]; } } @@ -3084,7 +3099,6 @@ void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_lis } const Vector<RID> &RasterizerSceneRD::gi_probe_get_slots() const { - return gi_probe_slots; } @@ -3123,7 +3137,6 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) { int base_height = rb->height; for (uint32_t i = 0; i < mipmaps_required; i++) { - RenderBuffers::Blur::Mipmap mm; mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[0].texture, 0, i); @@ -3133,7 +3146,6 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) { rb->blur[0].mipmaps.push_back(mm); if (i > 0) { - mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[1].texture, 0, i - 1); rb->blur[1].mipmaps.push_back(mm); @@ -3178,7 +3190,6 @@ void RasterizerSceneRD::_allocate_luminance_textures(RenderBuffers *rb) { } void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) { - if (rb->texture.is_valid()) { RD::get_singleton()->free(rb->texture); rb->texture = RID(); @@ -3244,7 +3255,6 @@ void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) { } void RasterizerSceneRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -3264,7 +3274,6 @@ void RasterizerSceneRD::_process_sss(RID p_render_buffers, const CameraMatrix &p } void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_roughness_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -3318,7 +3327,6 @@ void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffe } void RasterizerSceneRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -3386,7 +3394,6 @@ void RasterizerSceneRD::_process_ssao(RID p_render_buffers, RID p_environment, R } void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -3397,7 +3404,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu bool can_use_effects = rb->width >= 8 && rb->height >= 8; if (can_use_effects && camfx && (camfx->dof_blur_near_enabled || camfx->dof_blur_far_enabled) && camfx->dof_blur_amount > 0.0) { - if (rb->blur[0].texture.is_null()) { _allocate_blur_textures(rb); _render_buffers_uniform_set_changed(p_render_buffers); @@ -3408,7 +3414,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu } if (can_use_effects && env && env->auto_exposure) { - if (rb->luminance.current.is_null()) { _allocate_luminance_textures(rb); _render_buffers_uniform_set_changed(p_render_buffers); @@ -3429,7 +3434,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu int glow_mask = 0; if (can_use_effects && env && env->glow_enabled) { - /* see that blur textures are allocated */ if (rb->blur[0].texture.is_null()) { @@ -3439,7 +3443,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) { if (env->glow_levels & (1 << i)) { - if (i >= rb->blur[1].mipmaps.size()) { max_glow_level = rb->blur[1].mipmaps.size() - 1; glow_mask |= 1 << max_glow_level; @@ -3452,7 +3455,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu } for (int i = 0; i < (max_glow_level + 1); i++) { - int vp_w = rb->blur[1].mipmaps[i].width; int vp_h = rb->blur[1].mipmaps[i].height; @@ -3479,7 +3481,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu tonemap.exposure_texture = rb->luminance.current; tonemap.auto_exposure_grey = env->auto_exp_scale; } else { - tonemap.exposure_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE); } @@ -3574,7 +3575,6 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s } RID RasterizerSceneRD::render_buffers_get_back_buffer_texture(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); if (!rb->blur[0].texture.is_valid()) { @@ -3591,7 +3591,6 @@ RID RasterizerSceneRD::render_buffers_get_ao_texture(RID p_render_buffers) { } void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); rb->width = p_width; rb->height = p_height; @@ -3646,7 +3645,6 @@ void RasterizerSceneRD::sub_surface_scattering_set_scale(float p_scale, float p_ } void RasterizerSceneRD::shadows_quality_set(RS::ShadowQuality p_quality) { - ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum"); if (shadows_quality != p_quality) { @@ -3687,7 +3685,6 @@ void RasterizerSceneRD::shadows_quality_set(RS::ShadowQuality p_quality) { } void RasterizerSceneRD::directional_shadow_quality_set(RS::ShadowQuality p_quality) { - ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum"); if (directional_shadow_quality != p_quality) { @@ -3741,8 +3738,7 @@ RasterizerSceneRD::RenderBufferData *RasterizerSceneRD::render_buffers_get_data( return rb->data; } -void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_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) { - +void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_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) { Color clear_color; if (p_render_buffers.is_valid()) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); @@ -3752,7 +3748,7 @@ void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_ca clear_color = storage->get_default_clear_color(); } - _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_light_cull_result, p_light_cull_count, p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_gi_probe_cull_result, p_gi_probe_cull_count, p_decal_cull_result, p_decal_cull_count, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color); + _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_light_cull_result, p_light_cull_count, p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_gi_probe_cull_result, p_gi_probe_cull_count, p_decal_cull_result, p_decal_cull_count, p_lightmap_cull_result, p_lightmap_cull_count, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color); if (p_render_buffers.is_valid()) { RENDER_TIMESTAMP("Tonemap"); @@ -3763,7 +3759,6 @@ void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_ca } void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) { - LightInstance *light_instance = light_instance_owner.getornull(p_light); ERR_FAIL_COND(!light_instance); @@ -3805,7 +3800,6 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas atlas_rect.size.height = light_instance->directional_rect.size.y; if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { - atlas_rect.size.width /= 2; atlas_rect.size.height /= 2; @@ -3819,11 +3813,9 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas } } else if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) { - atlas_rect.size.height /= 2; if (p_pass == 0) { - } else { atlas_rect.position.y += atlas_rect.size.height; } @@ -3876,9 +3868,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS); if (storage->light_get_type(light_instance->light) == RS::LIGHT_OMNI) { - if (storage->light_omni_get_shadow_mode(light_instance->light) == RS::LIGHT_OMNI_SHADOW_CUBE) { - ShadowCubemap *cubemap = _get_shadow_cubemap(shadow_size / 2); render_fb = cubemap->side_fb[p_pass]; @@ -3890,7 +3880,6 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas finalize_cubemap = p_pass == 5; } else { - light_projection = light_instance->shadow_transform[0].camera; light_transform = light_instance->shadow_transform[0].transform; @@ -3906,7 +3895,6 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas } } else if (storage->light_get_type(light_instance->light) == RS::LIGHT_SPOT) { - light_projection = light_instance->shadow_transform[0].camera; light_transform = light_instance->shadow_transform[0].transform; @@ -3947,12 +3935,10 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas } void RasterizerSceneRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) { - _render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_framebuffer, p_region); } bool RasterizerSceneRD::free(RID p_rid) { - if (render_buffers_owner.owns(p_rid)) { RenderBuffers *rb = render_buffers_owner.getornull(p_rid); _free_render_buffer_data(rb); @@ -4024,7 +4010,6 @@ bool RasterizerSceneRD::free(RID p_rid) { sky_owner.free(p_rid); } else if (light_instance_owner.owns(p_rid)) { - LightInstance *light_instance = light_instance_owner.getornull(p_rid); //remove from shadow atlases.. @@ -4042,7 +4027,6 @@ bool RasterizerSceneRD::free(RID p_rid) { light_instance_owner.free(p_rid); } else if (shadow_atlas_owner.owns(p_rid)) { - shadow_atlas_set_size(p_rid, 0); shadow_atlas_owner.free(p_rid); @@ -4079,6 +4063,97 @@ float RasterizerSceneRD::screen_space_roughness_limiter_get_curve() const { return screen_space_roughness_limiter_curve; } +TypedArray<Image> RasterizerSceneRD::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + tf.width = p_image_size.width; // Always 64x64 + tf.height = p_image_size.height; + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + + RID albedo_alpha_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RID normal_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RID orm_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + RID emission_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + tf.format = RD::DATA_FORMAT_R32_SFLOAT; + RID depth_write_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32; + RID depth_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + Vector<RID> fb_tex; + fb_tex.push_back(albedo_alpha_tex); + fb_tex.push_back(normal_tex); + fb_tex.push_back(orm_tex); + fb_tex.push_back(emission_tex); + fb_tex.push_back(depth_write_tex); + fb_tex.push_back(depth_tex); + + RID fb = RD::get_singleton()->framebuffer_create(fb_tex); + + //RID sampled_light; + + InstanceBase ins; + + ins.base_type = RSG::storage->get_base_type(p_base); + ins.base = p_base; + ins.materials.resize(RSG::storage->mesh_get_surface_count(p_base)); + for (int i = 0; i < ins.materials.size(); i++) { + if (i < p_material_overrides.size()) { + ins.materials.write[i] = p_material_overrides[i]; + } + } + + InstanceBase *cull = &ins; + _render_uv2(&cull, 1, fb, Rect2i(0, 0, p_image_size.width, p_image_size.height)); + + TypedArray<Image> ret; + + { + PackedByteArray data = RD::get_singleton()->texture_get_data(albedo_alpha_tex, 0); + Ref<Image> img; + img.instance(); + img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); + RD::get_singleton()->free(albedo_alpha_tex); + ret.push_back(img); + } + + { + PackedByteArray data = RD::get_singleton()->texture_get_data(normal_tex, 0); + Ref<Image> img; + img.instance(); + img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); + RD::get_singleton()->free(normal_tex); + ret.push_back(img); + } + + { + PackedByteArray data = RD::get_singleton()->texture_get_data(orm_tex, 0); + Ref<Image> img; + img.instance(); + img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); + RD::get_singleton()->free(orm_tex); + ret.push_back(img); + } + + { + PackedByteArray data = RD::get_singleton()->texture_get_data(emission_tex, 0); + Ref<Image> img; + img.instance(); + img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBAH, data); + RD::get_singleton()->free(emission_tex); + ret.push_back(img); + } + + RD::get_singleton()->free(depth_write_tex); + RD::get_singleton()->free(depth_tex); + + return ret; +} + RasterizerSceneRD *RasterizerSceneRD::singleton = nullptr; RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { @@ -4093,7 +4168,6 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); { - //kinda complicated to compute the amount of slots, we try to use as many as we can gi_probe_max_lights = 32; @@ -4148,7 +4222,6 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { } { - String defines; if (gi_probe_use_anisotropy) { defines += "\n#define USE_ANISOTROPY\n"; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h index a511838e16..781dbd50cc 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h @@ -52,7 +52,6 @@ protected: // Skys need less info from Directional Lights than the normal shaders struct SkyDirectionalLightData { - float direction[3]; float energy; float color[3]; @@ -62,7 +61,6 @@ protected: }; struct SkySceneState { - SkyDirectionalLightData *directional_lights; SkyDirectionalLightData *last_frame_directional_lights; uint32_t max_directional_lights; @@ -74,15 +72,15 @@ protected: } sky_scene_state; struct RenderBufferData { - virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) = 0; virtual ~RenderBufferData() {} }; virtual RenderBufferData *_create_render_buffer_data() = 0; - 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, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_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_color) = 0; + 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, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_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_color) = 0; 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 use_dp_flip, bool p_use_pancake) = 0; virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0; + virtual void _render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); @@ -111,7 +109,6 @@ private: RasterizerStorageRD *storage; struct ReflectionData { - struct Layer { struct Mipmap { RID framebuffers[6]; @@ -286,7 +283,6 @@ private: /* REFLECTION ATLAS */ struct ReflectionAtlas { - int count = 0; int size = 0; @@ -308,7 +304,6 @@ private: /* REFLECTION PROBE INSTANCE */ struct ReflectionProbeInstance { - RID probe; int atlas_index = -1; RID atlas; @@ -330,7 +325,6 @@ private: /* REFLECTION PROBE INSTANCE */ struct DecalInstance { - RID decal; Transform transform; }; @@ -340,7 +334,6 @@ private: /* GIPROBE INSTANCE */ struct GIProbeLight { - uint32_t type; float energy; float radius; @@ -357,7 +350,6 @@ private: }; struct GIProbePushConstant { - int32_t limits[3]; uint32_t stack_size; @@ -373,7 +365,6 @@ private: }; struct GIProbeDynamicPushConstant { - int32_t limits[3]; uint32_t light_count; int32_t x_dir[3]; @@ -395,7 +386,6 @@ private: }; struct GIProbeInstance { - RID probe; RID texture; RID anisotropy[2]; //only if anisotropy is used @@ -495,7 +485,6 @@ private: /* SHADOW ATLAS */ struct ShadowAtlas { - enum { QUADRANT_SHIFT = 27, SHADOW_INDEX_MASK = (1 << QUADRANT_SHIFT) - 1, @@ -503,7 +492,6 @@ private: }; struct Quadrant { - uint32_t subdivision; struct Shadow { @@ -567,7 +555,6 @@ private: /* SHADOW CUBEMAPS */ struct ShadowCubemap { - RID cubemap; RID side_fb[6]; }; @@ -588,9 +575,7 @@ private: /* LIGHT INSTANCE */ struct LightInstance { - struct ShadowTransform { - CameraMatrix camera; Transform transform; float farplane; @@ -637,7 +622,6 @@ private: /* ENVIRONMENT */ struct Environent { - // BG RS::EnvironmentBG background = RS::ENV_BG_CLEAR_COLOR; RID sky; @@ -710,7 +694,6 @@ private: /* CAMERA EFFECTS */ struct CameraEffects { - bool dof_blur_far_enabled = false; float dof_blur_far_distance = 10; float dof_blur_far_transition = 5; @@ -737,7 +720,6 @@ private: /* RENDER BUFFERS */ struct RenderBuffers { - RenderBufferData *data = nullptr; int width = 0, height = 0; RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; @@ -766,7 +748,6 @@ private: Blur blur[2]; //the second one starts from the first mipmap struct Luminance { - Vector<RID> reduce; RID current; } luminance; @@ -843,6 +824,7 @@ public: void sky_set_radiance_size(RID p_sky, int p_radiance_size); void sky_set_mode(RID p_sky, RS::SkyMode p_mode); void sky_set_material(RID p_sky, RID p_material); + Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size); RID sky_get_radiance_texture_rd(RID p_sky) const; RID sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, int p_set) const; @@ -900,6 +882,8 @@ public: void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) {} void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {} + virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size); + virtual RID camera_effects_create(); virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter); @@ -924,7 +908,6 @@ public: } _FORCE_INLINE_ Rect2 light_instance_get_shadow_atlas_rect(RID p_light_instance, RID p_shadow_atlas) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); LightInstance *li = light_instance_owner.getornull(p_light_instance); uint32_t key = shadow_atlas->shadow_owners[li->self]; @@ -951,13 +934,11 @@ public: } _FORCE_INLINE_ CameraMatrix light_instance_get_shadow_camera(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].camera; } _FORCE_INLINE_ float light_instance_get_shadow_texel_size(RID p_light_instance, RID p_shadow_atlas) { - #ifdef DEBUG_ENABLED LightInstance *li = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND_V(!li->shadow_atlases.has(p_shadow_atlas), 0); @@ -980,46 +961,38 @@ public: _FORCE_INLINE_ Transform light_instance_get_shadow_transform(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].transform; } _FORCE_INLINE_ float light_instance_get_shadow_bias_scale(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].bias_scale; } _FORCE_INLINE_ float light_instance_get_shadow_range(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].farplane; } _FORCE_INLINE_ float light_instance_get_shadow_range_begin(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].range_begin; } _FORCE_INLINE_ Vector2 light_instance_get_shadow_uv_scale(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].uv_scale; } _FORCE_INLINE_ Rect2 light_instance_get_directional_shadow_atlas_rect(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].atlas_rect; } _FORCE_INLINE_ float light_instance_get_directional_shadow_split(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].split; } _FORCE_INLINE_ float light_instance_get_directional_shadow_texel_size(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].shadow_texel_size; } @@ -1194,7 +1167,7 @@ public: RID render_buffers_get_ao_texture(RID p_render_buffers); RID render_buffers_get_back_buffer_texture(RID p_render_buffers); - void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_shadow_atlas, RID p_camera_effects, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass); + void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_shadow_atlas, RID p_camera_effects, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass); void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count); @@ -1235,6 +1208,8 @@ public: int get_roughness_layers() const; bool is_using_radiance_cubemap_array() const; + virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size); + virtual bool free(RID p_rid); virtual void update(); diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp index 8d299d623a..4f216d7cb5 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp @@ -36,7 +36,6 @@ #include "servers/rendering/shader_language.h" Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) { - Ref<Image> image = p_image->duplicate(); switch (p_image->get_format()) { @@ -403,7 +402,6 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima } break; //etc2 case Image::FORMAT_ETC2_R11S: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { r_format.format = RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK; } else { @@ -481,7 +479,6 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; } break; case Image::FORMAT_ETC2_RGB8A1: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK; r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK; @@ -498,7 +495,6 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; } break; case Image::FORMAT_ETC2_RA_AS_RG: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK; r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK; @@ -609,11 +605,116 @@ RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) { } RID RasterizerStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) { + ERR_FAIL_COND_V(p_layers.size() == 0, RID()); - return RID(); + ERR_FAIL_COND_V(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6, RID()); + ERR_FAIL_COND_V(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY && (p_layers.size() < 6 || (p_layers.size() % 6) != 0), RID()); + + TextureToRDFormat ret_format; + Vector<Ref<Image>> images; + { + int valid_width = 0; + int valid_height = 0; + bool valid_mipmaps = false; + Image::Format valid_format = Image::FORMAT_MAX; + + for (int i = 0; i < p_layers.size(); i++) { + ERR_FAIL_COND_V(p_layers[i]->empty(), RID()); + + if (i == 0) { + valid_width = p_layers[i]->get_width(); + valid_height = p_layers[i]->get_height(); + valid_format = p_layers[i]->get_format(); + valid_mipmaps = p_layers[i]->has_mipmaps(); + } else { + ERR_FAIL_COND_V(p_layers[i]->get_width() != valid_width, RID()); + ERR_FAIL_COND_V(p_layers[i]->get_height() != valid_height, RID()); + ERR_FAIL_COND_V(p_layers[i]->get_format() != valid_format, RID()); + ERR_FAIL_COND_V(p_layers[i]->has_mipmaps() != valid_mipmaps, RID()); + } + + images.push_back(_validate_texture_format(p_layers[i], ret_format)); + } + } + + Texture texture; + + texture.type = Texture::TYPE_LAYERED; + texture.layered_type = p_layered_type; + + texture.width = p_layers[0]->get_width(); + texture.height = p_layers[0]->get_height(); + texture.layers = p_layers.size(); + texture.mipmaps = p_layers[0]->get_mipmap_count() + 1; + texture.depth = 1; + texture.format = p_layers[0]->get_format(); + texture.validated_format = images[0]->get_format(); + + switch (p_layered_type) { + case RS::TEXTURE_LAYERED_2D_ARRAY: { + texture.rd_type = RD::TEXTURE_TYPE_2D_ARRAY; + } break; + case RS::TEXTURE_LAYERED_CUBEMAP: { + texture.rd_type = RD::TEXTURE_TYPE_CUBE; + } break; + case RS::TEXTURE_LAYERED_CUBEMAP_ARRAY: { + texture.rd_type = RD::TEXTURE_TYPE_CUBE_ARRAY; + } break; + } + + texture.rd_format = ret_format.format; + texture.rd_format_srgb = ret_format.format_srgb; + + RD::TextureFormat rd_format; + RD::TextureView rd_view; + { //attempt register + rd_format.format = texture.rd_format; + rd_format.width = texture.width; + rd_format.height = texture.height; + rd_format.depth = 1; + rd_format.array_layers = texture.layers; + rd_format.mipmaps = texture.mipmaps; + rd_format.type = texture.rd_type; + rd_format.samples = RD::TEXTURE_SAMPLES_1; + rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { + rd_format.shareable_formats.push_back(texture.rd_format); + rd_format.shareable_formats.push_back(texture.rd_format_srgb); + } + } + { + rd_view.swizzle_r = ret_format.swizzle_r; + rd_view.swizzle_g = ret_format.swizzle_g; + rd_view.swizzle_b = ret_format.swizzle_b; + rd_view.swizzle_a = ret_format.swizzle_a; + } + Vector<Vector<uint8_t>> data_slices; + for (int i = 0; i < images.size(); i++) { + Vector<uint8_t> data = images[i]->get_data(); //use image data + data_slices.push_back(data); + } + texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); + ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID()); + if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { + rd_view.format_override = texture.rd_format_srgb; + texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); + if (texture.rd_texture_srgb.is_null()) { + RD::get_singleton()->free(texture.rd_texture); + ERR_FAIL_COND_V(texture.rd_texture_srgb.is_null(), RID()); + } + } + + //used for 2D, overridable + texture.width_2d = texture.width; + texture.height_2d = texture.height; + texture.is_render_target = false; + texture.rd_view = rd_view; + texture.is_proxy = false; + + return texture_owner.make_rid(texture); } -RID RasterizerStorageRD::texture_3d_create(const Vector<Ref<Image>> &p_slices) { +RID RasterizerStorageRD::texture_3d_create(const Vector<Ref<Image>> &p_slices) { return RID(); } @@ -641,7 +742,6 @@ RID RasterizerStorageRD::texture_proxy_create(RID p_base) { } void RasterizerStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) { - ERR_FAIL_COND(p_image.is_null() || p_image->empty()); Texture *tex = texture_owner.getornull(p_texture); @@ -666,14 +766,15 @@ void RasterizerStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_ void RasterizerStorageRD::texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer) { _texture_2d_update(p_texture, p_image, p_layer, true); } + void RasterizerStorageRD::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) { _texture_2d_update(p_texture, p_image, p_layer, false); } + void RasterizerStorageRD::texture_3d_update(RID p_texture, const Ref<Image> &p_image, int p_depth, int p_mipmap) { } void RasterizerStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) { - Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); ERR_FAIL_COND(!tex->is_proxy); @@ -714,7 +815,6 @@ void RasterizerStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) { //these two APIs can be used together or in combination with the others. RID RasterizerStorageRD::texture_2d_placeholder_create() { - //this could be better optimized to reuse an existing image , done this way //for now to get it working Ref<Image> image; @@ -729,17 +829,38 @@ RID RasterizerStorageRD::texture_2d_placeholder_create() { return texture_2d_create(image); } -RID RasterizerStorageRD::texture_2d_layered_placeholder_create() { - return RID(); +RID RasterizerStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayeredType p_layered_type) { + //this could be better optimized to reuse an existing image , done this way + //for now to get it working + Ref<Image> image; + image.instance(); + image->create(4, 4, false, Image::FORMAT_RGBA8); + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + image->set_pixel(i, j, Color(1, 0, 1, 1)); + } + } + + Vector<Ref<Image>> images; + if (p_layered_type == RS::TEXTURE_LAYERED_2D_ARRAY) { + images.push_back(image); + } else { + //cube + for (int i = 0; i < 6; i++) { + images.push_back(image); + } + } + + return texture_2d_layered_create(images, p_layered_type); } -RID RasterizerStorageRD::texture_3d_placeholder_create() { +RID RasterizerStorageRD::texture_3d_placeholder_create() { return RID(); } Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const { - Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND_V(!tex, Ref<Image>()); @@ -766,17 +887,16 @@ Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const { return image; } -Ref<Image> RasterizerStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) const { +Ref<Image> RasterizerStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) const { return Ref<Image>(); } -Ref<Image> RasterizerStorageRD::texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const { +Ref<Image> RasterizerStorageRD::texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const { return Ref<Image>(); } void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) { - Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); ERR_FAIL_COND(tex->proxy_to.is_valid()); //cant replace proxy @@ -815,6 +935,7 @@ void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) { decal_atlas.dirty = true; //mark it dirty since it was most likely modified } } + void RasterizerStorageRD::texture_set_size_override(RID p_texture, int p_width, int p_height) { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); @@ -828,6 +949,7 @@ void RasterizerStorageRD::texture_set_path(RID p_texture, const String &p_path) ERR_FAIL_COND(!tex); tex->path = p_path; } + String RasterizerStorageRD::texture_get_path(RID p_texture) const { return String(); } @@ -838,23 +960,27 @@ void RasterizerStorageRD::texture_set_detect_3d_callback(RID p_texture, RS::Text tex->detect_3d_callback_ud = p_userdata; tex->detect_3d_callback = p_callback; } + void RasterizerStorageRD::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); tex->detect_normal_callback_ud = p_userdata; tex->detect_normal_callback = p_callback; } + void RasterizerStorageRD::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); tex->detect_roughness_callback_ud = p_userdata; tex->detect_roughness_callback = p_callback; } + void RasterizerStorageRD::texture_debug_usage(List<RS::TextureInfo> *r_info) { } void RasterizerStorageRD::texture_set_proxy(RID p_proxy, RID p_base) { } + void RasterizerStorageRD::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) { } @@ -865,7 +991,6 @@ Size2 RasterizerStorageRD::texture_size_with_proxy(RID p_proxy) { /* SHADER API */ RID RasterizerStorageRD::shader_create() { - Shader shader; shader.data = nullptr; shader.type = SHADER_TYPE_MAX; @@ -881,16 +1006,17 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) { String mode_string = ShaderLanguage::get_shader_type(p_code); ShaderType new_type; - if (mode_string == "canvas_item") + if (mode_string == "canvas_item") { new_type = SHADER_TYPE_2D; - else if (mode_string == "particles") + } else if (mode_string == "particles") { new_type = SHADER_TYPE_PARTICLES; - else if (mode_string == "spatial") + } else if (mode_string == "spatial") { new_type = SHADER_TYPE_3D; - else if (mode_string == "sky") + } else if (mode_string == "sky") { new_type = SHADER_TYPE_SKY; - else + } else { new_type = SHADER_TYPE_MAX; + } if (new_type != shader->type) { if (shader->data) { @@ -899,7 +1025,6 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) { } for (Set<Material *>::Element *E = shader->owners.front(); E; E = E->next()) { - Material *material = E->get(); material->shader_type = new_type; if (material->data) { @@ -944,8 +1069,8 @@ String RasterizerStorageRD::shader_get_code(RID p_shader) const { ERR_FAIL_COND_V(!shader, String()); return shader->code; } -void RasterizerStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const { +void RasterizerStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const { Shader *shader = shader_owner.getornull(p_shader); ERR_FAIL_COND(!shader); if (shader->data) { @@ -954,7 +1079,6 @@ void RasterizerStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> } void RasterizerStorageRD::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) { - Shader *shader = shader_owner.getornull(p_shader); ERR_FAIL_COND(!shader); @@ -979,6 +1103,7 @@ RID RasterizerStorageRD::shader_get_default_texture_param(RID p_shader, const St return RID(); } + Variant RasterizerStorageRD::shader_get_param_default(RID p_shader, const StringName &p_param) const { Shader *shader = shader_owner.getornull(p_shader); ERR_FAIL_COND_V(!shader, Variant()); @@ -987,6 +1112,7 @@ Variant RasterizerStorageRD::shader_get_param_default(RID p_shader, const String } return Variant(); } + void RasterizerStorageRD::shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function) { ERR_FAIL_INDEX(p_shader_type, SHADER_TYPE_MAX); shader_data_request_func[p_shader_type] = p_function; @@ -995,7 +1121,6 @@ void RasterizerStorageRD::shader_set_data_request_function(ShaderType p_shader_t /* COMMON MATERIAL API */ RID RasterizerStorageRD::material_create() { - Material material; material.data = nullptr; material.shader = nullptr; @@ -1026,7 +1151,6 @@ void RasterizerStorageRD::_material_queue_update(Material *material, bool p_unif } void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) { - Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); @@ -1068,7 +1192,6 @@ void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) { } void RasterizerStorageRD::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) { - Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); @@ -1111,6 +1234,7 @@ void RasterizerStorageRD::material_set_next_pass(RID p_material, RID p_next_mate material->instance_dependency.instance_notify_changed(false, true); } + void RasterizerStorageRD::material_set_render_priority(RID p_material, int priority) { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); @@ -1132,6 +1256,7 @@ bool RasterizerStorageRD::material_is_animated(RID p_material) { } return false; //by default nothing is animated } + bool RasterizerStorageRD::material_casts_shadows(RID p_material) { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND_V(!material, true); @@ -1146,7 +1271,6 @@ bool RasterizerStorageRD::material_casts_shadows(RID p_material) { } void RasterizerStorageRD::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) { - Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); if (material->shader && material->shader->data) { @@ -1175,14 +1299,12 @@ void RasterizerStorageRD::material_set_data_request_function(ShaderType p_shader _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, const Variant &value, uint8_t *data, bool p_linear_color) { switch (type) { case ShaderLanguage::TYPE_BOOL: { - bool v = value; uint32_t *gui = (uint32_t *)data; *gui = v ? 1 : 0; } break; case ShaderLanguage::TYPE_BVEC2: { - int v = value; uint32_t *gui = (uint32_t *)data; gui[0] = v & 1 ? 1 : 0; @@ -1190,7 +1312,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } break; case ShaderLanguage::TYPE_BVEC3: { - int v = value; uint32_t *gui = (uint32_t *)data; gui[0] = (v & 1) ? 1 : 0; @@ -1199,7 +1320,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } break; case ShaderLanguage::TYPE_BVEC4: { - int v = value; uint32_t *gui = (uint32_t *)data; gui[0] = (v & 1) ? 1 : 0; @@ -1209,14 +1329,12 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } break; case ShaderLanguage::TYPE_INT: { - int v = value; int32_t *gui = (int32_t *)data; gui[0] = v; } break; case ShaderLanguage::TYPE_IVEC2: { - Vector<int> iv = value; int s = iv.size(); int32_t *gui = (int32_t *)data; @@ -1224,15 +1342,15 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy const int *r = iv.ptr(); for (int i = 0; i < 2; i++) { - if (i < s) + if (i < s) { gui[i] = r[i]; - else + } else { gui[i] = 0; + } } } break; case ShaderLanguage::TYPE_IVEC3: { - Vector<int> iv = value; int s = iv.size(); int32_t *gui = (int32_t *)data; @@ -1240,14 +1358,14 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy const int *r = iv.ptr(); for (int i = 0; i < 3; i++) { - if (i < s) + if (i < s) { gui[i] = r[i]; - else + } else { gui[i] = 0; + } } } break; case ShaderLanguage::TYPE_IVEC4: { - Vector<int> iv = value; int s = iv.size(); int32_t *gui = (int32_t *)data; @@ -1255,21 +1373,20 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy const int *r = iv.ptr(); for (int i = 0; i < 4; i++) { - if (i < s) + if (i < s) { gui[i] = r[i]; - else + } else { gui[i] = 0; + } } } break; case ShaderLanguage::TYPE_UINT: { - int v = value; uint32_t *gui = (uint32_t *)data; gui[0] = v; } break; case ShaderLanguage::TYPE_UVEC2: { - Vector<int> iv = value; int s = iv.size(); uint32_t *gui = (uint32_t *)data; @@ -1277,10 +1394,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy const int *r = iv.ptr(); for (int i = 0; i < 2; i++) { - if (i < s) + if (i < s) { gui[i] = r[i]; - else + } else { gui[i] = 0; + } } } break; case ShaderLanguage::TYPE_UVEC3: { @@ -1291,10 +1409,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy const int *r = iv.ptr(); for (int i = 0; i < 3; i++) { - if (i < s) + if (i < s) { gui[i] = r[i]; - else + } else { gui[i] = 0; + } } } break; @@ -1306,10 +1425,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy const int *r = iv.ptr(); for (int i = 0; i < 4; i++) { - if (i < s) + if (i < s) { gui[i] = r[i]; - else + } else { gui[i] = 0; + } } } break; case ShaderLanguage::TYPE_FLOAT: { @@ -1334,7 +1454,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } break; case ShaderLanguage::TYPE_VEC4: { - float *gui = (float *)data; if (value.get_type() == Variant::COLOR) { @@ -1386,7 +1505,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[7] = 0; } break; case ShaderLanguage::TYPE_MAT3: { - Basis v = value; float *gui = (float *)data; @@ -1404,7 +1522,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[11] = 0; } break; case ShaderLanguage::TYPE_MAT4: { - Transform v = value; float *gui = (float *)data; @@ -1431,22 +1548,18 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, const Vector<ShaderLanguage::ConstantNode::Value> &value, uint8_t *data) { - switch (type) { case ShaderLanguage::TYPE_BOOL: { - uint32_t *gui = (uint32_t *)data; *gui = value[0].boolean ? 1 : 0; } break; case ShaderLanguage::TYPE_BVEC2: { - uint32_t *gui = (uint32_t *)data; gui[0] = value[0].boolean ? 1 : 0; gui[1] = value[1].boolean ? 1 : 0; } break; case ShaderLanguage::TYPE_BVEC3: { - uint32_t *gui = (uint32_t *)data; gui[0] = value[0].boolean ? 1 : 0; gui[1] = value[1].boolean ? 1 : 0; @@ -1454,7 +1567,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_BVEC4: { - uint32_t *gui = (uint32_t *)data; gui[0] = value[0].boolean ? 1 : 0; gui[1] = value[1].boolean ? 1 : 0; @@ -1463,13 +1575,11 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_INT: { - int32_t *gui = (int32_t *)data; gui[0] = value[0].sint; } break; case ShaderLanguage::TYPE_IVEC2: { - int32_t *gui = (int32_t *)data; for (int i = 0; i < 2; i++) { @@ -1478,7 +1588,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_IVEC3: { - int32_t *gui = (int32_t *)data; for (int i = 0; i < 3; i++) { @@ -1487,7 +1596,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_IVEC4: { - int32_t *gui = (int32_t *)data; for (int i = 0; i < 4; i++) { @@ -1496,13 +1604,11 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_UINT: { - uint32_t *gui = (uint32_t *)data; gui[0] = value[0].uint; } break; case ShaderLanguage::TYPE_UVEC2: { - int32_t *gui = (int32_t *)data; for (int i = 0; i < 2; i++) { @@ -1525,13 +1631,11 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } } break; case ShaderLanguage::TYPE_FLOAT: { - float *gui = (float *)data; gui[0] = value[0].real; } break; case ShaderLanguage::TYPE_VEC2: { - float *gui = (float *)data; for (int i = 0; i < 2; i++) { @@ -1540,7 +1644,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_VEC3: { - float *gui = (float *)data; for (int i = 0; i < 3; i++) { @@ -1549,7 +1652,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_VEC4: { - float *gui = (float *)data; for (int i = 0; i < 4; i++) { @@ -1570,7 +1672,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, gui[7] = 0; } break; case ShaderLanguage::TYPE_MAT3: { - float *gui = (float *)data; gui[0] = value[0].real; @@ -1587,7 +1688,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, gui[11] = 0; } break; case ShaderLanguage::TYPE_MAT4: { - float *gui = (float *)data; for (int i = 0; i < 16; i++) { @@ -1600,9 +1700,7 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, uint8_t *data) { - switch (type) { - case ShaderLanguage::TYPE_BOOL: case ShaderLanguage::TYPE_INT: case ShaderLanguage::TYPE_UINT: @@ -1623,15 +1721,12 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, case ShaderLanguage::TYPE_IVEC4: case ShaderLanguage::TYPE_UVEC4: case ShaderLanguage::TYPE_VEC4: { - zeromem(data, 16); } break; case ShaderLanguage::TYPE_MAT2: { - zeromem(data, 32); } break; case ShaderLanguage::TYPE_MAT3: { - zeromem(data, 48); } break; case ShaderLanguage::TYPE_MAT4: { @@ -1644,13 +1739,12 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, } void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) { - bool uses_global_buffer = false; for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_uniforms.front(); E; E = E->next()) { - - if (E->get().order < 0) + if (E->get().order < 0) { continue; // texture, does not go here + } if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; //instance uniforms don't appear in the bufferr @@ -1738,7 +1832,6 @@ RasterizerStorageRD::MaterialData::~MaterialData() { } void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) { - RasterizerStorageRD *singleton = (RasterizerStorageRD *)RasterizerStorage::base_singleton; #ifdef TOOLS_ENABLED Texture *roughness_detect_texture = nullptr; @@ -1750,13 +1843,11 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va global_textures_pass++; for (int i = 0; i < p_texture_uniforms.size(); i++) { - const StringName &uniform_name = p_texture_uniforms[i].name; RID texture; if (p_texture_uniforms[i].global) { - RasterizerStorageRD *rs = base_singleton; uses_global_textures = true; @@ -1767,7 +1858,6 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); } else { - Map<StringName, uint64_t>::Element *E = used_global_textures.find(uniform_name); if (!E) { E = used_global_textures.insert(uniform_name, global_textures_pass); @@ -1784,7 +1874,6 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va } } else { if (!texture.is_valid()) { - const Map<StringName, Variant>::Element *V = p_parameters.find(uniform_name); if (V) { texture = V->get(); @@ -1794,7 +1883,6 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va if (!texture.is_valid()) { const Map<StringName, RID>::Element *W = p_default_textures.find(uniform_name); if (W) { - texture = W->get(); } } @@ -1825,7 +1913,6 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va Texture *tex = singleton->texture_owner.getornull(texture); if (tex) { - rd_texture = (srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture; #ifdef TOOLS_ENABLED if (tex->detect_3d_callback && p_use_linear_color) { @@ -1917,16 +2004,15 @@ void RasterizerStorageRD::_update_queued_materials() { } material_update_list = nullptr; } + /* MESH API */ RID RasterizerStorageRD::mesh_create() { - return mesh_owner.make_rid(Mesh()); } /// Returns stride void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) { - Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); @@ -1937,17 +2023,12 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ #ifdef DEBUG_ENABLED //do a validation, to catch errors first { - uint32_t stride = 0; for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) { - if ((p_surface.format & (1 << i))) { - switch (i) { - case RS::ARRAY_VERTEX: { - if (p_surface.format & RS::ARRAY_FLAG_USE_2D_VERTICES) { stride += sizeof(float) * 2; } else { @@ -1956,7 +2037,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ } break; case RS::ARRAY_NORMAL: { - if (p_surface.format & RS::ARRAY_COMPRESS_NORMAL) { stride += sizeof(int8_t) * 4; } else { @@ -1965,7 +2045,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ } break; case RS::ARRAY_TANGENT: { - if (p_surface.format & RS::ARRAY_COMPRESS_TANGENT) { stride += sizeof(int8_t) * 4; } else { @@ -1974,7 +2053,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ } break; case RS::ARRAY_COLOR: { - if (p_surface.format & RS::ARRAY_COMPRESS_COLOR) { stride += sizeof(int8_t) * 4; } else { @@ -1983,7 +2061,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ } break; case RS::ARRAY_TEX_UV: { - if (p_surface.format & RS::ARRAY_COMPRESS_TEX_UV) { stride += sizeof(int16_t) * 2; } else { @@ -1992,7 +2069,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ } break; case RS::ARRAY_TEX_UV2: { - if (p_surface.format & RS::ARRAY_COMPRESS_TEX_UV2) { stride += sizeof(int16_t) * 2; } else { @@ -2037,7 +2113,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ s->lod_count = p_surface.lods.size(); for (int i = 0; i < p_surface.lods.size(); i++) { - uint32_t indices = p_surface.lods[i].index_data.size() / (is_index_16 ? 2 : 4); s->lods[i].index_buffer = RD::get_singleton()->index_buffer_create(indices, is_index_16 ? RD::INDEX_BUFFER_FORMAT_UINT16 : RD::INDEX_BUFFER_FORMAT_UINT32, p_surface.lods[i].index_data); s->lods[i].index_array = RD::get_singleton()->index_array_create(s->lods[i].index_buffer, 0, indices); @@ -2050,7 +2125,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ s->bone_aabbs = p_surface.bone_aabbs; //only really useful for returning them. for (int i = 0; i < p_surface.blend_shapes.size(); i++) { - if (p_surface.blend_shapes[i].size() != p_surface.vertex_data.size()) { memdelete(s); ERR_FAIL_COND(p_surface.blend_shapes[i].size() != p_surface.vertex_data.size()); @@ -2095,6 +2169,7 @@ void RasterizerStorageRD::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMo mesh->blend_shape_mode = p_mode; } + RS::BlendShapeMode RasterizerStorageRD::mesh_get_blend_shape_mode(RID p_mesh) const { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, RS::BLEND_SHAPE_MODE_NORMALIZED); @@ -2121,6 +2196,7 @@ void RasterizerStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, R mesh->instance_dependency.instance_notify_changed(false, true); mesh->material_cache.clear(); } + RID RasterizerStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) const { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, RID()); @@ -2130,7 +2206,6 @@ RID RasterizerStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) co } RS::SurfaceData RasterizerStorageRD::mesh_get_surface(RID p_mesh, int p_surface) const { - Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, RS::SurfaceData()); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RS::SurfaceData()); @@ -2176,6 +2251,7 @@ void RasterizerStorageRD::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) { ERR_FAIL_COND(!mesh); mesh->custom_aabb = p_aabb; } + AABB RasterizerStorageRD::mesh_get_custom_aabb(RID p_mesh) const { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, AABB()); @@ -2199,10 +2275,8 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { AABB aabb; for (uint32_t i = 0; i < mesh->surface_count; i++) { - AABB laabb; if ((mesh->surfaces[i]->format & RS::ARRAY_FORMAT_BONES) && mesh->surfaces[i]->bone_aabbs.size()) { - int bs = mesh->surfaces[i]->bone_aabbs.size(); const AABB *skbones = mesh->surfaces[i]->bone_aabbs.ptr(); @@ -2214,9 +2288,9 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { if (skeleton->use_2d) { for (int j = 0; j < bs; j++) { - - if (skbones[0].size == Vector3()) + if (skbones[0].size == Vector3()) { continue; //bone is unused + } const float *dataptr = baseptr + j * 8; @@ -2241,9 +2315,9 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { } } else { for (int j = 0; j < bs; j++) { - - if (skbones[0].size == Vector3()) + if (skbones[0].size == Vector3()) { continue; //bone is unused + } const float *dataptr = baseptr + j * 12; @@ -2276,7 +2350,6 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { laabb = mesh->surfaces[i]->aabb; } } else { - laabb = mesh->surfaces[i]->aabb; } @@ -2291,7 +2364,6 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { } void RasterizerStorageRD::mesh_clear(RID p_mesh) { - Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); for (uint32_t i = 0; i < mesh->surface_count; i++) { @@ -2345,7 +2417,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su uint32_t stride = 0; for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) { - RD::VertexAttribute vd; RID buffer; vd.location = i; @@ -2354,9 +2425,7 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su // Not supplied by surface, use default value buffer = mesh_default_rd_buffers[i]; switch (i) { - case RS::ARRAY_VERTEX: { - vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT; } break; @@ -2364,25 +2433,20 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT; } break; case RS::ARRAY_TANGENT: { - vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; } break; case RS::ARRAY_COLOR: { - vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; } break; case RS::ARRAY_TEX_UV: { - vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; } break; case RS::ARRAY_TEX_UV2: { - vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; } break; case RS::ARRAY_BONES: { - //assumed weights too vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; } break; @@ -2395,9 +2459,7 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su buffer = s->vertex_buffer; switch (i) { - case RS::ARRAY_VERTEX: { - if (s->format & RS::ARRAY_FLAG_USE_2D_VERTICES) { vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; stride += sizeof(float) * 2; @@ -2408,7 +2470,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su } break; case RS::ARRAY_NORMAL: { - if (s->format & RS::ARRAY_COMPRESS_NORMAL) { vd.format = RD::DATA_FORMAT_R8G8B8A8_SNORM; stride += sizeof(int8_t) * 4; @@ -2419,7 +2480,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su } break; case RS::ARRAY_TANGENT: { - if (s->format & RS::ARRAY_COMPRESS_TANGENT) { vd.format = RD::DATA_FORMAT_R8G8B8A8_SNORM; stride += sizeof(int8_t) * 4; @@ -2430,7 +2490,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su } break; case RS::ARRAY_COLOR: { - if (s->format & RS::ARRAY_COMPRESS_COLOR) { vd.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; stride += sizeof(int8_t) * 4; @@ -2441,7 +2500,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su } break; case RS::ARRAY_TEX_UV: { - if (s->format & RS::ARRAY_COMPRESS_TEX_UV) { vd.format = RD::DATA_FORMAT_R16G16_SFLOAT; stride += sizeof(int16_t) * 2; @@ -2452,7 +2510,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su } break; case RS::ARRAY_TEX_UV2: { - if (s->format & RS::ARRAY_COMPRESS_TEX_UV2) { vd.format = RD::DATA_FORMAT_R16G16_SFLOAT; stride += sizeof(int16_t) * 2; @@ -2497,12 +2554,10 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su ////////////////// MULTIMESH RID RasterizerStorageRD::multimesh_create() { - return multimesh_owner.make_rid(MultiMesh()); } void RasterizerStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); @@ -2538,7 +2593,6 @@ void RasterizerStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, R multimesh->visible_instances = MIN(multimesh->visible_instances, multimesh->instances); if (multimesh->instances) { - multimesh->buffer = RD::get_singleton()->storage_buffer_create(multimesh->instances * multimesh->stride_cache * 4); } } @@ -2593,7 +2647,6 @@ void RasterizerStorageRD::_multimesh_make_local(MultiMesh *multimesh) const { if (multimesh->buffer_set) { Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer); { - const uint8_t *r = buffer.ptr(); copymem(w, r, buffer.size()); } @@ -2604,13 +2657,12 @@ void RasterizerStorageRD::_multimesh_make_local(MultiMesh *multimesh) const { uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; multimesh->data_cache_dirty_regions = memnew_arr(bool, data_cache_dirty_region_count); for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) { - multimesh->data_cache_dirty_regions[i] = 0; + multimesh->data_cache_dirty_regions[i] = false; } multimesh->data_cache_used_dirty_regions = 0; } void RasterizerStorageRD::_multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb) { - uint32_t region_index = p_index / MULTIMESH_DIRTY_REGION_SIZE; #ifdef DEBUG_ENABLED uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; @@ -2656,7 +2708,6 @@ void RasterizerStorageRD::_multimesh_mark_all_dirty(MultiMesh *multimesh, bool p } void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances) { - ERR_FAIL_COND(multimesh->mesh.is_null()); AABB aabb; AABB mesh_aabb = mesh_get_aabb(multimesh->mesh); @@ -2665,7 +2716,6 @@ void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const Transform t; if (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_3D) { - t.basis.elements[0][0] = data[0]; t.basis.elements[0][1] = data[1]; t.basis.elements[0][2] = data[2]; @@ -2680,7 +2730,6 @@ void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const t.origin.z = data[11]; } else { - t.basis.elements[0].x = data[0]; t.basis.elements[1].x = data[1]; t.origin.x = data[3]; @@ -2701,7 +2750,6 @@ void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const } void RasterizerStorageRD::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); @@ -2732,7 +2780,6 @@ void RasterizerStorageRD::multimesh_instance_set_transform(RID p_multimesh, int } void RasterizerStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); @@ -2757,8 +2804,8 @@ void RasterizerStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, i _multimesh_mark_dirty(multimesh, p_index, true); } -void RasterizerStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) { +void RasterizerStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); @@ -2779,6 +2826,7 @@ void RasterizerStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_in _multimesh_mark_dirty(multimesh, p_index, false); } + void RasterizerStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); @@ -2802,7 +2850,6 @@ void RasterizerStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, in } RID RasterizerStorageRD::multimesh_get_mesh(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, RID()); @@ -2810,7 +2857,6 @@ RID RasterizerStorageRD::multimesh_get_mesh(RID p_multimesh) const { } Transform RasterizerStorageRD::multimesh_instance_get_transform(RID p_multimesh, int p_index) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, Transform()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform()); @@ -2840,8 +2886,8 @@ Transform RasterizerStorageRD::multimesh_instance_get_transform(RID p_multimesh, return t; } -Transform2D RasterizerStorageRD::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const { +Transform2D RasterizerStorageRD::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, Transform2D()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform2D()); @@ -2865,8 +2911,8 @@ Transform2D RasterizerStorageRD::multimesh_instance_get_transform_2d(RID p_multi return t; } -Color RasterizerStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_index) const { +Color RasterizerStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_index) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, Color()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color()); @@ -2888,8 +2934,8 @@ Color RasterizerStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_i return c; } -Color RasterizerStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { +Color RasterizerStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, Color()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color()); @@ -2969,7 +3015,6 @@ Vector<float> RasterizerStorageRD::multimesh_get_buffer(RID p_multimesh) const { } void RasterizerStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p_visible) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_COND(p_visible < -1 || p_visible > multimesh->instances); @@ -2984,6 +3029,7 @@ void RasterizerStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p multimesh->visible_instances = p_visible; } + int RasterizerStorageRD::multimesh_get_visible_instances(RID p_multimesh) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, 0); @@ -3000,9 +3046,7 @@ AABB RasterizerStorageRD::multimesh_get_aabb(RID p_multimesh) const { } void RasterizerStorageRD::_update_dirty_multimeshes() { - while (multimesh_dirty_list) { - MultiMesh *multimesh = multimesh_dirty_list; if (multimesh->data_cache.size()) { //may have been cleared, so only process if it exists @@ -3011,7 +3055,6 @@ void RasterizerStorageRD::_update_dirty_multimeshes() { uint32_t visible_instances = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances; if (multimesh->data_cache_used_dirty_regions) { - uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; uint32_t visible_region_count = (visible_instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; @@ -3060,12 +3103,10 @@ void RasterizerStorageRD::_update_dirty_multimeshes() { /* SKELETON API */ RID RasterizerStorageRD::skeleton_create() { - return skeleton_owner.make_rid(Skeleton()); } void RasterizerStorageRD::_skeleton_make_dirty(Skeleton *skeleton) { - if (!skeleton->dirty) { skeleton->dirty = true; skeleton->dirty_list = skeleton_dirty_list; @@ -3074,13 +3115,13 @@ void RasterizerStorageRD::_skeleton_make_dirty(Skeleton *skeleton) { } void RasterizerStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton) { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); ERR_FAIL_COND(p_bones < 0); - if (skeleton->size == p_bones && skeleton->use_2d == p_2d_skeleton) + if (skeleton->size == p_bones && skeleton->use_2d == p_2d_skeleton) { return; + } skeleton->size = p_bones; skeleton->use_2d = p_2d_skeleton; @@ -3093,7 +3134,6 @@ void RasterizerStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_ } if (skeleton->size) { - skeleton->data.resize(skeleton->size * (skeleton->use_2d ? 8 : 12)); skeleton->buffer = RD::get_singleton()->storage_buffer_create(skeleton->data.size() * sizeof(float)); zeromem(skeleton->data.ptrw(), skeleton->data.size() * sizeof(float)); @@ -3101,8 +3141,8 @@ void RasterizerStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_ _skeleton_make_dirty(skeleton); } } -int RasterizerStorageRD::skeleton_get_bone_count(RID p_skeleton) const { +int RasterizerStorageRD::skeleton_get_bone_count(RID p_skeleton) const { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND_V(!skeleton, 0); @@ -3110,7 +3150,6 @@ int RasterizerStorageRD::skeleton_get_bone_count(RID p_skeleton) const { } void RasterizerStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); @@ -3136,7 +3175,6 @@ void RasterizerStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone } Transform RasterizerStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND_V(!skeleton, Transform()); @@ -3162,8 +3200,8 @@ Transform RasterizerStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p return t; } -void RasterizerStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) { +void RasterizerStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); @@ -3183,8 +3221,8 @@ void RasterizerStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_b _skeleton_make_dirty(skeleton); } -Transform2D RasterizerStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { +Transform2D RasterizerStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND_V(!skeleton, Transform2D()); @@ -3205,7 +3243,6 @@ Transform2D RasterizerStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, } void RasterizerStorageRD::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton->use_2d); @@ -3214,13 +3251,10 @@ void RasterizerStorageRD::skeleton_set_base_transform_2d(RID p_skeleton, const T } void RasterizerStorageRD::_update_dirty_skeletons() { - while (skeleton_dirty_list) { - Skeleton *skeleton = skeleton_dirty_list; if (skeleton->size) { - RD::get_singleton()->buffer_update(skeleton->buffer, 0, skeleton->data.size() * sizeof(float), skeleton->data.ptr(), false); } @@ -3238,7 +3272,6 @@ void RasterizerStorageRD::_update_dirty_skeletons() { /* LIGHT */ RID RasterizerStorageRD::light_create(RS::LightType p_type) { - Light light; light.type = p_type; @@ -3262,14 +3295,13 @@ RID RasterizerStorageRD::light_create(RS::LightType p_type) { } void RasterizerStorageRD::light_set_color(RID p_light, const Color &p_color) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); light->color = p_color; } -void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, float p_value) { +void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, float p_value) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); ERR_FAIL_INDEX(p_param, RS::LIGHT_PARAM_MAX); @@ -3284,7 +3316,6 @@ void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, f case RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS: case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE: case RS::LIGHT_PARAM_SHADOW_BIAS: { - light->version++; light->instance_dependency.instance_notify_changed(true, false); } break; @@ -3294,8 +3325,8 @@ void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, f light->param[p_param] = p_value; } -void RasterizerStorageRD::light_set_shadow(RID p_light, bool p_enabled) { +void RasterizerStorageRD::light_set_shadow(RID p_light, bool p_enabled) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); light->shadow = p_enabled; @@ -3305,14 +3336,12 @@ void RasterizerStorageRD::light_set_shadow(RID p_light, bool p_enabled) { } void RasterizerStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); light->shadow_color = p_color; } void RasterizerStorageRD::light_set_projector(RID p_light, RID p_texture) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3332,14 +3361,13 @@ void RasterizerStorageRD::light_set_projector(RID p_light, RID p_texture) { } void RasterizerStorageRD::light_set_negative(RID p_light, bool p_enable) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); light->negative = p_enable; } -void RasterizerStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) { +void RasterizerStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3350,7 +3378,6 @@ void RasterizerStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) { } void RasterizerStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3369,8 +3396,8 @@ void RasterizerStorageRD::light_set_use_gi(RID p_light, bool p_enabled) { light->version++; light->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) { +void RasterizerStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3381,7 +3408,6 @@ void RasterizerStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniS } RS::LightOmniShadowMode RasterizerStorageRD::light_omni_get_shadow_mode(RID p_light) { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_OMNI_SHADOW_CUBE); @@ -3389,7 +3415,6 @@ RS::LightOmniShadowMode RasterizerStorageRD::light_omni_get_shadow_mode(RID p_li } void RasterizerStorageRD::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3399,7 +3424,6 @@ void RasterizerStorageRD::light_directional_set_shadow_mode(RID p_light, RS::Lig } void RasterizerStorageRD::light_directional_set_blend_splits(RID p_light, bool p_enable) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3409,7 +3433,6 @@ void RasterizerStorageRD::light_directional_set_blend_splits(RID p_light, bool p } bool RasterizerStorageRD::light_directional_get_blend_splits(RID p_light) const { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, false); @@ -3417,7 +3440,6 @@ bool RasterizerStorageRD::light_directional_get_blend_splits(RID p_light) const } RS::LightDirectionalShadowMode RasterizerStorageRD::light_directional_get_shadow_mode(RID p_light) { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL); @@ -3425,7 +3447,6 @@ RS::LightDirectionalShadowMode RasterizerStorageRD::light_directional_get_shadow } void RasterizerStorageRD::light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3433,7 +3454,6 @@ void RasterizerStorageRD::light_directional_set_shadow_depth_range_mode(RID p_li } RS::LightDirectionalShadowDepthRangeMode RasterizerStorageRD::light_directional_get_shadow_depth_range_mode(RID p_light) const { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE); @@ -3448,7 +3468,6 @@ bool RasterizerStorageRD::light_get_use_gi(RID p_light) { } uint64_t RasterizerStorageRD::light_get_version(RID p_light) const { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, 0); @@ -3456,25 +3475,20 @@ uint64_t RasterizerStorageRD::light_get_version(RID p_light) const { } AABB RasterizerStorageRD::light_get_aabb(RID p_light) const { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, AABB()); switch (light->type) { - case RS::LIGHT_SPOT: { - float len = light->param[RS::LIGHT_PARAM_RANGE]; float size = Math::tan(Math::deg2rad(light->param[RS::LIGHT_PARAM_SPOT_ANGLE])) * len; return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len)); }; case RS::LIGHT_OMNI: { - float r = light->param[RS::LIGHT_PARAM_RANGE]; return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2); }; case RS::LIGHT_DIRECTIONAL: { - return AABB(); }; } @@ -3485,12 +3499,10 @@ AABB RasterizerStorageRD::light_get_aabb(RID p_light) const { /* REFLECTION PROBE */ RID RasterizerStorageRD::reflection_probe_create() { - return reflection_probe_owner.make_rid(ReflectionProbe()); } void RasterizerStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3499,7 +3511,6 @@ void RasterizerStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::Refl } void RasterizerStorageRD::reflection_probe_set_intensity(RID p_probe, float p_intensity) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3507,7 +3518,6 @@ void RasterizerStorageRD::reflection_probe_set_intensity(RID p_probe, float p_in } void RasterizerStorageRD::reflection_probe_set_interior_ambient(RID p_probe, const Color &p_ambient) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3515,7 +3525,6 @@ void RasterizerStorageRD::reflection_probe_set_interior_ambient(RID p_probe, con } void RasterizerStorageRD::reflection_probe_set_interior_ambient_energy(RID p_probe, float p_energy) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3523,7 +3532,6 @@ void RasterizerStorageRD::reflection_probe_set_interior_ambient_energy(RID p_pro } void RasterizerStorageRD::reflection_probe_set_interior_ambient_probe_contribution(RID p_probe, float p_contrib) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3531,7 +3539,6 @@ void RasterizerStorageRD::reflection_probe_set_interior_ambient_probe_contributi } void RasterizerStorageRD::reflection_probe_set_max_distance(RID p_probe, float p_distance) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3539,16 +3546,16 @@ void RasterizerStorageRD::reflection_probe_set_max_distance(RID p_probe, float p reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) { +void RasterizerStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->extents = p_extents; reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) { +void RasterizerStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3557,15 +3564,14 @@ void RasterizerStorageRD::reflection_probe_set_origin_offset(RID p_probe, const } void RasterizerStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_enable) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->interior = p_enable; reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) { +void RasterizerStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3573,15 +3579,14 @@ void RasterizerStorageRD::reflection_probe_set_enable_box_projection(RID p_probe } void RasterizerStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->enable_shadows = p_enable; reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) { +void RasterizerStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3590,7 +3595,6 @@ void RasterizerStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p } void RasterizerStorageRD::reflection_probe_set_resolution(RID p_probe, int p_resolution) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); ERR_FAIL_COND(p_resolution < 32); @@ -3608,8 +3612,8 @@ AABB RasterizerStorageRD::reflection_probe_get_aabb(RID p_probe) const { return aabb; } -RS::ReflectionProbeUpdateMode RasterizerStorageRD::reflection_probe_get_update_mode(RID p_probe) const { +RS::ReflectionProbeUpdateMode RasterizerStorageRD::reflection_probe_get_update_mode(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_UPDATE_ALWAYS); @@ -3617,7 +3621,6 @@ RS::ReflectionProbeUpdateMode RasterizerStorageRD::reflection_probe_get_update_m } uint32_t RasterizerStorageRD::reflection_probe_get_cull_mask(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); @@ -3625,14 +3628,13 @@ uint32_t RasterizerStorageRD::reflection_probe_get_cull_mask(RID p_probe) const } Vector3 RasterizerStorageRD::reflection_probe_get_extents(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, Vector3()); return reflection_probe->extents; } -Vector3 RasterizerStorageRD::reflection_probe_get_origin_offset(RID p_probe) const { +Vector3 RasterizerStorageRD::reflection_probe_get_origin_offset(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, Vector3()); @@ -3640,7 +3642,6 @@ Vector3 RasterizerStorageRD::reflection_probe_get_origin_offset(RID p_probe) con } bool RasterizerStorageRD::reflection_probe_renders_shadows(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, false); @@ -3648,7 +3649,6 @@ bool RasterizerStorageRD::reflection_probe_renders_shadows(RID p_probe) const { } float RasterizerStorageRD::reflection_probe_get_origin_max_distance(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); @@ -3656,7 +3656,6 @@ float RasterizerStorageRD::reflection_probe_get_origin_max_distance(RID p_probe) } int RasterizerStorageRD::reflection_probe_get_resolution(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); @@ -3664,21 +3663,20 @@ int RasterizerStorageRD::reflection_probe_get_resolution(RID p_probe) const { } float RasterizerStorageRD::reflection_probe_get_intensity(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->intensity; } -bool RasterizerStorageRD::reflection_probe_is_interior(RID p_probe) const { +bool RasterizerStorageRD::reflection_probe_is_interior(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, false); return reflection_probe->interior; } -bool RasterizerStorageRD::reflection_probe_is_box_projection(RID p_probe) const { +bool RasterizerStorageRD::reflection_probe_is_box_projection(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, false); @@ -3686,21 +3684,20 @@ bool RasterizerStorageRD::reflection_probe_is_box_projection(RID p_probe) const } Color RasterizerStorageRD::reflection_probe_get_interior_ambient(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, Color()); return reflection_probe->interior_ambient; } -float RasterizerStorageRD::reflection_probe_get_interior_ambient_energy(RID p_probe) const { +float RasterizerStorageRD::reflection_probe_get_interior_ambient_energy(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->interior_ambient_energy; } -float RasterizerStorageRD::reflection_probe_get_interior_ambient_probe_contribution(RID p_probe) const { +float RasterizerStorageRD::reflection_probe_get_interior_ambient_probe_contribution(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); @@ -3717,6 +3714,7 @@ void RasterizerStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extent decal->extents = p_extents; decal->instance_dependency.instance_notify_changed(true, false); } + void RasterizerStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); @@ -3740,6 +3738,7 @@ void RasterizerStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type decal->instance_dependency.instance_notify_changed(false, true); } + void RasterizerStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); @@ -3757,6 +3756,7 @@ void RasterizerStorageRD::decal_set_modulate(RID p_decal, const Color &p_modulat ERR_FAIL_COND(!decal); decal->modulate = p_modulate; } + void RasterizerStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); @@ -3765,7 +3765,6 @@ void RasterizerStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) { } void RasterizerStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) { - Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->distance_fade = p_enabled; @@ -3774,7 +3773,6 @@ void RasterizerStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, f } void RasterizerStorageRD::decal_set_fade(RID p_decal, float p_above, float p_below) { - Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->upper_fade = p_above; @@ -3782,7 +3780,6 @@ void RasterizerStorageRD::decal_set_fade(RID p_decal, float p_above, float p_bel } void RasterizerStorageRD::decal_set_normal_fade(RID p_decal, float p_fade) { - Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->normal_fade = p_fade; @@ -3796,7 +3793,6 @@ AABB RasterizerStorageRD::decal_get_aabb(RID p_decal) const { } RID RasterizerStorageRD::gi_probe_create() { - return gi_probe_owner.make_rid(GIProbe()); } @@ -3938,6 +3934,7 @@ Vector3i RasterizerStorageRD::gi_probe_get_octree_size(RID p_gi_probe) const { ERR_FAIL_COND_V(!gi_probe, Vector3i()); return gi_probe->octree_size; } + Vector<uint8_t> RasterizerStorageRD::gi_probe_get_octree_cells(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>()); @@ -3947,6 +3944,7 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_octree_cells(RID p_gi_probe) c } return Vector<uint8_t>(); } + Vector<uint8_t> RasterizerStorageRD::gi_probe_get_data_cells(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>()); @@ -3956,6 +3954,7 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_data_cells(RID p_gi_probe) con } return Vector<uint8_t>(); } + Vector<uint8_t> RasterizerStorageRD::gi_probe_get_distance_field(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>()); @@ -3965,12 +3964,14 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_distance_field(RID p_gi_probe) } return Vector<uint8_t>(); } + Vector<int> RasterizerStorageRD::gi_probe_get_level_counts(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Vector<int>()); return gi_probe->level_counts; } + Transform RasterizerStorageRD::gi_probe_get_to_cell_xform(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Transform()); @@ -3985,6 +3986,7 @@ void RasterizerStorageRD::gi_probe_set_dynamic_range(RID p_gi_probe, float p_ran gi_probe->dynamic_range = p_range; gi_probe->version++; } + float RasterizerStorageRD::gi_probe_get_dynamic_range(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); @@ -3999,6 +4001,7 @@ void RasterizerStorageRD::gi_probe_set_propagation(RID p_gi_probe, float p_range gi_probe->propagation = p_range; gi_probe->version++; } + float RasterizerStorageRD::gi_probe_get_propagation(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); @@ -4011,6 +4014,7 @@ void RasterizerStorageRD::gi_probe_set_energy(RID p_gi_probe, float p_energy) { gi_probe->energy = p_energy; } + float RasterizerStorageRD::gi_probe_get_energy(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); @@ -4023,6 +4027,7 @@ void RasterizerStorageRD::gi_probe_set_ao(RID p_gi_probe, float p_ao) { gi_probe->ao = p_ao; } + float RasterizerStorageRD::gi_probe_get_ao(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); @@ -4030,7 +4035,6 @@ float RasterizerStorageRD::gi_probe_get_ao(RID p_gi_probe) const { } void RasterizerStorageRD::gi_probe_set_ao_size(RID p_gi_probe, float p_strength) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); @@ -4049,6 +4053,7 @@ void RasterizerStorageRD::gi_probe_set_bias(RID p_gi_probe, float p_bias) { gi_probe->bias = p_bias; } + float RasterizerStorageRD::gi_probe_get_bias(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); @@ -4061,6 +4066,7 @@ void RasterizerStorageRD::gi_probe_set_normal_bias(RID p_gi_probe, float p_norma gi_probe->normal_bias = p_normal_bias; } + float RasterizerStorageRD::gi_probe_get_normal_bias(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); @@ -4068,7 +4074,6 @@ float RasterizerStorageRD::gi_probe_get_normal_bias(RID p_gi_probe) const { } void RasterizerStorageRD::gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); @@ -4121,13 +4126,12 @@ uint32_t RasterizerStorageRD::gi_probe_get_data_version(RID p_gi_probe) { } RID RasterizerStorageRD::gi_probe_get_octree_buffer(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, RID()); return gi_probe->octree_buffer; } -RID RasterizerStorageRD::gi_probe_get_data_buffer(RID p_gi_probe) const { +RID RasterizerStorageRD::gi_probe_get_data_buffer(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, RID()); return gi_probe->data_buffer; @@ -4140,10 +4144,182 @@ RID RasterizerStorageRD::gi_probe_get_sdf_texture(RID p_gi_probe) { return gi_probe->sdf_texture; } +/* LIGHTMAP API */ + +RID RasterizerStorageRD::lightmap_create() { + return lightmap_owner.make_rid(Lightmap()); +} + +void RasterizerStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND(!lm); + + lightmap_array_version++; + + //erase lightmap users + if (lm->light_texture.is_valid()) { + Texture *t = texture_owner.getornull(lm->light_texture); + if (t) { + t->lightmap_users.erase(p_lightmap); + } + } + + Texture *t = texture_owner.getornull(p_light); + lm->light_texture = p_light; + lm->uses_spherical_harmonics = p_uses_spherical_haromics; + + RID default_2d_array = default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE]; + if (!t) { + if (using_lightmap_array) { + if (lm->array_index >= 0) { + lightmap_textures.write[lm->array_index] = default_2d_array; + lm->array_index = -1; + } + } + + return; + } + + t->lightmap_users.insert(p_lightmap); + + if (using_lightmap_array) { + if (lm->array_index < 0) { + //not in array, try to put in array + for (int i = 0; i < lightmap_textures.size(); i++) { + if (lightmap_textures[i] == default_2d_array) { + lm->array_index = i; + break; + } + } + } + ERR_FAIL_COND_MSG(lm->array_index < 0, "Maximum amount of lightmaps in use (" + itos(lightmap_textures.size()) + ") has been exceeded, lightmap will nod display properly."); + + lightmap_textures.write[lm->array_index] = t->rd_texture; + } +} + +void RasterizerStorageRD::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND(!lm); + lm->bounds = p_bounds; +} + +void RasterizerStorageRD::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND(!lm); + lm->interior = p_interior; +} + +void RasterizerStorageRD::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND(!lm); + + if (p_points.size()) { + ERR_FAIL_COND(p_points.size() * 9 != p_point_sh.size()); + ERR_FAIL_COND((p_tetrahedra.size() % 4) != 0); + ERR_FAIL_COND((p_bsp_tree.size() % 6) != 0); + } + + lm->points = p_points; + lm->bsp_tree = p_bsp_tree; + lm->point_sh = p_point_sh; + lm->tetrahedra = p_tetrahedra; +} + +PackedVector3Array RasterizerStorageRD::lightmap_get_probe_capture_points(RID p_lightmap) const { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND_V(!lm, PackedVector3Array()); + + return lm->points; +} + +PackedColorArray RasterizerStorageRD::lightmap_get_probe_capture_sh(RID p_lightmap) const { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND_V(!lm, PackedColorArray()); + return lm->point_sh; +} + +PackedInt32Array RasterizerStorageRD::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND_V(!lm, PackedInt32Array()); + return lm->tetrahedra; +} + +PackedInt32Array RasterizerStorageRD::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND_V(!lm, PackedInt32Array()); + return lm->bsp_tree; +} + +void RasterizerStorageRD::lightmap_set_probe_capture_update_speed(float p_speed) { + lightmap_probe_capture_update_speed = p_speed; +} + +void RasterizerStorageRD::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND(!lm); + + for (int i = 0; i < 9; i++) { + r_sh[i] = Color(0, 0, 0, 0); + } + + if (!lm->points.size() || !lm->bsp_tree.size() || !lm->tetrahedra.size()) { + return; + } + + static_assert(sizeof(Lightmap::BSP) == 24); + + const Lightmap::BSP *bsp = (const Lightmap::BSP *)lm->bsp_tree.ptr(); + int32_t node = 0; + while (node >= 0) { + if (Plane(bsp[node].plane[0], bsp[node].plane[1], bsp[node].plane[2], bsp[node].plane[3]).is_point_over(p_point)) { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(bsp[node].over >= 0 && bsp[node].over < node); +#endif + + node = bsp[node].over; + } else { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(bsp[node].under >= 0 && bsp[node].under < node); +#endif + node = bsp[node].under; + } + } + + if (node == Lightmap::BSP::EMPTY_LEAF) { + return; //nothing could be done + } + + node = ABS(node) - 1; + + uint32_t *tetrahedron = (uint32_t *)&lm->tetrahedra[node * 4]; + Vector3 points[4] = { lm->points[tetrahedron[0]], lm->points[tetrahedron[1]], lm->points[tetrahedron[2]], lm->points[tetrahedron[3]] }; + const Color *sh_colors[4]{ &lm->point_sh[tetrahedron[0] * 9], &lm->point_sh[tetrahedron[1] * 9], &lm->point_sh[tetrahedron[2] * 9], &lm->point_sh[tetrahedron[3] * 9] }; + Color barycentric = Geometry::tetrahedron_get_barycentric_coords(points[0], points[1], points[2], points[3], p_point); + + for (int i = 0; i < 4; i++) { + float c = CLAMP(barycentric[i], 0.0, 1.0); + for (int j = 0; j < 9; j++) { + r_sh[j] += sh_colors[i][j] * c; + } + } +} + +bool RasterizerStorageRD::lightmap_is_interior(RID p_lightmap) const { + const Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND_V(!lm, false); + return lm->interior; +} + +AABB RasterizerStorageRD::lightmap_get_aabb(RID p_lightmap) const { + const Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND_V(!lm, AABB()); + return lm->bounds; +} + /* RENDER TARGET API */ void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) { - //free in reverse dependency order if (rt->framebuffer.is_valid()) { RD::get_singleton()->free(rt->framebuffer); @@ -4172,7 +4348,6 @@ void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) { } void RasterizerStorageRD::_update_render_target(RenderTarget *rt) { - if (rt->texture.is_null()) { //create a placeholder until updated rt->texture = texture_2d_placeholder_create(); @@ -4277,7 +4452,6 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) { //create mipmaps for (uint32_t i = 1; i < mipmaps_required; i++) { - RenderTarget::BackbufferMipmap mm; { mm.mipmap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, i); @@ -4341,14 +4515,12 @@ void RasterizerStorageRD::render_target_set_flag(RID p_render_target, RenderTarg } bool RasterizerStorageRD::render_target_was_used(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, false); return rt->was_used; } void RasterizerStorageRD::render_target_set_as_unused(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); rt->was_used = false; @@ -4367,12 +4539,14 @@ RID RasterizerStorageRD::render_target_get_rd_framebuffer(RID p_render_target) { return rt->framebuffer; } + RID RasterizerStorageRD::render_target_get_rd_texture(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, RID()); return rt->color; } + void RasterizerStorageRD::render_target_request_clear(RID p_render_target, const Color &p_clear_color) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); @@ -4387,21 +4561,18 @@ bool RasterizerStorageRD::render_target_is_clear_requested(RID p_render_target) } Color RasterizerStorageRD::render_target_get_clear_request_color(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, Color()); return rt->clear_color; } void RasterizerStorageRD::render_target_disable_clear_request(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); rt->clear_requested = false; } void RasterizerStorageRD::render_target_do_clear_request(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); if (!rt->clear_requested) { @@ -4476,7 +4647,6 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In Mesh *mesh = mesh_owner.getornull(p_base); p_instance->update_dependency(&mesh->instance_dependency); } else if (multimesh_owner.owns(p_base)) { - MultiMesh *multimesh = multimesh_owner.getornull(p_base); p_instance->update_dependency(&multimesh->instance_dependency); if (multimesh->mesh.is_valid()) { @@ -4491,6 +4661,9 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In } else if (gi_probe_owner.owns(p_base)) { GIProbe *gip = gi_probe_owner.getornull(p_base); p_instance->update_dependency(&gip->instance_dependency); + } else if (lightmap_owner.owns(p_base)) { + Lightmap *lm = lightmap_owner.getornull(p_base); + p_instance->update_dependency(&lm->instance_dependency); } else if (light_owner.owns(p_base)) { Light *l = light_owner.getornull(p_base); p_instance->update_dependency(&l->instance_dependency); @@ -4498,7 +4671,6 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In } void RasterizerStorageRD::skeleton_update_dependency(RID p_skeleton, RasterizerScene::InstanceBase *p_instance) { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); @@ -4506,7 +4678,6 @@ void RasterizerStorageRD::skeleton_update_dependency(RID p_skeleton, RasterizerS } RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const { - if (mesh_owner.owns(p_rid)) { return RS::INSTANCE_MESH; } @@ -4525,6 +4696,9 @@ RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const { if (light_owner.owns(p_rid)) { return RS::INSTANCE_LIGHT; } + if (lightmap_owner.owns(p_rid)) { + return RS::INSTANCE_LIGHTMAP; + } return RS::INSTANCE_NONE; } @@ -4588,7 +4762,7 @@ void RasterizerStorageRD::_update_decal_atlas() { Vector<DecalAtlas::SortItem> itemsv; itemsv.resize(decal_atlas.textures.size()); int base_size = 8; - const RID *K = NULL; + const RID *K = nullptr; int idx = 0; while ((K = decal_atlas.textures.next(K))) { @@ -4618,7 +4792,6 @@ void RasterizerStorageRD::_update_decal_atlas() { int atlas_height = 0; while (true) { - Vector<int> v_offsetsv; v_offsetsv.resize(base_size); @@ -4678,12 +4851,11 @@ void RasterizerStorageRD::_update_decal_atlas() { DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture); t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2); t->uv_rect.size = items[i].pixel_size; - //print_line("blitrect: " + t->uv_rect); + t->uv_rect.position /= Size2(decal_atlas.size); t->uv_rect.size /= Size2(decal_atlas.size); } } else { - //use border as size, so it at least has enough mipmaps decal_atlas.size.width = border; decal_atlas.size.height = border; @@ -4735,14 +4907,13 @@ void RasterizerStorageRD::_update_decal_atlas() { Color clear_color(0, 0, 0, 0); if (decal_atlas.textures.size()) { - if (i == 0) { Vector<Color> cc; cc.push_back(clear_color); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc); - const RID *K = NULL; + const RID *K = nullptr; while ((K = decal_atlas.textures.next(K))) { DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K); Texture *src_tex = texture_owner.getornull(*K); @@ -4753,7 +4924,6 @@ void RasterizerStorageRD::_update_decal_atlas() { prev_texture = mm.texture; } else { - effects.copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size)); prev_texture = mm.texture; } @@ -4764,7 +4934,6 @@ void RasterizerStorageRD::_update_decal_atlas() { } int32_t RasterizerStorageRD::_global_variable_allocate(uint32_t p_elements) { - int32_t idx = 0; while (idx + p_elements <= global_variables.buffer_size) { if (global_variables.buffer_usage[idx].elements == 0) { @@ -4791,10 +4960,8 @@ int32_t RasterizerStorageRD::_global_variable_allocate(uint32_t p_elements) { } void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value) { - switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; bool b = p_value; bv.x = b ? 1.0 : 0.0; @@ -4973,7 +5140,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS:: } break; case RS::GLOBAL_VAR_TYPE_MAT3: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; Basis v = p_value; bv[0].x = v.elements[0][0]; @@ -4993,7 +5159,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS:: } break; case RS::GLOBAL_VAR_TYPE_MAT4: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; Vector<float> m2 = p_value; @@ -5023,7 +5188,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS:: } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; Transform2D v = p_value; bv[0].x = v.elements[0][0]; @@ -5043,7 +5207,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS:: } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; Transform v = p_value; bv[0].x = v.basis.elements[0][0]; @@ -5074,7 +5237,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS:: } void RasterizerStorageRD::_global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements) { - int32_t prev_chunk = -1; for (int32_t i = 0; i < p_elements; i++) { @@ -5091,7 +5253,6 @@ void RasterizerStorageRD::_global_variable_mark_buffer_dirty(int32_t p_index, in } void RasterizerStorageRD::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) { - ERR_FAIL_COND(global_variables.variables.has(p_name)); GlobalVariables::Variable gv; gv.type = p_type; @@ -5102,7 +5263,6 @@ void RasterizerStorageRD::global_variable_add(const StringName &p_name, RS::Glob //is texture global_variables.must_update_texture_materials = true; //normally ther are no } else { - gv.buffer_elements = 1; if (p_type == RS::GLOBAL_VAR_TYPE_COLOR || p_type == RS::GLOBAL_VAR_TYPE_MAT2) { //color needs to elements to store srgb and linear @@ -5145,13 +5305,13 @@ void RasterizerStorageRD::global_variable_remove(const StringName &p_name) { global_variables.variables.erase(p_name); } -Vector<StringName> RasterizerStorageRD::global_variable_get_list() const { +Vector<StringName> RasterizerStorageRD::global_variable_get_list() const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance."); } - const StringName *K = NULL; + const StringName *K = nullptr; Vector<StringName> names; while ((K = global_variables.variables.next(K))) { names.push_back(*K); @@ -5179,6 +5339,7 @@ void RasterizerStorageRD::global_variable_set(const StringName &p_name, const Va } } } + void RasterizerStorageRD::global_variable_set_override(const StringName &p_name, const Variant &p_value) { if (!global_variables.variables.has(p_name)) { return; //variable may not exist @@ -5208,7 +5369,6 @@ void RasterizerStorageRD::global_variable_set_override(const StringName &p_name, } Variant RasterizerStorageRD::global_variable_get(const StringName &p_name) const { - if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance."); } @@ -5221,7 +5381,6 @@ Variant RasterizerStorageRD::global_variable_get(const StringName &p_name) const } RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type_internal(const StringName &p_name) const { - if (!global_variables.variables.has(p_name)) { return RS::GLOBAL_VAR_TYPE_MAX; } @@ -5238,7 +5397,6 @@ RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type(const Strin } void RasterizerStorageRD::global_variables_load_settings(bool p_load_textures) { - List<PropertyInfo> settings; ProjectSettings::get_singleton()->get_property_list(&settings); @@ -5344,8 +5502,8 @@ void RasterizerStorageRD::global_variables_instance_free(RID p_instance) { } global_variables.instance_buffer_pos.erase(p_instance); } -void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) { +void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) { if (!global_variables.instance_buffer_pos.has(p_instance)) { return; //just not allocated, ignore } @@ -5389,7 +5547,6 @@ void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p } void RasterizerStorageRD::_update_global_variables() { - if (global_variables.buffer_dirty_region_count > 0) { uint32_t total_regions = global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE; if (total_regions / global_variables.buffer_dirty_region_count <= 4) { @@ -5401,7 +5558,6 @@ void RasterizerStorageRD::_update_global_variables() { for (uint32_t i = 0; i < total_regions; i++) { if (global_variables.buffer_dirty_regions[i]) { - RD::get_singleton()->buffer_update(global_variables.buffer, i * region_byte_size, region_byte_size, global_variables.buffer_values); global_variables.buffer_dirty_regions[i] = false; @@ -5449,7 +5605,6 @@ void RasterizerStorageRD::update_dirty_resources() { } bool RasterizerStorageRD::has_os_feature(const String &p_feature) const { - if (p_feature == "rgtc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) { return true; } @@ -5472,8 +5627,8 @@ bool RasterizerStorageRD::has_os_feature(const String &p_feature) const { return false; } -bool RasterizerStorageRD::free(RID p_rid) { +bool RasterizerStorageRD::free(RID p_rid) { if (texture_owner.owns(p_rid)) { Texture *t = texture_owner.getornull(p_rid); @@ -5563,9 +5718,13 @@ bool RasterizerStorageRD::free(RID p_rid) { GIProbe *gi_probe = gi_probe_owner.getornull(p_rid); gi_probe->instance_dependency.instance_notify_deleted(p_rid); gi_probe_owner.free(p_rid); + } else if (lightmap_owner.owns(p_rid)) { + lightmap_set_textures(p_rid, RID(), false); + Lightmap *lightmap = lightmap_owner.getornull(p_rid); + lightmap->instance_dependency.instance_notify_deleted(p_rid); + lightmap_owner.free(p_rid); } else if (light_owner.owns(p_rid)) { - light_set_projector(p_rid, RID()); //clear projector // delete the texture Light *light = light_owner.getornull(p_rid); @@ -5606,6 +5765,7 @@ void RasterizerStorageRD::capture_timestamp(const String &p_name) { uint32_t RasterizerStorageRD::get_captured_timestamps_count() const { return RD::get_singleton()->get_captured_timestamps_count(); } + uint64_t RasterizerStorageRD::get_captured_timestamps_frame() const { return RD::get_singleton()->get_captured_timestamps_frame(); } @@ -5613,9 +5773,11 @@ uint64_t RasterizerStorageRD::get_captured_timestamps_frame() const { uint64_t RasterizerStorageRD::get_captured_timestamp_gpu_time(uint32_t p_index) const { return RD::get_singleton()->get_captured_timestamp_gpu_time(p_index); } + uint64_t RasterizerStorageRD::get_captured_timestamp_cpu_time(uint32_t p_index) const { return RD::get_singleton()->get_captured_timestamp_cpu_time(p_index); } + String RasterizerStorageRD::get_captured_timestamp_name(uint32_t p_index) const { return RD::get_singleton()->get_captured_timestamp_name(p_index); } @@ -5623,7 +5785,6 @@ String RasterizerStorageRD::get_captured_timestamp_name(uint32_t p_index) const RasterizerStorageRD *RasterizerStorageRD::base_singleton = nullptr; RasterizerStorageRD::RasterizerStorageRD() { - base_singleton = this; for (int i = 0; i < SHADER_TYPE_MAX; i++) { @@ -5801,6 +5962,32 @@ RasterizerStorageRD::RasterizerStorageRD() { } } + { //create default array + + RD::TextureFormat tformat; + tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + tformat.width = 4; + tformat.height = 4; + tformat.array_layers = 1; + tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; + tformat.type = RD::TEXTURE_TYPE_2D_ARRAY; + + Vector<uint8_t> pv; + pv.resize(16 * 4); + for (int i = 0; i < 16; i++) { + pv.set(i * 4 + 0, 255); + pv.set(i * 4 + 1, 255); + pv.set(i * 4 + 2, 255); + pv.set(i * 4 + 3, 255); + } + + { + Vector<Vector<uint8_t>> vpv; + vpv.push_back(pv); + default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + } + } + //default samplers for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) { for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) { @@ -5812,7 +5999,6 @@ RasterizerStorageRD::RasterizerStorageRD() { sampler_state.max_lod = 0; } break; case RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR: { - sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.max_lod = 0; @@ -5848,7 +6034,6 @@ RasterizerStorageRD::RasterizerStorageRD() { } switch (j) { case RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED: { - sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE; sampler_state.repeat_v = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE; @@ -5871,129 +6056,134 @@ RasterizerStorageRD::RasterizerStorageRD() { //default rd buffers { - - //vertex + Vector<uint8_t> buffer; { + buffer.resize(sizeof(float) * 3); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 0.0; + fptr[1] = 0.0; + fptr[2] = 0.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_VERTEX] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } - Vector<uint8_t> buffer; + { //normal + buffer.resize(sizeof(float) * 3); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 1.0; + fptr[1] = 0.0; + fptr[2] = 0.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_NORMAL] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } - buffer.resize(sizeof(float) * 3); - { - uint8_t *w = buffer.ptrw(); - float *fptr = (float *)w; - fptr[0] = 0.0; - fptr[1] = 0.0; - fptr[2] = 0.0; - } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_VERTEX] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} + { //tangent + buffer.resize(sizeof(float) * 4); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 1.0; + fptr[1] = 0.0; + fptr[2] = 0.0; + fptr[3] = 0.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TANGENT] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } -{ //normal - Vector<uint8_t> buffer; - buffer.resize(sizeof(float) * 3); - { - uint8_t *w = buffer.ptrw(); - float *fptr = (float *)w; - fptr[0] = 1.0; - fptr[1] = 0.0; - fptr[2] = 0.0; - } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_NORMAL] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} + { //color + buffer.resize(sizeof(float) * 4); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 1.0; + fptr[1] = 1.0; + fptr[2] = 1.0; + fptr[3] = 1.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_COLOR] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } -{ //tangent - Vector<uint8_t> buffer; - buffer.resize(sizeof(float) * 4); - { - uint8_t *w = buffer.ptrw(); - float *fptr = (float *)w; - fptr[0] = 1.0; - fptr[1] = 0.0; - fptr[2] = 0.0; - fptr[3] = 0.0; - } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TANGENT] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} + { //tex uv 1 + buffer.resize(sizeof(float) * 2); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 0.0; + fptr[1] = 0.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } + { //tex uv 2 + buffer.resize(sizeof(float) * 2); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 0.0; + fptr[1] = 0.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV2] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } -{ //color - Vector<uint8_t> buffer; - buffer.resize(sizeof(float) * 4); - { - uint8_t *w = buffer.ptrw(); - float *fptr = (float *)w; - fptr[0] = 1.0; - fptr[1] = 1.0; - fptr[2] = 1.0; - fptr[3] = 1.0; - } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_COLOR] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} + { //bones + buffer.resize(sizeof(uint32_t) * 4); + { + uint8_t *w = buffer.ptrw(); + uint32_t *fptr = (uint32_t *)w; + fptr[0] = 0; + fptr[1] = 0; + fptr[2] = 0; + fptr[3] = 0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_BONES] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } -{ //tex uv 1 - Vector<uint8_t> buffer; - buffer.resize(sizeof(float) * 2); - { - uint8_t *w = buffer.ptrw(); - float *fptr = (float *)w; - fptr[0] = 0.0; - fptr[1] = 0.0; - } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} -{ //tex uv 2 - Vector<uint8_t> buffer; - buffer.resize(sizeof(float) * 2); - { - uint8_t *w = buffer.ptrw(); - float *fptr = (float *)w; - fptr[0] = 0.0; - fptr[1] = 0.0; + { //weights + buffer.resize(sizeof(float) * 4); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 0.0; + fptr[1] = 0.0; + fptr[2] = 0.0; + fptr[3] = 0.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_WEIGHTS] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV2] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} -{ //bones - Vector<uint8_t> buffer; - buffer.resize(sizeof(uint32_t) * 4); { - uint8_t *w = buffer.ptrw(); - uint32_t *fptr = (uint32_t *)w; - fptr[0] = 0; - fptr[1] = 0; - fptr[2] = 0; - fptr[3] = 0; + Vector<String> sdf_versions; + sdf_versions.push_back(""); //one only + giprobe_sdf_shader.initialize(sdf_versions); + giprobe_sdf_shader_version = giprobe_sdf_shader.version_create(); + giprobe_sdf_shader.version_set_compute_code(giprobe_sdf_shader_version, "", "", "", Vector<String>()); + giprobe_sdf_shader_version_shader = giprobe_sdf_shader.version_get_shader(giprobe_sdf_shader_version, 0); + giprobe_sdf_shader_pipeline = RD::get_singleton()->compute_pipeline_create(giprobe_sdf_shader_version_shader); } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_BONES] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} -{ //weights - Vector<uint8_t> buffer; - buffer.resize(sizeof(float) * 4); - { - uint8_t *w = buffer.ptrw(); - float *fptr = (float *)w; - fptr[0] = 0.0; - fptr[1] = 0.0; - fptr[2] = 0.0; - fptr[3] = 0.0; + using_lightmap_array = true; // high end + if (using_lightmap_array) { + uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); + + if (textures_per_stage <= 256) { + lightmap_textures.resize(32); + } else { + lightmap_textures.resize(1024); + } + + for (int i = 0; i < lightmap_textures.size(); i++) { + lightmap_textures.write[i] = default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE]; + } } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_WEIGHTS] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} -} -{ - Vector<String> sdf_versions; - sdf_versions.push_back(""); //one only - giprobe_sdf_shader.initialize(sdf_versions); - giprobe_sdf_shader_version = giprobe_sdf_shader.version_create(); - giprobe_sdf_shader.version_set_compute_code(giprobe_sdf_shader_version, "", "", "", Vector<String>()); - giprobe_sdf_shader_version_shader = giprobe_sdf_shader.version_get_shader(giprobe_sdf_shader_version, 0); - giprobe_sdf_shader_pipeline = RD::get_singleton()->compute_pipeline_create(giprobe_sdf_shader_version_shader); -} + lightmap_probe_capture_update_speed = GLOBAL_GET("rendering/lightmapper/probe_capture_update_speed"); } RasterizerStorageRD::~RasterizerStorageRD() { - memdelete_arr(global_variables.buffer_values); memdelete_arr(global_variables.buffer_usage); memdelete_arr(global_variables.buffer_dirty_regions); diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h index f874c3baf8..fe9377192e 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h @@ -64,7 +64,6 @@ public: typedef ShaderData *(*ShaderDataRequestFunction)(); struct MaterialData { - void update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color); void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color); @@ -92,6 +91,7 @@ public: DEFAULT_RD_TEXTURE_CUBEMAP_BLACK, DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK, DEFAULT_RD_TEXTURE_3D_WHITE, + DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE, DEFAULT_RD_TEXTURE_MAX }; @@ -110,7 +110,6 @@ public: private: /* TEXTURE API */ struct Texture { - enum Type { TYPE_2D, TYPE_LAYERED, @@ -118,6 +117,7 @@ private: }; Type type; + RS::TextureLayeredType layered_type = RS::TEXTURE_LAYERED_2D_ARRAY; RenderingDevice::TextureType rd_type; RID rd_texture; @@ -147,6 +147,7 @@ private: RID proxy_to; Vector<RID> proxies; + Set<RID> lightmap_users; RS::TextureDetectCallback detect_3d_callback = nullptr; void *detect_3d_callback_ud = nullptr; @@ -187,7 +188,6 @@ private: struct DecalAtlas { struct Texture { - int panorama_to_dp_users; int users; Rect2 uv_rect; @@ -271,7 +271,6 @@ private: /* Mesh */ struct Mesh { - struct Surface { RS::PrimitiveType primitive = RS::PRIMITIVE_POINTS; uint32_t format = 0; @@ -413,7 +412,6 @@ private: /* LIGHT */ struct Light { - RS::LightType type; float param[RS::LIGHT_PARAM_MAX]; Color color = Color(1, 1, 1, 1); @@ -438,7 +436,6 @@ private: /* REFLECTION PROBE */ struct ReflectionProbe { - RS::ReflectionProbeUpdateMode update_mode = RS::REFLECTION_PROBE_UPDATE_ONCE; int resolution = 256; float intensity = 1.0; @@ -461,7 +458,6 @@ private: /* DECAL */ struct Decal { - Vector3 extents = Vector3(1, 1, 1); RID textures[RS::DECAL_TEXTURE_MAX]; float emission_energy = 1.0; @@ -483,7 +479,6 @@ private: /* GI PROBE */ struct GIProbe { - RID octree_buffer; RID data_buffer; RID sdf_texture; @@ -524,10 +519,42 @@ private: mutable RID_Owner<GIProbe> gi_probe_owner; + /* REFLECTION PROBE */ + + struct Lightmap { + RID light_texture; + bool uses_spherical_harmonics = false; + bool interior = false; + AABB bounds = AABB(Vector3(), Vector3(1, 1, 1)); + int32_t array_index = -1; //unassigned + PackedVector3Array points; + PackedColorArray point_sh; + PackedInt32Array tetrahedra; + PackedInt32Array bsp_tree; + + struct BSP { + static const int32_t EMPTY_LEAF = INT32_MIN; + float plane[4]; + int32_t over = EMPTY_LEAF, under = EMPTY_LEAF; + }; + + RasterizerScene::InstanceDependency instance_dependency; + }; + + bool using_lightmap_array; //high end uses this + /* for high end */ + + Vector<RID> lightmap_textures; + + uint64_t lightmap_array_version = 0; + + mutable RID_Owner<Lightmap> lightmap_owner; + + float lightmap_probe_capture_update_speed = 4; + /* RENDER TARGET */ struct RenderTarget { - Size2i size; RID framebuffer; RID color; @@ -568,7 +595,6 @@ private: /* GLOBAL SHADER VARIABLES */ struct GlobalVariables { - enum { BUFFER_DIRTY_REGION_SIZE = 1024 }; @@ -653,7 +679,7 @@ public: //these two APIs can be used together or in combination with the others. virtual RID texture_2d_placeholder_create(); - virtual RID texture_2d_layered_placeholder_create(); + virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type); virtual RID texture_3d_placeholder_create(); virtual Ref<Image> texture_2d_get(RID p_texture) const; @@ -1037,7 +1063,6 @@ public: AABB light_get_aabb(RID p_light) const; _FORCE_INLINE_ float light_get_param(RID p_light, RS::LightParam p_param) { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, 0); @@ -1045,7 +1070,6 @@ public: } _FORCE_INLINE_ RID light_get_projector(RID p_light) { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RID()); @@ -1053,7 +1077,6 @@ public: } _FORCE_INLINE_ Color light_get_color(RID p_light) { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, Color()); @@ -1061,7 +1084,6 @@ public: } _FORCE_INLINE_ Color light_get_shadow_color(RID p_light) { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, Color()); @@ -1069,7 +1091,6 @@ public: } _FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, 0); @@ -1077,7 +1098,6 @@ public: } _FORCE_INLINE_ bool light_has_shadow(RID p_light) const { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL); @@ -1085,7 +1105,6 @@ public: } _FORCE_INLINE_ bool light_is_negative(RID p_light) const { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL); @@ -1093,7 +1112,6 @@ public: } _FORCE_INLINE_ float light_get_transmittance_bias(RID p_light) const { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, 0.0); @@ -1270,23 +1288,47 @@ public: /* LIGHTMAP CAPTURE */ - void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) {} - AABB lightmap_capture_get_bounds(RID p_capture) const { return AABB(); } - void lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) {} - RID lightmap_capture_create() { - return RID(); + virtual RID lightmap_create(); + + virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics); + virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds); + virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior); + virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree); + virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const; + virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const; + virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const; + virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const; + virtual AABB lightmap_get_aabb(RID p_lightmap) const; + virtual bool lightmap_is_interior(RID p_lightmap) const; + virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh); + virtual void lightmap_set_probe_capture_update_speed(float p_speed); + _FORCE_INLINE_ float lightmap_get_probe_capture_update_speed() const { + return lightmap_probe_capture_update_speed; + } + + _FORCE_INLINE_ int32_t lightmap_get_array_index(RID p_lightmap) const { + ERR_FAIL_COND_V(!using_lightmap_array, -1); //only for arrays + const Lightmap *lm = lightmap_owner.getornull(p_lightmap); + return lm->array_index; } - Vector<uint8_t> lightmap_capture_get_octree(RID p_capture) const { - return Vector<uint8_t>(); + _FORCE_INLINE_ bool lightmap_uses_spherical_harmonics(RID p_lightmap) const { + ERR_FAIL_COND_V(!using_lightmap_array, false); //only for arrays + const Lightmap *lm = lightmap_owner.getornull(p_lightmap); + return lm->uses_spherical_harmonics; } - void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) {} - Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const { return Transform(); } - void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) {} - int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const { return 0; } - void lightmap_capture_set_energy(RID p_capture, float p_energy) {} - float lightmap_capture_get_energy(RID p_capture) const { return 0.0; } - const Vector<LightmapCaptureOctree> *lightmap_capture_get_octree_ptr(RID p_capture) const { - return nullptr; + _FORCE_INLINE_ uint64_t lightmap_array_get_version() const { + ERR_FAIL_COND_V(!using_lightmap_array, 0); //only for arrays + return lightmap_array_version; + } + + _FORCE_INLINE_ int lightmap_array_get_size() const { + ERR_FAIL_COND_V(!using_lightmap_array, 0); //only for arrays + return lightmap_textures.size(); + } + + _FORCE_INLINE_ const Vector<RID> &lightmap_array_get_textures() const { + ERR_FAIL_COND_V(!using_lightmap_array, lightmap_textures); //only for arrays + return lightmap_textures; } /* PARTICLES */ diff --git a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp index 2bfdb7fffe..5cc3da8d4e 100644 --- a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp +++ b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp @@ -31,23 +31,25 @@ #include "render_pipeline_vertex_format_cache_rd.h" #include "core/os/memory.h" -RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id) { - +RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe) { RD::PipelineMultisampleState multisample_state_version = multisample_state; multisample_state_version.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_framebuffer_format_id); - RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, rasterization_state, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags); + RD::PipelineRasterizationState raster_state_version = rasterization_state; + raster_state_version.wireframe = p_wireframe; + + RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, raster_state_version, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags); ERR_FAIL_COND_V(pipeline.is_null(), RID()); versions = (Version *)memrealloc(versions, sizeof(Version) * (version_count + 1)); versions[version_count].framebuffer_id = p_framebuffer_format_id; versions[version_count].vertex_id = p_vertex_format_id; + versions[version_count].wireframe = p_wireframe; versions[version_count].pipeline = pipeline; version_count++; return pipeline; } void RenderPipelineVertexFormatCacheRD::_clear() { - if (versions) { for (uint32_t i = 0; i < version_count; i++) { //shader may be gone, so this may not be valid diff --git a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h index ecb1b42b06..cf15e79586 100644 --- a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h +++ b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h @@ -35,7 +35,6 @@ #include "servers/rendering/rendering_device.h" class RenderPipelineVertexFormatCacheRD { - SpinLock spin_lock; RID shader; @@ -51,13 +50,14 @@ class RenderPipelineVertexFormatCacheRD { struct Version { RD::VertexFormatID vertex_id; RD::FramebufferFormatID framebuffer_id; + bool wireframe; RID pipeline; }; Version *versions; uint32_t version_count; - RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id); + RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe); void _clear(); @@ -65,7 +65,7 @@ public: void setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0); void update_shader(RID p_shader); - _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id) { + _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe = false) { #ifdef DEBUG_ENABLED ERR_FAIL_COND_V_MSG(shader.is_null(), RID(), "Attempted to use an unused shader variant (shader is null),"); @@ -74,13 +74,13 @@ public: spin_lock.lock(); RID result; for (uint32_t i = 0; i < version_count; i++) { - if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id) { + if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id && versions[i].wireframe == p_wireframe) { result = versions[i].pipeline; spin_lock.unlock(); return result; } } - result = _generate_version(p_vertex_format_id, p_framebuffer_format_id); + result = _generate_version(p_vertex_format_id, p_framebuffer_format_id, p_wireframe); spin_lock.unlock(); return result; } diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp index 25856c92c7..d0b91df470 100644 --- a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp @@ -38,7 +38,6 @@ #define SL ShaderLanguage static String _mktab(int p_level) { - String tb; for (int i = 0; i < p_level; i++) { tb += "\t"; @@ -48,7 +47,6 @@ static String _mktab(int p_level) { } static String _typestr(SL::DataType p_type) { - String type = ShaderLanguage::get_datatype_name(p_type); if (ShaderLanguage::is_sampler_type(p_type)) { type = type.replace("sampler", "texture"); //we use textures instead of samplers @@ -57,9 +55,7 @@ static String _typestr(SL::DataType p_type) { } static int _get_datatype_size(SL::DataType p_type) { - switch (p_type) { - case SL::TYPE_VOID: return 0; case SL::TYPE_BOOL: @@ -120,8 +116,11 @@ static int _get_datatype_size(SL::DataType p_type) { return 16; case SL::TYPE_SAMPLERCUBE: return 16; + case SL::TYPE_SAMPLERCUBEARRAY: + return 16; case SL::TYPE_STRUCT: return 0; + case SL::TYPE_MAX: { ERR_FAIL_V(0); }; @@ -131,9 +130,7 @@ static int _get_datatype_size(SL::DataType p_type) { } static int _get_datatype_alignment(SL::DataType p_type) { - switch (p_type) { - case SL::TYPE_VOID: return 0; case SL::TYPE_BOOL: @@ -194,6 +191,8 @@ static int _get_datatype_alignment(SL::DataType p_type) { return 16; case SL::TYPE_SAMPLERCUBE: return 16; + case SL::TYPE_SAMPLERCUBEARRAY: + return 16; case SL::TYPE_STRUCT: return 0; case SL::TYPE_MAX: { @@ -203,8 +202,8 @@ static int _get_datatype_alignment(SL::DataType p_type) { ERR_FAIL_V(0); } -static String _interpstr(SL::DataInterpolation p_interp) { +static String _interpstr(SL::DataInterpolation p_interp) { switch (p_interp) { case SL::INTERPOLATION_FLAT: return "flat "; @@ -215,7 +214,6 @@ static String _interpstr(SL::DataInterpolation p_interp) { } static String _prestr(SL::DataPrecision p_pres) { - switch (p_pres) { case SL::PRECISION_LOWP: return "lowp "; @@ -230,7 +228,6 @@ static String _prestr(SL::DataPrecision p_pres) { } static String _qualstr(SL::ArgumentQualifier p_qual) { - switch (p_qual) { case SL::ARGUMENT_QUALIFIER_IN: return ""; @@ -243,18 +240,15 @@ static String _qualstr(SL::ArgumentQualifier p_qual) { } static String _opstr(SL::Operator p_op) { - return SL::get_operator_text(p_op); } static String _mkid(const String &p_id) { - String id = "m_" + p_id.replace("__", "_dus_"); return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl } static String f2sp0(float p_float) { - String num = rtoss(p_float); if (num.find(".") == -1 && num.find("e") == -1) { num += ".0"; @@ -263,18 +257,17 @@ static String f2sp0(float p_float) { } static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value> &p_values) { - switch (p_type) { case SL::TYPE_BOOL: return p_values[0].boolean ? "true" : "false"; case SL::TYPE_BVEC2: case SL::TYPE_BVEC3: case SL::TYPE_BVEC4: { - String text = "bvec" + itos(p_type - SL::TYPE_BOOL + 1) + "("; for (int i = 0; i < p_values.size(); i++) { - if (i > 0) + if (i > 0) { text += ","; + } text += p_values[i].boolean ? "true" : "false"; } @@ -287,11 +280,11 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo case SL::TYPE_IVEC2: case SL::TYPE_IVEC3: case SL::TYPE_IVEC4: { - String text = "ivec" + itos(p_type - SL::TYPE_INT + 1) + "("; for (int i = 0; i < p_values.size(); i++) { - if (i > 0) + if (i > 0) { text += ","; + } text += itos(p_values[i].sint); } @@ -304,11 +297,11 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo case SL::TYPE_UVEC2: case SL::TYPE_UVEC3: case SL::TYPE_UVEC4: { - String text = "uvec" + itos(p_type - SL::TYPE_UINT + 1) + "("; for (int i = 0; i < p_values.size(); i++) { - if (i > 0) + if (i > 0) { text += ","; + } text += itos(p_values[i].uint) + "u"; } @@ -320,11 +313,11 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo case SL::TYPE_VEC2: case SL::TYPE_VEC3: case SL::TYPE_VEC4: { - String text = "vec" + itos(p_type - SL::TYPE_FLOAT + 1) + "("; for (int i = 0; i < p_values.size(); i++) { - if (i > 0) + if (i > 0) { text += ","; + } text += f2sp0(p_values[i].real); } @@ -335,11 +328,11 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo case SL::TYPE_MAT2: case SL::TYPE_MAT3: case SL::TYPE_MAT4: { - String text = "mat" + itos(p_type - SL::TYPE_MAT2 + 2) + "("; for (int i = 0; i < p_values.size(); i++) { - if (i > 0) + if (i > 0) { text += ","; + } text += f2sp0(p_values[i].real); } @@ -365,7 +358,6 @@ String ShaderCompilerRD::_get_sampler_name(ShaderLanguage::TextureFilter p_filte } void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added) { - int fidx = -1; for (int i = 0; i < p_node->functions.size(); i++) { @@ -378,7 +370,6 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S ERR_FAIL_COND(fidx == -1); for (Set<StringName>::Element *E = p_node->functions[fidx].uses_function.front(); E; E = E->next()) { - if (added.has(E->get())) { continue; //was added already } @@ -405,9 +396,9 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S header = _typestr(fnode->return_type) + " " + _mkid(fnode->name) + "("; } for (int i = 0; i < fnode->arguments.size(); i++) { - - if (i > 0) + if (i > 0) { header += ", "; + } if (fnode->arguments[i].type == SL::TYPE_STRUCT) { header += _qualstr(fnode->arguments[i].qualifier) + _mkid(fnode->arguments[i].type_str) + " " + _mkid(fnode->arguments[i].name); } else { @@ -489,19 +480,14 @@ static String _get_global_variable_from_type_and_index(const String &p_buffer, c } String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning) { - String code; switch (p_node->type) { - case SL::Node::TYPE_SHADER: { - SL::ShaderNode *pnode = (SL::ShaderNode *)p_node; for (int i = 0; i < pnode->render_modes.size(); i++) { - if (p_default_actions.render_mode_defines.has(pnode->render_modes[i]) && !used_rmode_defines.has(pnode->render_modes[i])) { - r_gen_code.defines.push_back(p_default_actions.render_mode_defines[pnode->render_modes[i]]); used_rmode_defines.insert(pnode->render_modes[i]); } @@ -519,7 +505,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge // structs for (int i = 0; i < pnode->vstructs.size(); i++) { - SL::StructNode *st = pnode->vstructs[i].shader_struct; String struct_code; @@ -555,11 +540,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge int max_uniforms = 0; for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) { - if (SL::is_sampler_type(E->get().type)) { max_texture_uniforms++; } else { - if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; //instances are indexed directly, dont need index uniforms } @@ -579,7 +562,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge bool uses_uniforms = false; for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) { - String ucode; if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { @@ -621,7 +603,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge r_gen_code.texture_uniforms.write[E->get().texture_order] = texture; } else { if (!uses_uniforms) { - r_gen_code.defines.push_back(String("#define USE_MATERIAL_UNIFORMS\n")); uses_uniforms = true; } @@ -647,7 +628,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge // add up int offset = 0; for (int i = 0; i < uniform_sizes.size(); i++) { - int align = offset % uniform_alignments[i]; if (align != 0) { @@ -667,9 +647,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge #else // add up for (int i = 0; i < uniform_sizes.size(); i++) { - if (i > 0) { - int align = uniform_sizes[i - 1] % uniform_alignments[i]; if (align != 0) { uniform_sizes[i - 1] += uniform_alignments[i] - align; @@ -681,7 +659,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge //offset r_gen_code.uniform_offsets.resize(uniform_sizes.size()); for (int i = 0; i < uniform_sizes.size(); i++) { - if (i > 0) r_gen_code.uniform_offsets[i] = uniform_sizes[i - 1]; else @@ -707,7 +684,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge uint32_t index = p_default_actions.base_varying_index; for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) { - String vcode; String interp_mode = _interpstr(E->get().interpolation); vcode += _prestr(E->get().precision); @@ -759,7 +735,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge Set<StringName> added_fragment; //share for light for (int i = 0; i < pnode->functions.size(); i++) { - SL::FunctionNode *fnode = pnode->functions[i].function; function = fnode; @@ -767,19 +742,16 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge current_func_name = fnode->name; if (fnode->name == vertex_name) { - _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.vertex_global, added_vtx); r_gen_code.vertex = function_code[vertex_name]; } if (fnode->name == fragment_name) { - _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.fragment_global, added_fragment); r_gen_code.fragment = function_code[fragment_name]; } if (fnode->name == light_name) { - _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.fragment_global, added_fragment); r_gen_code.light = function_code[light_name]; } @@ -789,10 +761,8 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge //code+=dump_node_code(pnode->body,p_level); } break; case SL::Node::TYPE_STRUCT: { - } break; case SL::Node::TYPE_FUNCTION: { - } break; case SL::Node::TYPE_BLOCK: { SL::BlockNode *bnode = (SL::BlockNode *)p_node; @@ -803,7 +773,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } for (int i = 0; i < bnode->statements.size(); i++) { - String scode = _dump_node_code(bnode->statements[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->single_statement) { @@ -865,9 +834,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge used_flag_pointers.insert(vnode->name); } - if (p_default_actions.renames.has(vnode->name)) + if (p_default_actions.renames.has(vnode->name)) { code = p_default_actions.renames[vnode->name]; - else { + } else { if (shader->uniforms.has(vnode->name)) { //its a uniform! const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[vnode->name]; @@ -925,7 +894,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge code += ")"; } break; case SL::Node::TYPE_ARRAY_DECLARATION: { - SL::ArrayDeclarationNode *adnode = (SL::ArrayDeclarationNode *)p_node; String declaration; if (adnode->is_const) { @@ -991,10 +959,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge used_flag_pointers.insert(anode->name); } - if (p_default_actions.renames.has(anode->name)) + if (p_default_actions.renames.has(anode->name)) { code = p_default_actions.renames[anode->name]; - else + } else { code = _mkid(anode->name); + } if (anode->call_expression != nullptr) { code += "."; @@ -1026,7 +995,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge SL::OperatorNode *onode = (SL::OperatorNode *)p_node; switch (onode->op) { - case SL::OP_ASSIGN: case SL::OP_ASSIGN_ADD: case SL::OP_ASSIGN_SUB: @@ -1054,7 +1022,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge case SL::OP_CALL: case SL::OP_STRUCT: case SL::OP_CONSTRUCT: { - ERR_FAIL_COND_V(onode->arguments[0]->type != SL::Node::TYPE_VARIABLE, String()); SL::VariableNode *vnode = (SL::VariableNode *)onode->arguments[0]; @@ -1065,7 +1032,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } else if (onode->op == SL::OP_CONSTRUCT) { code += String(vnode->name); } else { - if (internal_functions.has(vnode->name)) { code += vnode->name; is_texture_func = texture_functions.has(vnode->name); @@ -1079,11 +1045,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge code += "("; for (int i = 1; i < onode->arguments.size(); i++) { - if (i > 1) + if (i > 1) { code += ", "; + } String node_code = _dump_node_code(onode->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); if (is_texture_func && i == 1 && onode->arguments[i]->type == SL::Node::TYPE_VARIABLE) { - //need to map from texture to sampler in order to sample const SL::VariableNode *varnode = static_cast<const SL::VariableNode *>(onode->arguments[i]); @@ -1129,7 +1095,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge code += ")"; } break; case SL::OP_INDEX: { - code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); code += "["; code += _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); @@ -1137,7 +1102,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } break; case SL::OP_SELECT_IF: { - code += "("; code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); code += "?"; @@ -1149,7 +1113,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } break; default: { - code = "(" + _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")"; break; } @@ -1159,37 +1122,29 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge case SL::Node::TYPE_CONTROL_FLOW: { SL::ControlFlowNode *cfnode = (SL::ControlFlowNode *)p_node; if (cfnode->flow_op == SL::FLOW_OP_IF) { - code += _mktab(p_level) + "if (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n"; code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); if (cfnode->blocks.size() == 2) { - code += _mktab(p_level) + "else\n"; code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); } } else if (cfnode->flow_op == SL::FLOW_OP_SWITCH) { - code += _mktab(p_level) + "switch (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n"; code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); } else if (cfnode->flow_op == SL::FLOW_OP_CASE) { - code += _mktab(p_level) + "case " + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ":\n"; code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); } else if (cfnode->flow_op == SL::FLOW_OP_DEFAULT) { - code += _mktab(p_level) + "default:\n"; code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); } else if (cfnode->flow_op == SL::FLOW_OP_DO) { - code += _mktab(p_level) + "do"; code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ");"; } else if (cfnode->flow_op == SL::FLOW_OP_WHILE) { - code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n"; code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); } else if (cfnode->flow_op == SL::FLOW_OP_FOR) { - String left = _dump_node_code(cfnode->blocks[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); String middle = _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); String right = _dump_node_code(cfnode->expressions[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); @@ -1197,14 +1152,12 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); } else if (cfnode->flow_op == SL::FLOW_OP_RETURN) { - if (cfnode->expressions.size()) { code = "return " + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ";"; } else { code = "return;"; } } else if (cfnode->flow_op == SL::FLOW_OP_DISCARD) { - if (p_actions.usage_flag_pointers.has("DISCARD") && !used_flag_pointers.has("DISCARD")) { *p_actions.usage_flag_pointers["DISCARD"] = true; used_flag_pointers.insert("DISCARD"); @@ -1212,10 +1165,8 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge code = "discard;"; } else if (cfnode->flow_op == SL::FLOW_OP_CONTINUE) { - code = "continue;"; } else if (cfnode->flow_op == SL::FLOW_OP_BREAK) { - code = "break;"; } @@ -1241,11 +1192,9 @@ ShaderLanguage::DataType ShaderCompilerRD::_get_variable_type(const StringName & } Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) { - Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_types(), _get_variable_type); if (err != OK) { - Vector<String> shader = p_code.split("\n"); for (int i = 0; i < shader.size(); i++) { print_line(itos(i + 1) + " " + shader[i]); diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.h b/servers/rendering/rasterizer_rd/shader_compiler_rd.h index 16d53197a7..eaad34b8cd 100644 --- a/servers/rendering/rasterizer_rd/shader_compiler_rd.h +++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.h @@ -39,7 +39,6 @@ class ShaderCompilerRD { public: struct IdentifierActions { - Map<StringName, Pair<int *, int>> render_mode_values; Map<StringName, bool *> render_mode_flags; Map<StringName, bool *> usage_flag_pointers; @@ -49,7 +48,6 @@ public: }; struct GeneratedCode { - Vector<String> defines; struct Texture { StringName name; @@ -77,7 +75,6 @@ public: }; struct DefaultIdentifierActions { - Map<StringName, String> renames; Map<StringName, String> render_mode_defines; Map<StringName, String> usage_defines; diff --git a/servers/rendering/rasterizer_rd/shader_rd.cpp b/servers/rendering/rasterizer_rd/shader_rd.cpp index d60a58813e..8c57651263 100644 --- a/servers/rendering/rasterizer_rd/shader_rd.cpp +++ b/servers/rendering/rasterizer_rd/shader_rd.cpp @@ -35,7 +35,6 @@ #include "servers/rendering/rendering_device.h" void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name) { - name = p_name; //split vertex and shader code (thank you, shader compiler programmers from you know what company). if (p_vertex_code) { @@ -64,7 +63,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con if (cpos == -1) { vertex_code1 = code.ascii(); } else { - vertex_code1 = code.substr(0, cpos).ascii(); String code2 = code.substr(cpos + globals_tag.length(), code.length()); @@ -72,7 +70,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con if (cpos == -1) { vertex_code2 = code2.ascii(); } else { - vertex_code2 = code2.substr(0, cpos).ascii(); vertex_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii(); } @@ -106,7 +103,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con if (cpos == -1) { fragment_code1 = code.ascii(); } else { - fragment_code1 = code.substr(0, cpos).ascii(); //print_line("CODE1:\n"+String(fragment_code1.get_data())); @@ -116,7 +112,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con if (cpos == -1) { fragment_code2 = code2.ascii(); } else { - fragment_code2 = code2.substr(0, cpos).ascii(); //print_line("CODE2:\n"+String(fragment_code2.get_data())); @@ -126,7 +121,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con if (cpos == -1) { fragment_code3 = code3.ascii(); } else { - fragment_code3 = code3.substr(0, cpos).ascii(); //print_line("CODE3:\n"+String(fragment_code3.get_data())); fragment_code4 = code3.substr(cpos + code_tag.length(), code3.length()).ascii(); @@ -165,7 +159,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con if (cpos == -1) { compute_code1 = code.ascii(); } else { - compute_code1 = code.substr(0, cpos).ascii(); String code2 = code.substr(cpos + globals_tag.length(), code.length()); @@ -173,7 +166,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con if (cpos == -1) { compute_code2 = code2.ascii(); } else { - compute_code2 = code2.substr(0, cpos).ascii(); compute_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii(); } @@ -183,7 +175,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con } RID ShaderRD::version_create() { - //initialize() was never called ERR_FAIL_COND_V(variant_defines.size() == 0, RID()); @@ -208,7 +199,6 @@ void ShaderRD::_clear_version(Version *p_version) { } void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { - Vector<RD::ShaderStageData> stages; String error; @@ -250,7 +240,6 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { if (stage.spir_v.size() == 0) { build_ok = false; } else { - stage.shader_stage = RD::SHADER_STAGE_VERTEX; stages.push_back(stage); } @@ -295,7 +284,6 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { if (stage.spir_v.size() == 0) { build_ok = false; } else { - stage.shader_stage = RD::SHADER_STAGE_FRAGMENT; stages.push_back(stage); } @@ -336,7 +324,6 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { if (stage.spir_v.size() == 0) { build_ok = false; } else { - stage.shader_stage = RD::SHADER_STAGE_COMPUTE; stages.push_back(stage); } @@ -361,7 +348,6 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { } void ShaderRD::_compile_version(Version *p_version) { - _clear_version(p_version); p_version->valid = false; @@ -373,7 +359,6 @@ void ShaderRD::_compile_version(Version *p_version) { RasterizerRD::thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version); #else for (int i = 0; i < variant_defines.size(); i++) { - _compile_variant(i, p_version); } #endif @@ -402,7 +387,6 @@ void ShaderRD::_compile_version(Version *p_version) { } void ShaderRD::version_set_code(RID p_version, const String &p_uniforms, const String &p_vertex_globals, const String &p_vertex_code, const String &p_fragment_globals, const String &p_fragment_light, const String &p_fragment_code, const Vector<String> &p_custom_defines) { - ERR_FAIL_COND(is_compute); Version *version = version_owner.getornull(p_version); @@ -427,7 +411,6 @@ void ShaderRD::version_set_code(RID p_version, const String &p_uniforms, const S } void ShaderRD::version_set_compute_code(RID p_version, const String &p_uniforms, const String &p_compute_globals, const String &p_compute_code, const Vector<String> &p_custom_defines) { - ERR_FAIL_COND(!is_compute); Version *version = version_owner.getornull(p_version); @@ -460,7 +443,6 @@ bool ShaderRD::version_is_valid(RID p_version) { } bool ShaderRD::version_free(RID p_version) { - if (version_owner.owns(p_version)) { Version *version = version_owner.getornull(p_version); _clear_version(version); @@ -477,7 +459,6 @@ void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String 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()); } } diff --git a/servers/rendering/rasterizer_rd/shader_rd.h b/servers/rendering/rasterizer_rd/shader_rd.h index 6635b08cc8..d9bb068ba6 100644 --- a/servers/rendering/rasterizer_rd/shader_rd.h +++ b/servers/rendering/rasterizer_rd/shader_rd.h @@ -43,7 +43,6 @@ */ class ShaderRD { - //versions CharString general_defines; Vector<CharString> variant_defines; diff --git a/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl b/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl index 7153fe6b17..18555d9672 100644 --- a/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl +++ b/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl @@ -51,6 +51,7 @@ layout(push_constant, binding = 1, std430) uniform Params { float jitter_seed; uint pad[2]; } + params; //used to work around downsampling filter @@ -69,7 +70,6 @@ float get_depth_at_pos(vec2 uv) { } float get_blur_size(float depth) { - if (params.blur_near_active && depth < params.blur_near_begin) { return -(1.0 - smoothstep(params.blur_near_end, params.blur_near_begin, depth)) * params.blur_size - DEPTH_GAP; //near blur is negative } @@ -95,7 +95,6 @@ float hash12n(vec2 p) { #if defined(MODE_BOKEH_BOX) || defined(MODE_BOKEH_HEXAGONAL) vec4 weighted_filter_dir(vec2 dir, vec2 uv, vec2 pixel_size) { - dir *= pixel_size; vec4 color = texture(color_texture, uv); @@ -109,7 +108,6 @@ vec4 weighted_filter_dir(vec2 dir, vec2 uv, vec2 pixel_size) { } for (int i = -params.blur_steps; i <= params.blur_steps; i++) { - if (i == 0) { continue; } @@ -141,7 +139,6 @@ vec4 weighted_filter_dir(vec2 dir, vec2 uv, vec2 pixel_size) { #endif void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); if (any(greaterThan(pos, params.size))) { //too large, do nothing @@ -218,7 +215,6 @@ void main() { float radius = params.blur_scale; for (float ang = 0.0; radius < params.blur_size; ang += GOLDEN_ANGLE) { - vec2 suv = uv + vec2(cos(ang), sin(ang)) * pixel_size * radius; vec4 sample_color = texture(color_texture, suv); float sample_size = abs(sample_color.a); diff --git a/servers/rendering/rasterizer_rd/shaders/canvas.glsl b/servers/rendering/rasterizer_rd/shaders/canvas.glsl index 28135fce31..fea36eb65c 100644 --- a/servers/rendering/rasterizer_rd/shaders/canvas.glsl +++ b/servers/rendering/rasterizer_rd/shaders/canvas.glsl @@ -40,7 +40,6 @@ VERTEX_SHADER_GLOBALS /* clang-format on */ void main() { - vec4 instance_custom = vec4(0.0); #ifdef USE_PRIMITIVE @@ -149,7 +148,6 @@ VERTEX_SHADER_CODE color_interp = color; if (bool(draw_data.flags & FLAGS_USE_PIXEL_SNAP)) { - vertex = floor(vertex + 0.5); // precision issue on some hardware creates artifacts within texture // offset uv by a small amount to avoid @@ -258,7 +256,6 @@ vec4 light_compute( vec2 screen_uv, vec2 uv, vec4 color) { - vec4 light = vec4(0.0); /* clang-format off */ LIGHT_SHADER_CODE @@ -271,7 +268,6 @@ LIGHT_SHADER_CODE #ifdef USE_NINEPATCH float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, float margin_begin, float margin_end, int np_repeat, inout int draw_center) { - float tex_size = 1.0 / tex_pixel_size; if (pixel < margin_begin) { @@ -313,7 +309,6 @@ float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, flo #endif void main() { - vec4 color = color_interp; vec2 uv = uv_interp; vec2 vertex = vertex_interp; @@ -335,7 +330,6 @@ void main() { #endif if (bool(draw_data.flags & FLAGS_CLIP_RECT_UV)) { - uv = clamp(uv, draw_data.src_rect.xy, draw_data.src_rect.xy + abs(draw_data.src_rect.zw)); } @@ -458,7 +452,6 @@ FRAGMENT_SHADER_CODE light_color.rgb *= light_base_color.rgb * light_base_color.a; if (normal_used) { - vec3 light_pos = vec3(light_array.data[light_base].position, light_array.data[light_base].height); vec3 pos = light_vertex; vec3 light_vec = normalize(light_pos - pos); @@ -490,7 +483,6 @@ FRAGMENT_SHADER_CODE } if (bool(light_array.data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) { - vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_array.data[light_base].shadow_matrix[0], light_array.data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations. vec2 pos_norm = normalize(shadow_pos); diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl b/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl index 7b30cc8fe9..3e0d5c4ffc 100644 --- a/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl +++ b/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl @@ -7,18 +7,17 @@ layout(location = 0) in highp vec3 vertex; /* clang-format on */ layout(push_constant, binding = 0, std430) uniform Constants { - mat4 projection; mat2x4 modelview; vec2 direction; vec2 pad; } + constants; layout(location = 0) out highp float depth; void main() { - highp vec4 vtx = vec4(vertex, 1.0) * mat4(constants.modelview[0], constants.modelview[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); depth = dot(constants.direction, vtx.xy); @@ -35,6 +34,5 @@ layout(location = 0) in highp float depth; layout(location = 0) out highp float distance_buf; void main() { - distance_buf = depth; } diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl index a39866004b..ba05b8b2fb 100644 --- a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl +++ b/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl @@ -51,6 +51,7 @@ layout(push_constant, binding = 0, std430) uniform DrawData { vec2 color_texture_pixel_size; uint lights[4]; } + draw_data; // The values passed per draw primitives are cached within it @@ -82,6 +83,7 @@ layout(set = 2, binding = 0, std140) uniform CanvasData { float time_pad; //uint light_count; } + canvas_data; layout(set = 2, binding = 1) uniform textureBuffer skeleton_buffer; @@ -90,6 +92,7 @@ layout(set = 2, binding = 2, std140) uniform SkeletonData { mat4 skeleton_transform; //in world coordinates mat4 skeleton_transform_inverse; } + skeleton_data; #ifdef USE_LIGHTING @@ -123,6 +126,7 @@ struct Light { layout(set = 2, binding = 3, std140) uniform LightData { Light data[MAX_LIGHTS]; } + light_array; layout(set = 2, binding = 4) uniform texture2D light_textures[MAX_LIGHT_TEXTURES]; @@ -135,6 +139,7 @@ layout(set = 2, binding = 6) uniform sampler shadow_sampler; layout(set = 2, binding = 7, std430) restrict readonly buffer GlobalVariableData { vec4 data[]; } + global_variables; /* SET3: Render Target Data */ diff --git a/servers/rendering/rasterizer_rd/shaders/copy.glsl b/servers/rendering/rasterizer_rd/shaders/copy.glsl index 2d7661f65f..249e7963d0 100644 --- a/servers/rendering/rasterizer_rd/shaders/copy.glsl +++ b/servers/rendering/rasterizer_rd/shaders/copy.glsl @@ -37,9 +37,16 @@ layout(push_constant, binding = 1, std430) uniform Params { float camera_z_near; uint pad2[2]; } + params; +#ifdef MODE_CUBEMAP_ARRAY_TO_PANORAMA +layout(set = 0, binding = 0) uniform samplerCubeArray source_color; +#elif defined(MODE_CUBEMAP_TO_PANORAMA) +layout(set = 0, binding = 0) uniform samplerCube source_color; +#else layout(set = 0, binding = 0) uniform sampler2D source_color; +#endif #ifdef GLOW_USE_AUTO_EXPOSURE layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure; @@ -54,10 +61,9 @@ layout(rgba32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_bu #endif void main() { - // Pixel being shaded ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(pos, params.section.zw))) { //too large, do nothing + if (any(greaterThanEqual(pos, params.section.zw))) { //too large, do nothing return; } @@ -78,7 +84,6 @@ void main() { //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect if (bool(params.flags & FLAG_HORIZONTAL)) { - ivec2 base_pos = (pos + params.section.xy) << 1; vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.214607; color += texelFetch(source_color, base_pos + ivec2(1, 0), 0) * 0.189879; @@ -89,7 +94,6 @@ void main() { color += texelFetch(source_color, base_pos + ivec2(-3, 0), 0) * 0.071303; imageStore(dest_buffer, pos + params.target, color); } else { - ivec2 base_pos = (pos + params.section.xy); vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.38774; color += texelFetch(source_color, base_pos + ivec2(0, 1), 0) * 0.24477; @@ -115,7 +119,6 @@ void main() { vec4 color = vec4(0.0); if (bool(params.flags & FLAG_HORIZONTAL)) { - ivec2 base_pos = (pos + params.section.xy) << 1; ivec2 section_begin = params.section.xy << 1; ivec2 section_end = section_begin + (params.section.zw << 1); @@ -129,7 +132,6 @@ void main() { GLOW_ADD(ivec2(-3, 0), 0.106595); color *= params.glow_strength; } else { - ivec2 base_pos = pos + params.section.xy; ivec2 section_begin = params.section.xy; ivec2 section_end = section_begin + params.section.zw; @@ -217,4 +219,25 @@ void main() { imageStore(dest_buffer, pos + params.target, color); #endif + +#if defined(MODE_CUBEMAP_TO_PANORAMA) || defined(MODE_CUBEMAP_ARRAY_TO_PANORAMA) + + const float PI = 3.14159265359; + vec2 uv = vec2(pos) / vec2(params.section.zw); + uv.y = 1.0 - uv.y; + float phi = uv.x * 2.0 * PI; + float theta = uv.y * PI; + + vec3 normal; + normal.x = sin(phi) * sin(theta) * -1.0; + normal.y = cos(theta); + normal.z = cos(phi) * sin(theta) * -1.0; + +#ifdef MODE_CUBEMAP_TO_PANORAMA + vec4 color = textureLod(source_color, normal, params.camera_z_far); //the biggest the lod the least the acne +#else + vec4 color = textureLod(source_color, vec4(normal, params.camera_z_far), 0.0); //the biggest the lod the least the acne +#endif + imageStore(dest_buffer, pos + params.target, color); +#endif } diff --git a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl index 07f8d09743..5f53045afd 100644 --- a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl +++ b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl @@ -17,10 +17,10 @@ layout(push_constant, binding = 1, std430) uniform Params { bool force_luminance; uint pad[3]; } + params; void main() { - vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); uv_interp = base_arr[gl_VertexIndex]; @@ -63,7 +63,6 @@ layout(set = 0, binding = 0) uniform sampler2D source_color; layout(location = 0) out vec4 frag_color; void main() { - vec2 uv = uv_interp; #ifdef MODE_PANORAMA_TO_DP diff --git a/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl b/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl index 02ebe1a53b..133d97ffcb 100644 --- a/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl +++ b/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl @@ -18,12 +18,12 @@ layout(push_constant, binding = 1, std430) uniform Params { float z_near; bool z_flip; } + params; layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D depth_buffer; void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing return; diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl b/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl index 9f3ecf6053..8d88e46727 100644 --- a/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl +++ b/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl @@ -37,6 +37,7 @@ layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly imageCube dest_ layout(push_constant, binding = 1, std430) uniform Params { uint face_size; } + params; #define M_PI 3.14159265359 @@ -46,26 +47,31 @@ void get_dir_0(out vec3 dir, in float u, in float v) { dir[1] = v; dir[2] = -u; } + void get_dir_1(out vec3 dir, in float u, in float v) { dir[0] = -1.0; dir[1] = v; dir[2] = u; } + void get_dir_2(out vec3 dir, in float u, in float v) { dir[0] = u; dir[1] = 1.0; dir[2] = -v; } + void get_dir_3(out vec3 dir, in float u, in float v) { dir[0] = u; dir[1] = -1.0; dir[2] = v; } + void get_dir_4(out vec3 dir, in float u, in float v) { dir[0] = u; dir[1] = v; dir[2] = 1.0; } + void get_dir_5(out vec3 dir, in float u, in float v) { dir[0] = -u; dir[1] = v; diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl b/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl index 193d0a8a3c..20bc0e2d0d 100644 --- a/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl +++ b/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl @@ -51,11 +51,13 @@ layout(rgba16f, set = 2, binding = 6) uniform restrict writeonly imageCube dest_ layout(set = 1, binding = 0, std430) buffer restrict readonly Data { vec4[7][5][3][24] coeffs; } + data; #else layout(set = 1, binding = 0, std430) buffer restrict readonly Data { vec4[7][5][6] coeffs; } + data; #endif diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl b/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl index e85996fa1a..0e6e51f0de 100644 --- a/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl +++ b/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl @@ -21,6 +21,7 @@ layout(push_constant, binding = 1, std430) uniform Params { bool use_direct_write; float face_size; } + params; #define M_PI 3.14159265359 @@ -119,10 +120,8 @@ void main() { //vec4 color = color_interp; if (params.use_direct_write) { - imageStore(dest_cubemap, ivec3(id), vec4(texture(source_cube, N).rgb, 1.0)); } else { - vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); for (uint sampleNum = 0u; sampleNum < params.sample_count; sampleNum++) { @@ -135,7 +134,6 @@ void main() { float ndotl = clamp(dot(N, L), 0.0, 1.0); if (ndotl > 0.0) { - sum.rgb += textureLod(source_cube, L, 0.0).rgb * ndotl; sum.a += ndotl; } diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe.glsl b/servers/rendering/rasterizer_rd/shaders/giprobe.glsl index fd09f96a57..60c4032d80 100644 --- a/servers/rendering/rasterizer_rd/shaders/giprobe.glsl +++ b/servers/rendering/rasterizer_rd/shaders/giprobe.glsl @@ -24,6 +24,7 @@ struct CellChildren { layout(set = 0, binding = 1, std430) buffer CellChildrenBuffer { CellChildren data[]; } + cell_children; struct CellData { @@ -36,6 +37,7 @@ struct CellData { layout(set = 0, binding = 2, std430) buffer CellDataBuffer { CellData data[]; } + cell_data; #endif // MODE DYNAMIC @@ -47,7 +49,6 @@ cell_data; #if defined(MODE_COMPUTE_LIGHT) || defined(MODE_DYNAMIC_LIGHTING) struct Light { - uint type; float energy; float radius; @@ -66,6 +67,7 @@ struct Light { layout(set = 0, binding = 3, std140) uniform Lights { Light data[MAX_LIGHTS]; } + lights; #endif // MODE COMPUTE LIGHT @@ -97,11 +99,13 @@ layout(push_constant, binding = 0, std430) uniform Params { float aniso_strength; uint pad; } + params; layout(set = 0, binding = 4, std430) buffer Outputs { vec4 data[]; } + outputs; #endif // MODE DYNAMIC @@ -144,6 +148,7 @@ layout(push_constant, binding = 0, std430) uniform Params { float propagation; float pad[3]; } + params; #ifdef MODE_DYNAMIC_LIGHTING @@ -191,7 +196,6 @@ layout(r16ui, set = 0, binding = 13) uniform restrict writeonly uimage3D aniso_n #if defined(MODE_COMPUTE_LIGHT) || defined(MODE_DYNAMIC_LIGHTING) float raymarch(float distance, float distance_adv, vec3 from, vec3 direction) { - vec3 cell_size = 1.0 / vec3(params.limits); float occlusion = 1.0; while (distance > 0.5) { //use this to avoid precision errors @@ -213,14 +217,11 @@ float raymarch(float distance, float distance_adv, vec3 from, vec3 direction) { } bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 light_pos) { - if (lights.data[light].type == LIGHT_TYPE_DIRECTIONAL) { - light_pos = pos - lights.data[light].direction * length(vec3(params.limits)); attenuation = 1.0; } else { - light_pos = lights.data[light].position; float distance = length(pos - light_pos); if (distance >= lights.data[light].radius) { @@ -230,7 +231,6 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 attenuation = pow(clamp(1.0 - distance / lights.data[light].radius, 0.0001, 1.0), lights.data[light].attenuation); if (lights.data[light].type == LIGHT_TYPE_SPOT) { - vec3 rel = normalize(pos - light_pos); float angle = acos(dot(rel, lights.data[light].direction)); if (angle > lights.data[light].spot_angle_radians) { @@ -246,7 +246,6 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 } float get_normal_advance(vec3 p_normal) { - vec3 normal = p_normal; vec3 unorm = abs(normal); @@ -269,7 +268,6 @@ float get_normal_advance(vec3 p_normal) { } void clip_segment(vec4 plane, vec3 begin, inout vec3 end) { - vec3 segment = begin - end; float den = dot(plane.xyz, segment); @@ -302,7 +300,6 @@ bool compute_light_at_pos(uint index, vec3 pos, vec3 normal, inout vec3 light, i } if (lights.data[index].has_shadow) { - float distance_adv = get_normal_advance(light_dir); vec3 to = pos; @@ -352,7 +349,6 @@ bool compute_light_at_pos(uint index, vec3 pos, vec3 normal, inout vec3 light, i #endif // MODE COMPUTE LIGHT void main() { - #ifndef MODE_DYNAMIC uint cell_index = gl_GlobalInvocationID.x; @@ -383,7 +379,6 @@ void main() { #endif for (uint i = 0; i < params.light_count; i++) { - vec3 light; vec3 light_dir; if (!compute_light_at_pos(i, pos, normal.xyz, light, light_dir)) { @@ -394,7 +389,6 @@ void main() { #ifdef MODE_ANISOTROPIC for (uint j = 0; j < 6; j++) { - accum[j] += max(0.0, dot(accum_dirs[j], -light_dir)) * light; } #else @@ -461,7 +455,6 @@ void main() { #endif if (length(normal.xyz) > 0.2) { - vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); vec3 tangent = normalize(cross(v0, normal.xyz)); vec3 bitangent = normalize(cross(tangent, normal.xyz)); @@ -481,11 +474,9 @@ void main() { float tan_half_angle = 0.577; for (int i = 0; i < MAX_CONE_DIRS; i++) { - vec3 direction = normal_mat * cone_dirs[i]; vec4 color = vec4(0.0); { - float dist = 1.5; float max_distance = length(vec3(params.limits)); vec3 cell_size = 1.0 / vec3(params.limits); @@ -519,7 +510,6 @@ void main() { color *= cone_weights[i] * vec4(albedo.rgb, 1.0) * params.dynamic_range; //restore range #ifdef MODE_ANISOTROPIC for (uint j = 0; j < 6; j++) { - accum[j] += max(0.0, dot(accum_dirs[j], direction)) * color.rgb; } #else @@ -594,7 +584,6 @@ void main() { #ifdef MODE_WRITE_TEXTURE { - #ifdef MODE_ANISOTROPIC vec3 accum_total = vec3(0.0); accum_total += outputs.data[cell_index * 6 + 0].rgb; @@ -665,7 +654,6 @@ void main() { vec3 accum = vec3(0.0); for (uint i = 0; i < params.light_count; i++) { - vec3 light; vec3 light_dir; if (!compute_light_at_pos(i, vec3(pos) * params.pos_multiplier, normal, light, light_dir)) { diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl b/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl index c0fcb9a8c4..db3043fb28 100644 --- a/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl +++ b/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl @@ -16,6 +16,7 @@ struct CellData { layout(set = 0, binding = 1, std140) buffer CellDataBuffer { CellData data[]; } + cell_data; layout(set = 0, binding = 2) uniform texture3D color_tex; @@ -28,7 +29,6 @@ layout(set = 0, binding = 5) uniform texture3D aniso_neg_tex; #endif layout(push_constant, binding = 0, std430) uniform Params { - mat4 projection; uint cell_offset; float dynamic_range; @@ -37,12 +37,12 @@ layout(push_constant, binding = 0, std430) uniform Params { ivec3 bounds; uint pad; } + params; layout(location = 0) out vec4 color_interp; void main() { - const vec3 cube_triangles[36] = vec3[]( vec3(-1.0f, -1.0f, -1.0f), vec3(-1.0f, -1.0f, 1.0f), @@ -184,7 +184,6 @@ layout(location = 0) in vec4 color_interp; layout(location = 0) out vec4 frag_color; void main() { - frag_color = color_interp; #ifdef MODE_DEBUG_LIGHT_FULL diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl b/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl index d089236723..37ea673fbe 100644 --- a/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl +++ b/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl @@ -20,6 +20,7 @@ struct CellChildren { layout(set = 0, binding = 1, std430) buffer CellChildrenBuffer { CellChildren data[]; } + cell_children; struct CellData { @@ -32,6 +33,7 @@ struct CellData { layout(set = 0, binding = 2, std430) buffer CellDataBuffer { CellData data[]; } + cell_data; layout(r8ui, set = 0, binding = 3) uniform restrict writeonly uimage3D sdf_tex; @@ -42,10 +44,10 @@ layout(push_constant, binding = 0, std430) uniform Params { uint pad0; uint pad1; } + params; void main() { - vec3 pos = vec3(gl_GlobalInvocationID); float closest_dist = 100000.0; @@ -82,6 +84,7 @@ float distance_to_aabb(ivec3 pos, ivec3 aabb_pos, ivec3 aabb_size) { return length(delta); } + void main() { ivec3 pos = ivec3(gl_GlobalInvocationID); diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl b/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl index c832223b1e..7a79f6a3ac 100644 --- a/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl +++ b/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl @@ -18,6 +18,7 @@ struct CellChildren { layout(set = 0, binding = 1, std430) buffer CellChildrenBuffer { CellChildren data[]; } + cell_children; struct CellData { @@ -30,6 +31,7 @@ struct CellData { layout(set = 0, binding = 2, std430) buffer CellDataBuffer { CellData data[]; } + cell_data; #define LIGHT_TYPE_DIRECTIONAL 0 @@ -57,6 +59,7 @@ struct Light { layout(set = 0, binding = 3, std140) uniform Lights { Light data[MAX_LIGHTS]; } + lights; #endif @@ -74,17 +77,18 @@ layout(push_constant, binding = 0, std430) uniform Params { uint cell_count; uint pad[2]; } + params; layout(set = 0, binding = 4, std140) uniform Outputs { vec4 data[]; } + output; #ifdef MODE_COMPUTE_LIGHT uint raymarch(float distance, float distance_adv, vec3 from, vec3 direction) { - uint result = NO_CHILDREN; ivec3 size = ivec3(max(max(params.limits.x, params.limits.y), params.limits.z)); @@ -96,12 +100,10 @@ uint raymarch(float distance, float distance_adv, vec3 from, vec3 direction) { ivec3 pos = ivec3(from); if (all(greaterThanEqual(pos, ivec3(0))) && all(lessThan(pos, size))) { - ivec3 ofs = ivec3(0); ivec3 half_size = size / 2; for (int i = 0; i < params.stack_size - 1; i++) { - bvec3 greater = greaterThanEqual(pos, ofs + half_size); ofs += mix(ivec3(0), half_size, greater); @@ -137,14 +139,11 @@ uint raymarch(float distance, float distance_adv, vec3 from, vec3 direction) { } bool compute_light_vector(uint light, uint cell, vec3 pos, out float attenuation, out vec3 light_pos) { - if (lights.data[light].type == LIGHT_TYPE_DIRECTIONAL) { - light_pos = pos - lights.data[light].direction * length(vec3(params.limits)); attenuation = 1.0; } else { - light_pos = lights.data[light].position; float distance = length(pos - light_pos); if (distance >= lights.data[light].radius) { @@ -154,7 +153,6 @@ bool compute_light_vector(uint light, uint cell, vec3 pos, out float attenuation attenuation = pow(clamp(1.0 - distance / lights.data[light].radius, 0.0001, 1.0), lights.data[light].attenuation); if (lights.data[light].type == LIGHT_TYPE_SPOT) { - vec3 rel = normalize(pos - light_pos); float angle = acos(dot(rel, lights.data[light].direction)); if (angle > lights.data[light].spot_angle_radians) { @@ -170,7 +168,6 @@ bool compute_light_vector(uint light, uint cell, vec3 pos, out float attenuation } float get_normal_advance(vec3 p_normal) { - vec3 normal = p_normal; vec3 unorm = abs(normal); @@ -195,7 +192,6 @@ float get_normal_advance(vec3 p_normal) { #endif void main() { - uint cell_index = gl_GlobalInvocationID.x; if (cell_index >= params.cell_count) { return; @@ -220,7 +216,6 @@ void main() { #endif for (uint i = 0; i < params.light_count; i++) { - float attenuation; vec3 light_pos; @@ -237,7 +232,6 @@ void main() { } if (lights.data[i].has_shadow) { - float distance_adv = get_normal_advance(light_dir); distance += distance_adv - mod(distance, distance_adv); //make it reach the center of the box always diff --git a/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl b/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl index 4bf5b7e7f1..060b1a3101 100644 --- a/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl +++ b/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl @@ -37,15 +37,14 @@ layout(push_constant, binding = 1, std430) uniform Params { float exposure_adjust; float pad[3]; } + params; void main() { - uint t = gl_LocalInvocationID.y * BLOCK_SIZE + gl_LocalInvocationID.x; ivec2 pos = ivec2(gl_GlobalInvocationID.xy); if (any(lessThan(pos, params.source_size))) { - #ifdef READ_TEXTURE vec3 v = texelFetch(source_texture, pos, 0).rgb; tmp_data[t] = max(v.r, max(v.g, v.b)); diff --git a/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl b/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl index 3637b1abb2..e59424e3d6 100644 --- a/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl +++ b/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl @@ -16,12 +16,12 @@ layout(push_constant, binding = 1, std430) uniform Params { float curve; uint pad; } + params; #define HALF_PI 1.5707963267948966 void main() { - // Pixel being shaded ivec2 pos = ivec2(gl_GlobalInvocationID.xy); if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl index 4eba5d41d8..86d7ba6f1b 100644 --- a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl +++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl @@ -22,7 +22,7 @@ layout(location = 3) in vec4 color_attrib; layout(location = 4) in vec2 uv_attrib; -#if defined(UV2_USED) || defined(USE_LIGHTMAP) +#if defined(UV2_USED) || defined(USE_LIGHTMAP) || defined(MODE_RENDER_MATERIAL) layout(location = 5) in vec2 uv2_attrib; #endif @@ -49,7 +49,7 @@ layout(location = 6) out vec3 binormal_interp; #endif #ifdef USE_MATERIAL_UNIFORMS -layout(set = 5, binding = 0, std140) uniform MaterialUniforms{ +layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{ /* clang-format off */ MATERIAL_UNIFORMS /* clang-format on */ @@ -75,7 +75,6 @@ layout(location = 8) out float dp_clip; #endif void main() { - instance_index = draw_call.instance_index; vec4 instance_custom = vec4(0.0); #if defined(COLOR_USED) @@ -263,6 +262,14 @@ VERTEX_SHADER_CODE } } #endif + +#ifdef MODE_RENDER_MATERIAL + if (scene_data.material_uv2_mode) { + gl_Position.xy = (uv2_attrib.xy + draw_call.bake_uv2_offset) * 2.0 - 1.0; + gl_Position.z = 0.00001; + gl_Position.w = 1.0; + } +#endif } /* clang-format off */ @@ -315,7 +322,7 @@ layout(location = 8) in float dp_clip; #endif #ifdef USE_MATERIAL_UNIFORMS -layout(set = 5, binding = 0, std140) uniform MaterialUniforms{ +layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{ /* clang-format off */ MATERIAL_UNIFORMS /* clang-format on */ @@ -685,7 +692,6 @@ float quick_hash(vec2 pos) { } float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { - vec2 pos = coord.xy; float depth = coord.z; @@ -712,7 +718,6 @@ float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, ve } float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { - vec2 pos = coord.xy; float depth = coord.z; @@ -739,7 +744,6 @@ float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { } float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex_scale) { - //find blocker float blocker_count = 0.0; float blocker_average = 0.0; @@ -753,7 +757,6 @@ float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex } for (uint i = 0; i < scene_data.directional_penumbra_shadow_samples; i++) { - vec2 suv = pssm_coord.xy + (disk_rotation * scene_data.directional_penumbra_shadow_kernel[i].xy) * tex_scale; float d = textureLod(sampler2D(shadow, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r; if (d < pssm_coord.z) { @@ -763,7 +766,6 @@ float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex } if (blocker_count > 0.0) { - //blockers found, do soft shadow blocker_average /= blocker_count; float penumbra = (pssm_coord.z - blocker_average) / blocker_average; @@ -821,7 +823,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v float size_A = 0.0; if (lights.data[idx].size > 0.0) { - float t = lights.data[idx].size / max(0.001, light_length); size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); } @@ -875,7 +876,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v bitangent *= lights.data[idx].soft_shadow_size * lights.data[idx].soft_shadow_scale; for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { - vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy; vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y; @@ -884,11 +884,9 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v vec4 uv_rect = lights.data[idx].atlas_rect; if (pos.z >= 0.0) { - pos.z += 1.0; uv_rect.y += uv_rect.w; } else { - pos.z = 1.0 - pos.z; } @@ -905,7 +903,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v } if (blocker_count > 0.0) { - //blockers found, do soft shadow blocker_average /= blocker_count; float penumbra = (z_norm - blocker_average) / blocker_average; @@ -916,7 +913,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v shadow = 0.0; for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { - vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy; vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y; @@ -924,11 +920,9 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v vec4 uv_rect = lights.data[idx].atlas_rect; if (pos.z >= 0.0) { - pos.z += 1.0; uv_rect.y += uv_rect.w; } else { - pos.z = 1.0 - pos.z; } @@ -946,12 +940,10 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v shadow = 1.0; } } else { - splane.xyz = normalize(splane.xyz); vec4 clamp_rect = lights.data[idx].atlas_rect; if (splane.z >= 0.0) { - splane.z += 1.0; clamp_rect.y += clamp_rect.w; @@ -971,7 +963,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v #ifdef LIGHT_TRANSMITTANCE_USED { - vec4 clamp_rect = lights.data[idx].atlas_rect; //redo shadowmapping, but shrink the model a bit to avoid arctifacts @@ -981,11 +972,9 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v splane = normalize(splane.xyz); if (splane.z >= 0.0) { - splane.z += 1.0; } else { - splane.z = 1.0 - splane.z; } @@ -1003,19 +992,16 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v vec3 no_shadow = vec3(1.0); if (lights.data[idx].projector_rect != vec4(0.0)) { - vec3 local_v = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz; local_v = normalize(local_v); vec4 atlas_rect = lights.data[idx].projector_rect; if (local_v.z >= 0.0) { - local_v.z += 1.0; atlas_rect.y += atlas_rect.w; } else { - local_v.z = 1.0 - local_v.z; } @@ -1030,10 +1016,8 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v local_v_ddx = normalize(local_v_ddx); if (local_v_ddx.z >= 0.0) { - local_v_ddx.z += 1.0; } else { - local_v_ddx.z = 1.0 - local_v_ddx.z; } @@ -1046,10 +1030,8 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v local_v_ddy = normalize(local_v_ddy); if (local_v_ddy.z >= 0.0) { - local_v_ddy.z += 1.0; } else { - local_v_ddy.z = 1.0 - local_v_ddy.z; } @@ -1137,7 +1119,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v float size_A = 0.0; if (lights.data[idx].size > 0.0) { - float t = lights.data[idx].size / max(0.001, light_length); size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); } @@ -1194,7 +1175,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v float uv_size = lights.data[idx].soft_shadow_size * z_norm * lights.data[idx].soft_shadow_scale; vec2 clamp_max = lights.data[idx].atlas_rect.xy + lights.data[idx].atlas_rect.zw; for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { - vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size; suv = clamp(suv, lights.data[idx].atlas_rect.xy, clamp_max); float d = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r; @@ -1205,7 +1185,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v } if (blocker_count > 0.0) { - //blockers found, do soft shadow blocker_average /= blocker_count; float penumbra = (z_norm - blocker_average) / blocker_average; @@ -1235,7 +1214,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v vec3 no_shadow = vec3(1.0); if (lights.data[idx].projector_rect != vec4(0.0)) { - splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)); splane /= splane.w; @@ -1258,7 +1236,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v #ifdef LIGHT_TRANSMITTANCE_USED { - splane = (lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * lights.data[idx].transmittance_bias, 1.0)); splane /= splane.w; splane.xy = splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy; @@ -1302,7 +1279,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v } void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughness, vec3 ambient_light, vec3 specular_light, inout vec4 ambient_accum, inout vec4 reflection_accum) { - vec3 box_extents = reflections.data[ref_index].box_extents; vec3 local_pos = (reflections.data[ref_index].local_matrix * vec4(vertex, 1.0)).xyz; @@ -1369,7 +1345,6 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes ambient_out.rgb *= ambient_out.a; ambient_accum += ambient_out; } else { - vec4 ambient_out; ambient_out.a = blend; ambient_out.rgb = reflections.data[ref_index].ambient.rgb; @@ -1386,7 +1361,6 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes //standard voxel cone trace vec4 voxel_cone_trace(texture3D probe, vec3 cell_size, vec3 pos, vec3 direction, float tan_half_angle, float max_distance, float p_bias) { - float dist = p_bias; vec4 color = vec4(0.0); @@ -1413,7 +1387,6 @@ vec4 voxel_cone_trace(texture3D probe, vec3 cell_size, vec3 pos, vec3 direction, #ifdef GI_PROBE_USE_ANISOTROPY vec4 voxel_cone_trace_anisotropic_45_degrees(texture3D probe, texture3D aniso_pos, texture3D aniso_neg, vec3 normal, vec3 cell_size, vec3 pos, vec3 direction, float tan_half_angle, float max_distance, float p_bias) { - float dist = p_bias; vec4 color = vec4(0.0); float radius = max(0.5, tan_half_angle * dist); @@ -1445,7 +1418,6 @@ vec4 voxel_cone_trace_anisotropic_45_degrees(texture3D probe, texture3D aniso_po #else vec4 voxel_cone_trace_45_degrees(texture3D probe, vec3 cell_size, vec3 pos, vec3 direction, float tan_half_angle, float max_distance, float p_bias) { - float dist = p_bias; vec4 color = vec4(0.0); float radius = max(0.5, tan_half_angle * dist); @@ -1477,7 +1449,6 @@ vec4 voxel_cone_trace_45_degrees(texture3D probe, vec3 cell_size, vec3 pos, vec3 //standard voxel cone trace vec4 voxel_cone_trace_anisotropic(texture3D probe, texture3D aniso_pos, texture3D aniso_neg, vec3 normal, vec3 cell_size, vec3 pos, vec3 direction, float tan_half_angle, float max_distance, float p_bias) { - float dist = p_bias; vec4 color = vec4(0.0); @@ -1508,7 +1479,6 @@ vec4 voxel_cone_trace_anisotropic(texture3D probe, texture3D aniso_pos, texture3 #endif void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 normal_xform, float roughness, vec3 ambient, vec3 environment, inout vec4 out_spec, inout vec4 out_diff) { - position = (gi_probes.data[index].xform * vec4(position, 1.0)).xyz; ref_vec = normalize((gi_probes.data[index].xform * vec4(ref_vec, 0.0)).xyz); normal = normalize((gi_probes.data[index].xform * vec4(normal, 0.0)).xyz); @@ -1569,7 +1539,6 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 vec3 light = vec3(0.0); for (int i = 0; i < MAX_CONE_DIRS; i++) { - vec3 dir = normalize((gi_probes.data[index].xform * vec4(normal_xform * cone_dirs[i], 0.0)).xyz); #if defined(GI_PROBE_HIGH_QUALITY) || defined(GI_PROBE_LOW_QUALITY) @@ -1601,7 +1570,6 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 light *= gi_probes.data[index].dynamic_range; if (gi_probes.data[index].ambient_occlusion > 0.001) { - float size = 1.0 + gi_probes.data[index].ambient_occlusion_size * 7.0; float taps, blend; @@ -1642,7 +1610,6 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) void main() { - #ifdef MODE_DUAL_PARABOLOID if (dp_clip > 0.0) @@ -1794,7 +1761,6 @@ FRAGMENT_SHADER_CODE //do outside for performance and avoiding arctifacts for (uint i = 0; i < decal_count; i++) { - uint decal_index = cluster_data.indices[decal_pointer + i]; if (!bool(decals.data[decal_index].mask & instances.data[instance_index].layer_mask)) { continue; //not masked @@ -1823,7 +1789,6 @@ FRAGMENT_SHADER_CODE albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix); if (decals.data[decal_index].normal_rect != vec4(0.0)) { - vec3 decal_normal = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz; decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy))); @@ -1834,7 +1799,6 @@ FRAGMENT_SHADER_CODE } if (decals.data[decal_index].orm_rect != vec4(0.0)) { - vec3 decal_orm = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz; #if defined(AO_USED) ao = mix(ao, decal_orm.r, decal_albedo.a); @@ -1868,7 +1832,6 @@ FRAGMENT_SHADER_CODE } if (scene_data.use_reflection_cubemap) { - vec3 ref_vec = reflect(-view, normal); ref_vec = scene_data.radiance_inverse_xform * ref_vec; #ifdef USE_RADIANCE_CUBEMAP_ARRAY @@ -1888,7 +1851,6 @@ FRAGMENT_SHADER_CODE #ifndef USE_LIGHTMAP //lightmap overrides everything if (scene_data.use_ambient_light) { - ambient_light = scene_data.ambient_light_color_energy.rgb; if (scene_data.use_ambient_cubemap) { @@ -1917,42 +1879,95 @@ FRAGMENT_SHADER_CODE #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) //gi probes +#ifdef USE_LIGHTMAP + //lightmap + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE)) { //has lightmap capture + uint index = instances.data[instance_index].gi_offset; + + vec3 wnormal = mat3(scene_data.camera_matrix) * normal; + const float c1 = 0.429043; + const float c2 = 0.511664; + const float c3 = 0.743125; + const float c4 = 0.886227; + const float c5 = 0.247708; + ambient_light += (c1 * lightmap_captures.data[index].sh[8].rgb * (wnormal.x * wnormal.x - wnormal.y * wnormal.y) + + c3 * lightmap_captures.data[index].sh[6].rgb * wnormal.z * wnormal.z + + c4 * lightmap_captures.data[index].sh[0].rgb - + c5 * lightmap_captures.data[index].sh[6].rgb + + 2.0 * c1 * lightmap_captures.data[index].sh[4].rgb * wnormal.x * wnormal.y + + 2.0 * c1 * lightmap_captures.data[index].sh[7].rgb * wnormal.x * wnormal.z + + 2.0 * c1 * lightmap_captures.data[index].sh[5].rgb * wnormal.y * wnormal.z + + 2.0 * c2 * lightmap_captures.data[index].sh[3].rgb * wnormal.x + + 2.0 * c2 * lightmap_captures.data[index].sh[1].rgb * wnormal.y + + 2.0 * c2 * lightmap_captures.data[index].sh[2].rgb * wnormal.z); + + } else if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { // has actual lightmap + bool uses_sh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SH_LIGHTMAP); + uint ofs = instances.data[instance_index].gi_offset & 0xFFF; + vec3 uvw; + uvw.xy = uv2 * instances.data[instance_index].lightmap_uv_scale.zw + instances.data[instance_index].lightmap_uv_scale.xy; + uvw.z = float((instances.data[instance_index].gi_offset >> 12) & 0xFF); + + if (uses_sh) { + uvw.z *= 4.0; //SH textures use 4 times more data + vec3 lm_light_l0 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 0.0), 0.0).rgb; + vec3 lm_light_l1n1 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 1.0), 0.0).rgb; + vec3 lm_light_l1_0 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb; + vec3 lm_light_l1p1 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb; + + uint idx = instances.data[instance_index].gi_offset >> 20; + vec3 n = normalize(lightmaps.data[idx].normal_xform * normal); + + ambient_light += lm_light_l0 * 0.282095f; + ambient_light += lm_light_l1n1 * 0.32573 * n.y; + ambient_light += lm_light_l1_0 * 0.32573 * n.z; + ambient_light += lm_light_l1p1 * 0.32573 * n.x; + if (metallic > 0.01) { // since the more direct bounced light is lost, we can kind of fake it with this trick + vec3 r = reflect(normalize(-vertex), normal); + specular_light += lm_light_l1n1 * 0.32573 * r.y; + specular_light += lm_light_l1_0 * 0.32573 * r.z; + specular_light += lm_light_l1p1 * 0.32573 * r.x; + } + } else { + ambient_light += textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw, 0.0).rgb; + } + } +#endif //lightmap capture #ifdef USE_VOXEL_CONE_TRACING - { // process giprobes - uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; - if (index1 != 0xFFFF) { - vec3 ref_vec = normalize(reflect(normalize(vertex), normal)); - //find arbitrary tangent and bitangent, then build a matrix - vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); - vec3 tangent = normalize(cross(v0, normal)); - vec3 bitangent = normalize(cross(tangent, normal)); - mat3 normal_mat = mat3(tangent, bitangent, normal); + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes - vec4 amb_accum = vec4(0.0); - vec4 spec_accum = vec4(0.0); - gi_probe_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); + uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; + vec3 ref_vec = normalize(reflect(normalize(vertex), normal)); + //find arbitrary tangent and bitangent, then build a matrix + vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); + vec3 tangent = normalize(cross(v0, normal)); + vec3 bitangent = normalize(cross(tangent, normal)); + mat3 normal_mat = mat3(tangent, bitangent, normal); - uint index2 = instances.data[instance_index].gi_offset >> 16; + vec4 amb_accum = vec4(0.0); + vec4 spec_accum = vec4(0.0); + gi_probe_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); - if (index2 != 0xFFFF) { - gi_probe_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); - } + uint index2 = instances.data[instance_index].gi_offset >> 16; - if (amb_accum.a > 0.0) { - amb_accum.rgb /= amb_accum.a; - } + if (index2 != 0xFFFF) { + gi_probe_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); + } - if (spec_accum.a > 0.0) { - spec_accum.rgb /= spec_accum.a; - } + if (amb_accum.a > 0.0) { + amb_accum.rgb /= amb_accum.a; + } - specular_light = spec_accum.rgb; - ambient_light = amb_accum.rgb; + if (spec_accum.a > 0.0) { + spec_accum.rgb /= spec_accum.a; } + + specular_light = spec_accum.rgb; + ambient_light = amb_accum.rgb; } #endif @@ -1965,7 +1980,6 @@ FRAGMENT_SHADER_CODE uint reflection_probe_pointer = cluster_cell.z & CLUSTER_POINTER_MASK; for (uint i = 0; i < reflection_probe_count; i++) { - uint ref_index = cluster_data.indices[reflection_probe_pointer + i]; reflection_process(ref_index, vertex, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); } @@ -1982,7 +1996,6 @@ FRAGMENT_SHADER_CODE } { - #if defined(DIFFUSE_TOON) //simplify for toon, as specular_light *= specular * metallic * albedo * 2.0; @@ -2007,7 +2020,6 @@ FRAGMENT_SHADER_CODE { //directional light for (uint i = 0; i < scene_data.directional_light_count; i++) { - if (!bool(directional_lights.data[i].mask & instances.data[instance_index].layer_mask)) { continue; //not masked } @@ -2067,7 +2079,6 @@ FRAGMENT_SHADER_CODE } #endif } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { - vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 1) @@ -2100,7 +2111,6 @@ FRAGMENT_SHADER_CODE } #endif } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { - vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 2) @@ -2134,7 +2144,6 @@ FRAGMENT_SHADER_CODE #endif } else { - vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 3) @@ -2170,7 +2179,6 @@ FRAGMENT_SHADER_CODE } if (directional_lights.data[i].blend_splits) { - vec3 shadow_color_blend = vec3(0.0); float pssm_blend; float shadow2; @@ -2280,7 +2288,6 @@ FRAGMENT_SHADER_CODE uint omni_light_pointer = cluster_cell.x & CLUSTER_POINTER_MASK; for (uint i = 0; i < omni_light_count; i++) { - uint light_index = cluster_data.indices[omni_light_pointer + i]; if (!bool(lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { @@ -2319,7 +2326,6 @@ FRAGMENT_SHADER_CODE uint spot_light_pointer = cluster_cell.y & CLUSTER_POINTER_MASK; for (uint i = 0; i < spot_light_count; i++) { - uint light_index = cluster_data.indices[spot_light_pointer + i]; if (!bool(lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { @@ -2424,7 +2430,6 @@ FRAGMENT_SHADER_CODE ao_light_affect = mix(1.0, ao, ao_light_affect); 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); - #else if (scene_data.ssao_enabled) { diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl index ce4fabf9f2..93ddcc9dbc 100644 --- a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl +++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl @@ -3,8 +3,10 @@ layout(push_constant, binding = 0, std430) uniform DrawCall { uint instance_index; - uint pad[3]; //16 bits minimum size + uint pad; //16 bits minimum size + vec2 bake_uv2_offset; //used for bake to uv2, ignored otherwise } + draw_call; /* Set 0 Scene data that never changes, ever */ @@ -27,7 +29,6 @@ layout(set = 0, binding = 1) uniform sampler material_samplers[12]; layout(set = 0, binding = 2) uniform sampler shadow_sampler; layout(set = 0, binding = 3, std140) uniform SceneData { - mat4 projection_matrix; mat4 inv_projection_matrix; @@ -77,6 +78,10 @@ layout(set = 0, binding = 3, std140) uniform SceneData { bool roughness_limiter_enabled; vec4 ao_color; + bool material_uv2_mode; + uint pad_material0; + uint pad_material1; + uint pad_material2; #if 0 vec4 ambient_light_color; @@ -113,13 +118,13 @@ layout(set = 0, binding = 3, std140) uniform SceneData { float fog_height_curve; #endif } -scene_data; -#define INSTANCE_FLAGS_FORWARD_MASK 0x7 -#define INSTANCE_FLAGS_FORWARD_OMNI_LIGHT_SHIFT 3 -#define INSTANCE_FLAGS_FORWARD_SPOT_LIGHT_SHIFT 6 -#define INSTANCE_FLAGS_FORWARD_DECAL_SHIFT 9 +scene_data; +#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 8) +#define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 9) +#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 10) +#define INSTANCE_FLAGS_USE_GIPROBE (1 << 11) #define INSTANCE_FLAGS_MULTIMESH (1 << 12) #define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13) #define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14) @@ -135,13 +140,15 @@ struct InstanceData { mat4 normal_transform; uint flags; uint instance_uniforms_ofs; //base offset in global buffer for instance variables - uint gi_offset; //GI information when using lightmapping (VCT or lightmap) + uint gi_offset; //GI information when using lightmapping (VCT or lightmap index) uint layer_mask; + vec4 lightmap_uv_scale; }; layout(set = 0, binding = 4, std430) restrict readonly buffer Instances { InstanceData data[]; } + instances; struct LightData { //this structure needs to be as packed as possible @@ -168,10 +175,10 @@ struct LightData { //this structure needs to be as packed as possible layout(set = 0, binding = 5, std430) restrict readonly buffer Lights { LightData data[]; } + lights; struct ReflectionData { - vec3 box_extents; float index; vec3 box_offset; @@ -185,6 +192,7 @@ struct ReflectionData { layout(set = 0, binding = 6, std140) uniform ReflectionProbeData { ReflectionData data[MAX_REFLECTION_DATA_STRUCTS]; } + reflections; struct DirectionalLightData { @@ -223,6 +231,7 @@ struct DirectionalLightData { layout(set = 0, binding = 7, std140) uniform DirectionalLights { DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; } + directional_lights; struct GIProbeData { @@ -244,16 +253,42 @@ struct GIProbeData { layout(set = 0, binding = 8, std140) uniform GIProbes { GIProbeData data[MAX_GI_PROBES]; } + gi_probes; layout(set = 0, binding = 9) uniform texture3D gi_probe_textures[MAX_GI_PROBE_TEXTURES]; +#define LIGHTMAP_FLAG_USE_DIRECTION 1 +#define LIGHTMAP_FLAG_USE_SPECULAR_DIRECTION 2 + +struct Lightmap { + mat3 normal_xform; +}; + +layout(set = 0, binding = 10, std140) restrict readonly buffer Lightmaps { + Lightmap data[]; +} + +lightmaps; + +layout(set = 0, binding = 11) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; + +struct LightmapCapture { + vec4 sh[9]; +}; + +layout(set = 0, binding = 12, std140) restrict readonly buffer LightmapCaptures { + LightmapCapture data[]; +} + +lightmap_captures; + #define CLUSTER_COUNTER_SHIFT 20 #define CLUSTER_POINTER_MASK ((1 << CLUSTER_COUNTER_SHIFT) - 1) #define CLUSTER_COUNTER_MASK 0xfff -layout(set = 0, binding = 10) uniform texture2D decal_atlas; -layout(set = 0, binding = 11) uniform texture2D decal_atlas_srgb; +layout(set = 0, binding = 13) uniform texture2D decal_atlas; +layout(set = 0, binding = 14) uniform texture2D decal_atlas_srgb; struct DecalData { mat4 xform; //to decal transform @@ -273,23 +308,26 @@ struct DecalData { float normal_fade; }; -layout(set = 0, binding = 12, std430) restrict readonly buffer Decals { +layout(set = 0, binding = 15, std430) restrict readonly buffer Decals { DecalData data[]; } + decals; -layout(set = 0, binding = 13) uniform utexture3D cluster_texture; +layout(set = 0, binding = 16) uniform utexture3D cluster_texture; -layout(set = 0, binding = 14, std430) restrict readonly buffer ClusterData { +layout(set = 0, binding = 17, std430) restrict readonly buffer ClusterData { uint indices[]; } + cluster_data; -layout(set = 0, binding = 15) uniform texture2D directional_shadow_atlas; +layout(set = 0, binding = 18) uniform texture2D directional_shadow_atlas; -layout(set = 0, binding = 16, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 19, std430) restrict readonly buffer GlobalVariableData { vec4 data[]; } + global_variables; // decal atlas @@ -312,7 +350,7 @@ layout(set = 2, binding = 0) uniform textureCubeArray reflection_atlas; layout(set = 2, binding = 1) uniform texture2D shadow_atlas; -/* Set 1, Render Buffers */ +/* Set 3, Render Buffers */ layout(set = 3, binding = 0) uniform texture2D depth_buffer; layout(set = 3, binding = 1) uniform texture2D color_buffer; @@ -325,6 +363,7 @@ layout(set = 3, binding = 4) uniform texture2D ao_buffer; layout(set = 4, binding = 0, std430) restrict readonly buffer Transforms { vec4 data[]; } + transforms; /* Set 5 User Material */ diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl index e3c26c9b72..39b10871ac 100644 --- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl +++ b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl @@ -24,7 +24,6 @@ layout(set = 3, binding = 1) uniform sampler2D source_roughness; #endif layout(push_constant, binding = 2, std430) uniform Params { - vec4 proj_info; ivec2 screen_size; @@ -43,6 +42,7 @@ layout(push_constant, binding = 2, std430) uniform Params { mat4 projection; } + params; vec2 view_to_screen(vec3 view_pos, out float w) { @@ -64,11 +64,10 @@ vec3 reconstructCSPosition(vec2 S, float z) { } void main() { - // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing return; } @@ -156,7 +155,6 @@ void main() { float steps_taken = 0.0; for (int i = 0; i < params.num_steps; i++) { - pos += line_advance; z += z_advance; w += w_advance; @@ -187,7 +185,6 @@ void main() { } if (found) { - float margin_blend = 1.0; vec2 margin = vec2((params.screen_size.x + params.screen_size.y) * 0.5 * 0.05); // make a uniform margin @@ -220,7 +217,6 @@ void main() { float roughness = texelFetch(source_roughness, ssC << 1, 0).r; if (roughness > 0.001) { - float cone_angle = min(roughness, 0.999) * M_PI * 0.5; float cone_len = length(final_pos - line_begin); float op_len = 2.0 * tan(cone_angle) * cone_len; // opposite side of iso triangle diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl index 1a5dd5ab55..c36143039c 100644 --- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl +++ b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl @@ -22,7 +22,6 @@ layout(r8, set = 2, binding = 1) uniform restrict writeonly image2D dest_radius; layout(r32f, set = 3, binding = 0) uniform restrict readonly image2D source_depth; layout(push_constant, binding = 2, std430) uniform Params { - vec4 proj_info; bool orthogonal; @@ -34,6 +33,7 @@ layout(push_constant, binding = 2, std430) uniform Params { bool vertical; uint steps; } + params; #define GAUSS_TABLE_SIZE 15 @@ -58,7 +58,6 @@ const float gauss_table[GAUSS_TABLE_SIZE + 1] = float[]( ); float gauss_weight(float p_val) { - float idxf; float c = modf(max(0.0, p_val * float(GAUSS_TABLE_SIZE)), idxf); int idx = int(idxf); @@ -80,7 +79,6 @@ vec3 reconstructCSPosition(vec2 S, float z) { } void do_filter(inout vec4 accum, inout float accum_radius, inout float divisor, ivec2 texcoord, ivec2 increment, vec3 p_pos, vec3 normal, float p_limit_radius) { - for (int i = 1; i < params.steps; i++) { float d = float(i * params.increment); ivec2 tc = texcoord + increment * i; @@ -104,7 +102,6 @@ void do_filter(inout vec4 accum, inout float accum_radius, inout float divisor, } if (d < radius) { - float w = gauss_weight(d / radius); accum += imageLoad(source_ssr, tc) * w; #ifndef VERTICAL_PASS @@ -116,11 +113,10 @@ void do_filter(inout vec4 accum, inout float accum_radius, inout float divisor, } void main() { - // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing return; } diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl index cec6c14c76..072f57eb40 100644 --- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl +++ b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl @@ -18,7 +18,6 @@ layout(r32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_depth layout(rgba8, set = 3, binding = 1) uniform restrict writeonly image2D dest_normal; layout(push_constant, binding = 1, std430) uniform Params { - ivec2 screen_size; float camera_z_near; float camera_z_far; @@ -27,14 +26,14 @@ layout(push_constant, binding = 1, std430) uniform Params { bool filtered; uint pad[2]; } + params; void main() { - // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing return; } //do not filter, SSR will generate arctifacts if this is done @@ -45,13 +44,11 @@ void main() { vec3 normal; if (params.filtered) { - color = vec4(0.0); depth = 0.0; normal = vec3(0.0); for (int i = 0; i < 4; i++) { - ivec2 ofs = ssC << 1; if (bool(i & 1)) { ofs.x += 1; diff --git a/servers/rendering/rasterizer_rd/shaders/sky.glsl b/servers/rendering/rasterizer_rd/shaders/sky.glsl index 536077980d..b0be03fe44 100644 --- a/servers/rendering/rasterizer_rd/shaders/sky.glsl +++ b/servers/rendering/rasterizer_rd/shaders/sky.glsl @@ -14,10 +14,10 @@ layout(push_constant, binding = 1, std430) uniform Params { vec4 position_multiplier; float time; } + params; void main() { - vec2 base_arr[4] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 1.0), vec2(1.0, 1.0), vec2(1.0, -1.0)); uv_interp = base_arr[gl_VertexIndex]; gl_Position = vec4(uv_interp, 1.0, 1.0); @@ -41,6 +41,7 @@ layout(push_constant, binding = 1, std430) uniform Params { vec4 position_multiplier; float time; //TODO consider adding vec2 screen res, and float radiance size } + params; #define SAMPLER_NEAREST_CLAMP 0 @@ -61,6 +62,7 @@ layout(set = 0, binding = 0) uniform sampler material_samplers[12]; layout(set = 0, binding = 1, std430) restrict readonly buffer GlobalVariableData { vec4 data[]; } + global_variables; #ifdef USE_MATERIAL_UNIFORMS @@ -109,6 +111,7 @@ struct DirectionalLightData { layout(set = 3, binding = 0, std140) uniform DirectionalLights { DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; } + directional_lights; /* clang-format off */ @@ -120,7 +123,6 @@ FRAGMENT_SHADER_GLOBALS layout(location = 0) out vec4 frag_color; void main() { - vec3 cube_normal; cube_normal.z = -1.0; cube_normal.x = (cube_normal.z * (-uv_interp.x - params.proj.x)) / params.proj.y; diff --git a/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl b/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl index b24f7dccc7..c693ea5abc 100644 --- a/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl +++ b/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl @@ -9,7 +9,6 @@ layout(location = 0) out vec2 uv_interp; /* clang-format on */ void main() { - vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); uv_interp = base_arr[gl_VertexIndex]; @@ -43,7 +42,6 @@ layout(set = 2, binding = 0) uniform sampler2D diffuse; layout(location = 0) out vec4 frag_color; void main() { - frag_color.rgb = texture(specular, uv_interp).rgb; frag_color.a = 0.0; #ifdef MODE_SSR diff --git a/servers/rendering/rasterizer_rd/shaders/ssao.glsl b/servers/rendering/rasterizer_rd/shaders/ssao.glsl index c9d7134610..764d7eeeac 100644 --- a/servers/rendering/rasterizer_rd/shaders/ssao.glsl +++ b/servers/rendering/rasterizer_rd/shaders/ssao.glsl @@ -78,6 +78,7 @@ layout(push_constant, binding = 1, std430) uniform Params { float proj_scale; uint pad; } + params; vec3 reconstructCSPosition(vec2 S, float z) { @@ -212,7 +213,7 @@ float sampleAO(in ivec2 ssC, in vec3 C, in vec3 n_C, in float ssDiskRadius, in f void main() { // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing return; } diff --git a/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl b/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl index e90c788e08..ca7cc7d71b 100644 --- a/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl +++ b/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl @@ -31,6 +31,7 @@ layout(push_constant, binding = 1, std430) uniform Params { ivec2 axis; /** (1, 0) or (0, 1) */ ivec2 screen_size; } + params; /** Filter radius in pixels. This will be multiplied by SCALE. */ @@ -46,10 +47,9 @@ const float gaussian[R + 1] = //float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // stddev = 3.0 void main() { - // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing return; } @@ -122,7 +122,6 @@ void main() { // We already handled the zero case above. This loop should be unrolled and the static branch optimized out, // so the IF statement has no runtime cost if (r != 0) { - ivec2 ppos = ssC + params.axis * (r * params.filter_scale); float value = texelFetch(source_ssao, clamp(ppos, ivec2(0), clamp_limit), 0).r; ivec2 rpos = clamp(ppos, ivec2(0), clamp_limit); diff --git a/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl b/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl index 8728154347..c590e406f3 100644 --- a/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl +++ b/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl @@ -16,6 +16,7 @@ layout(push_constant, binding = 1, std430) uniform Params { bool orthogonal; uint pad; } + params; #ifdef MINIFY_START @@ -26,7 +27,6 @@ layout(r32f, set = 0, binding = 0) uniform restrict readonly image2D source_imag layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D dest_image; void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); if (any(greaterThan(pos, params.source_size >> 1))) { //too large, do nothing diff --git a/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl b/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl index 41f8fde3ca..9d660c5865 100644 --- a/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl +++ b/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl @@ -93,7 +93,6 @@ const vec4 skin_kernel[kernel_size] = vec4[]( #endif //USE_11_SAMPLES layout(push_constant, binding = 1, std430) uniform Params { - ivec2 screen_size; float camera_z_far; float camera_z_near; @@ -106,6 +105,7 @@ layout(push_constant, binding = 1, std430) uniform Params { float depth_scale; uint pad[3]; } + params; layout(set = 0, binding = 0) uniform sampler2D source_image; @@ -113,7 +113,6 @@ layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly image2D dest_im layout(set = 2, binding = 0) uniform sampler2D source_depth; void do_filter(inout vec3 color_accum, inout vec3 divisor, vec2 uv, vec2 step, bool p_skin) { - // Accumulate the other samples: for (int i = 1; i < kernel_size; i++) { // Fetch color and depth for current sample: @@ -138,11 +137,10 @@ void do_filter(inout vec3 color_accum, inout vec3 divisor, vec2 uv, vec2 step, b } void main() { - // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing return; } @@ -153,7 +151,6 @@ void main() { float strength = abs(base_color.a); if (strength > 0.0) { - vec2 dir = params.vertical ? vec2(0.0, 1.0) : vec2(1.0, 0.0); // Fetch linear depth of current pixel: diff --git a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl index a142d263e2..f4754bfea7 100644 --- a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl +++ b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl @@ -9,7 +9,6 @@ layout(location = 0) out vec2 uv_interp; /* clang-format on */ void main() { - vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); uv_interp = base_arr[gl_VertexIndex]; gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); @@ -53,6 +52,7 @@ layout(push_constant, binding = 1, std430) uniform Params { bool use_fxaa; uint pad; } + params; layout(location = 0) out vec4 frag_color; @@ -260,7 +260,6 @@ vec3 apply_color_correction(vec3 color, sampler3D correction_tex) { } vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) { - const float FXAA_REDUCE_MIN = (1.0 / 128.0); const float FXAA_REDUCE_MUL = (1.0 / 8.0); const float FXAA_SPAN_MAX = 8.0; @@ -320,7 +319,6 @@ void main() { // Early Tonemap & SRGB Conversion if (params.use_glow && params.glow_mode == GLOW_MODE_MIX) { - vec3 glow = gather_glow(source_glow, uv_interp); color.rgb = mix(color.rgb, glow, params.glow_intensity); } @@ -335,7 +333,6 @@ void main() { // Glow if (params.use_glow && params.glow_mode != GLOW_MODE_MIX) { - vec3 glow = gather_glow(source_glow, uv_interp) * params.glow_intensity; // high dynamic range -> SRGB diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index a3bb39cd90..55b65d2747 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -44,6 +44,7 @@ RenderingDevice::ShaderCacheFunction RenderingDevice::cache_function = nullptr; void RenderingDevice::shader_set_compile_function(ShaderCompileFunction p_function) { compile_function = p_function; } + void RenderingDevice::shader_set_cache_function(ShaderCacheFunction p_function) { cache_function = p_function; } @@ -62,7 +63,6 @@ Vector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_stage, } RID RenderingDevice::_texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data) { - ERR_FAIL_COND_V(p_format.is_null(), RID()); ERR_FAIL_COND_V(p_view.is_null(), RID()); Vector<Vector<uint8_t>> data; @@ -87,7 +87,6 @@ RID RenderingDevice::_texture_create_shared_from_slice(const Ref<RDTextureView> } RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments) { - Vector<AttachmentFormat> attachments; attachments.resize(p_attachments.size()); @@ -100,7 +99,6 @@ RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create } RID RenderingDevice::_framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check) { - Vector<RID> textures = Variant(p_textures); return framebuffer_create(textures, p_format_check); } @@ -112,7 +110,6 @@ RID RenderingDevice::_sampler_create(const Ref<RDSamplerState> &p_state) { } RenderingDevice::VertexFormatID RenderingDevice::_vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats) { - Vector<VertexAttribute> descriptions; descriptions.resize(p_vertex_formats.size()); @@ -125,7 +122,6 @@ RenderingDevice::VertexFormatID RenderingDevice::_vertex_format_create(const Typ } RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers) { - Vector<RID> buffers = Variant(p_src_buffers); return vertex_array_create(p_vertex_count, p_vertex_format, buffers); @@ -147,7 +143,7 @@ Ref<RDShaderBytecode> RenderingDevice::_shader_compile_from_source(const Ref<RDS return bytecode; } -RID RenderingDevice::_shader_create(const Ref<RDShaderBytecode> &p_bytecode) { +RID RenderingDevice::shader_create_from_bytecode(const Ref<RDShaderBytecode> &p_bytecode) { ERR_FAIL_COND_V(p_bytecode.is_null(), RID()); Vector<ShaderStageData> stage_data; @@ -168,7 +164,6 @@ RID RenderingDevice::_shader_create(const Ref<RDShaderBytecode> &p_bytecode) { } RID RenderingDevice::_uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set) { - Vector<Uniform> uniforms; uniforms.resize(p_uniforms.size()); for (int i = 0; i < p_uniforms.size(); i++) { @@ -180,12 +175,10 @@ RID RenderingDevice::_uniform_set_create(const Array &p_uniforms, RID p_shader, } Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw) { - return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_sync_with_draw); } RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags) { - PipelineRasterizationState rasterization_state; if (p_rasterization_state.is_valid()) { rasterization_state = p_rasterization_state->base; @@ -220,7 +213,6 @@ RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p } Vector<int64_t> RenderingDevice::_draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) { - Vector<DrawListID> splits; splits.resize(p_splits); draw_list_begin_split(p_framebuffer, p_splits, splits.ptrw(), p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region); @@ -245,7 +237,6 @@ void RenderingDevice::_compute_list_set_push_constant(ComputeListID p_list, cons } void RenderingDevice::_bind_methods() { - ClassDB::bind_method(D_METHOD("texture_create", "format", "view", "data"), &RenderingDevice::_texture_create, DEFVAL(Array())); ClassDB::bind_method(D_METHOD("texture_create_shared", "view", "with_texture"), &RenderingDevice::_texture_create_shared); ClassDB::bind_method(D_METHOD("texture_create_shared_from_slice", "view", "with_texture", "layer", "mipmap", "slice_type"), &RenderingDevice::_texture_create_shared_from_slice, DEFVAL(TEXTURE_SLICE_2D)); @@ -276,7 +267,7 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("index_array_create", "index_buffer", "index_offset", "index_count"), &RenderingDevice::index_array_create); ClassDB::bind_method(D_METHOD("shader_compile_from_source", "shader_source", "allow_cache"), &RenderingDevice::_shader_compile_from_source, DEFVAL(true)); - ClassDB::bind_method(D_METHOD("shader_create", "shader_data"), &RenderingDevice::_shader_create); + ClassDB::bind_method(D_METHOD("shader_create", "shader_data"), &RenderingDevice::shader_create_from_bytecode); ClassDB::bind_method(D_METHOD("shader_get_vertex_input_attribute_mask", "shader"), &RenderingDevice::shader_get_vertex_input_attribute_mask); ClassDB::bind_method(D_METHOD("uniform_buffer_create", "size_bytes", "data"), &RenderingDevice::uniform_buffer_create, DEFVAL(Vector<uint8_t>())); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index c76fce5b5c..ee39ee11ed 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -596,6 +596,7 @@ public: } }; + RID shader_create_from_bytecode(const Ref<RDShaderBytecode> &p_bytecode); virtual RID shader_create(const Vector<ShaderStageData> &p_stages) = 0; virtual uint32_t shader_get_vertex_input_attribute_mask(RID p_shader) = 0; @@ -785,7 +786,6 @@ public: }; struct PipelineDepthStencilState { - bool enable_depth_test; bool enable_depth_write; CompareOperator depth_compare_operator; @@ -829,7 +829,6 @@ public: }; struct PipelineColorBlendState { - bool enable_logic_op; LogicOperation logic_op; struct Attachment { @@ -870,7 +869,6 @@ public: static PipelineColorBlendState create_blend(int p_attachments = 1) { PipelineColorBlendState bs; for (int i = 0; i < p_attachments; i++) { - Attachment ba; ba.enable_blend = true; ba.src_color_blend_factor = BLEND_FACTOR_SRC_ALPHA; @@ -1045,6 +1043,8 @@ public: virtual void submit() = 0; virtual void sync() = 0; + virtual uint64_t get_memory_usage() const = 0; + virtual RenderingDevice *create_local_device() = 0; static RenderingDevice *get_singleton(); @@ -1063,7 +1063,6 @@ protected: RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers); Ref<RDShaderBytecode> _shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache = true); - RID _shader_create(const Ref<RDShaderBytecode> &p_bytecode); RID _uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set); diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp index 43121e2cb5..2936843a9c 100644 --- a/servers/rendering/rendering_device_binds.cpp +++ b/servers/rendering/rendering_device_binds.cpp @@ -30,8 +30,7 @@ #include "rendering_device_binds.h" -Error RDShaderFile::parse_versions_from_text(const String &p_text, OpenIncludeFunction p_include_func, void *p_include_func_userdata) { - +Error RDShaderFile::parse_versions_from_text(const String &p_text, const String p_defines, OpenIncludeFunction p_include_func, void *p_include_func_userdata) { Vector<String> lines = p_text.split("\n"); bool reading_versions = false; @@ -56,6 +55,9 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, OpenIncludeFu { String ls = line.strip_edges(); + if (ls.begins_with("#[")) { //workaround for clang format + ls = ls.replace_first("#[", "["); + } if (ls.begins_with("[") && ls.ends_with("]")) { String section = ls.substr(1, ls.length() - 2).strip_edges(); if (section == "versions") { @@ -90,6 +92,13 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, OpenIncludeFu } } + if (stage == RD::SHADER_STAGE_MAX && line.strip_edges() != "") { + line = line.strip_edges(); + if (line.begins_with("//") || line.begins_with("/*")) { + continue; //assuming comment (single line) + } + } + if (reading_versions) { String l = line.strip_edges(); if (l != "") { @@ -110,7 +119,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, OpenIncludeFu } define = "\n" + define.substr(1, define.length() - 2).c_unescape() + "\n"; //add newline before and after jsut in case - version_texts[version] = define; + version_texts[version] = define + "\n" + p_defines; } } else { if (stage == RD::SHADER_STAGE_MAX && line.strip_edges() != "") { @@ -138,7 +147,6 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, OpenIncludeFu base_error = "#include used, but no include function provided."; } } else { - stage_code[stage] += line + "\n"; } } @@ -149,7 +157,6 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, OpenIncludeFu shader_file.instance(); if (base_error == "") { - if (stage_found[RD::SHADER_STAGE_COMPUTE] && stages_found > 1) { ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "When writing compute shaders, [compute] mustbe the only stage present."); } @@ -163,7 +170,6 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, OpenIncludeFu /* STEP 2, Compile the versions, add to shader file */ for (Map<StringName, String>::Element *E = version_texts.front(); E; E = E->next()) { - Ref<RDShaderBytecode> bytecode; bytecode.instance(); diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h index 2a5396a3e8..319c6d9fde 100644 --- a/servers/rendering/rendering_device_binds.h +++ b/servers/rendering/rendering_device_binds.h @@ -153,7 +153,6 @@ public: protected: static void _bind_methods() { - RD_BIND(Variant::INT, RDSamplerState, mag_filter); RD_BIND(Variant::INT, RDSamplerState, min_filter); RD_BIND(Variant::INT, RDSamplerState, mip_filter); @@ -322,8 +321,31 @@ public: return base_error; } + void print_errors(const String &p_file) { + if (base_error != "") { + ERR_PRINT("Error parsing shader '" + p_file + "':\n\n" + base_error); + } else { + for (Map<StringName, Ref<RDShaderBytecode>>::Element *E = versions.front(); E; E = E->next()) { + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + String error = E->get()->get_stage_compile_error(RD::ShaderStage(i)); + if (error != String()) { + static const char *stage_str[RD::SHADER_STAGE_MAX] = { + "vertex", + "fragment", + "tesselation_control", + "tesselation_evaluation", + "compute" + }; + + ERR_PRINT("Error parsing shader '" + p_file + "', version '" + String(E->key()) + "', stage '" + stage_str[i] + "':\n\n" + error); + } + } + } + } + } + typedef String (*OpenIncludeFunction)(const String &, void *userdata); - Error parse_versions_from_text(const String &p_text, OpenIncludeFunction p_include_func = nullptr, void *p_include_func_userdata = nullptr); + Error parse_versions_from_text(const String &p_text, const String p_defines = String(), OpenIncludeFunction p_include_func = nullptr, void *p_include_func_userdata = nullptr); protected: Dictionary _get_versions() const { @@ -546,7 +568,6 @@ public: RD_SETGET(bool, write_a) void set_as_mix() { - base = RD::PipelineColorBlendState::Attachment(); base.enable_blend = true; base.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA; @@ -557,7 +578,6 @@ public: protected: static void _bind_methods() { - ClassDB::bind_method(D_METHOD("set_as_mix"), &RDPipelineColorBlendStateAttachment::set_as_mix); RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, enable_blend); diff --git a/servers/rendering/rendering_server_canvas.cpp b/servers/rendering/rendering_server_canvas.cpp index 5d6dcfd2c1..0c9290a765 100644 --- a/servers/rendering/rendering_server_canvas.cpp +++ b/servers/rendering/rendering_server_canvas.cpp @@ -36,7 +36,6 @@ static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1; void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights) { - RENDER_TIMESTAMP("Cull CanvasItem Tree"); memset(z_list, 0, z_range * sizeof(RasterizerCanvas::Item *)); @@ -53,8 +52,9 @@ void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Can RasterizerCanvas::Item *list_end = nullptr; for (int i = 0; i < z_range; i++) { - if (!z_list[i]) + if (!z_list[i]) { continue; + } if (!list) { list = z_list[i]; list_end = z_last_list[i]; @@ -83,8 +83,9 @@ void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transfo r_index++; - if (child_items[i]->sort_y) + if (child_items[i]->sort_y) { _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index); + } } } } @@ -97,14 +98,13 @@ void _mark_ysort_dirty(RenderingServerCanvas::Item *ysort_owner, RID_PtrOwner<Re } void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner) { - Item *ci = p_canvas_item; - if (!ci->visible) + if (!ci->visible) { return; + } if (ci->children_order_dirty) { - ci->child_items.sort_custom<ItemIndexSort>(); ci->children_order_dirty = false; } @@ -114,17 +114,18 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo Rect2 global_rect = xform.xform(rect); global_rect.position += p_clip_rect.position; - if (ci->use_parent_material && p_material_owner) + if (ci->use_parent_material && p_material_owner) { ci->material_owner = p_material_owner; - else { + } else { p_material_owner = ci; ci->material_owner = nullptr; } Color modulate(ci->modulate.r * p_modulate.r, ci->modulate.g * p_modulate.g, ci->modulate.b * p_modulate.b, ci->modulate.a * p_modulate.a); - if (modulate.a < 0.007) + if (modulate.a < 0.007) { return; + } int child_item_count = ci->child_items.size(); Item **child_items = ci->child_items.ptrw(); @@ -142,7 +143,6 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo } if (ci->sort_y) { - if (ci->ysort_children_count == -1) { ci->ysort_children_count = 0; _collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count); @@ -158,15 +158,16 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo sorter.sort(child_items, child_item_count); } - if (ci->z_relative) + if (ci->z_relative) { p_z = CLAMP(p_z + ci->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX); - else + } else { p_z = ci->z_index; + } for (int i = 0; i < child_item_count; i++) { - - if (!child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) + if (!child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) { continue; + } if (ci->sort_y) { _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner); } else { @@ -175,7 +176,6 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo } if (ci->copy_back_buffer) { - ci->copy_back_buffer->screen_rect = xform.xform(ci->copy_back_buffer->rect).clip(p_clip_rect); } @@ -208,9 +208,9 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo } for (int i = 0; i < child_item_count; i++) { - - if (child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) + if (child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) { continue; + } if (ci->sort_y) { _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner); } else { @@ -220,17 +220,15 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo } void RenderingServerCanvas::_light_mask_canvas_items(int p_z, RasterizerCanvas::Item *p_canvas_item, RasterizerCanvas::Light *p_masked_lights) { - - if (!p_masked_lights) + if (!p_masked_lights) { return; + } RasterizerCanvas::Item *ci = p_canvas_item; while (ci) { - RasterizerCanvas::Light *light = p_masked_lights; while (light) { - if (ci->light_mask & light->item_mask && p_z >= light->z_min && p_z <= light->z_max && ci->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) { ci->light_masked = true; } @@ -243,11 +241,9 @@ void RenderingServerCanvas::_light_mask_canvas_items(int p_z, RasterizerCanvas:: } void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect) { - RENDER_TIMESTAMP(">Render Canvas"); if (p_canvas->children_order_dirty) { - p_canvas->child_items.sort(); p_canvas->children_order_dirty = false; } @@ -264,29 +260,24 @@ void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, } if (!has_mirror) { - _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights); } else { //used for parallaxlayer mirroring for (int i = 0; i < l; i++) { - const Canvas::ChildItem &ci2 = p_canvas->child_items[i]; _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights); //mirroring (useful for scrolling backgrounds) if (ci2.mirror.x != 0) { - Transform2D xform2 = p_transform * Transform2D(0, Vector2(ci2.mirror.x, 0)); _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); } if (ci2.mirror.y != 0) { - Transform2D xform2 = p_transform * Transform2D(0, Vector2(0, ci2.mirror.y)); _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); } if (ci2.mirror.y != 0 && ci2.mirror.x != 0) { - Transform2D xform2 = p_transform * Transform2D(0, ci2.mirror); _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); } @@ -297,7 +288,6 @@ void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, } RID RenderingServerCanvas::canvas_create() { - Canvas *canvas = memnew(Canvas); ERR_FAIL_COND_V(!canvas, RID()); RID rid = canvas_owner.make_rid(canvas); @@ -306,7 +296,6 @@ RID RenderingServerCanvas::canvas_create() { } void RenderingServerCanvas::canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring) { - Canvas *canvas = canvas_owner.getornull(p_canvas); ERR_FAIL_COND(!canvas); Item *canvas_item = canvas_item_owner.getornull(p_item); @@ -316,8 +305,8 @@ void RenderingServerCanvas::canvas_set_item_mirroring(RID p_canvas, RID p_item, ERR_FAIL_COND(idx == -1); canvas->child_items.write[idx].mirror = p_mirroring; } -void RenderingServerCanvas::canvas_set_modulate(RID p_canvas, const Color &p_color) { +void RenderingServerCanvas::canvas_set_modulate(RID p_canvas, const Color &p_color) { Canvas *canvas = canvas_owner.getornull(p_canvas); ERR_FAIL_COND(!canvas); canvas->modulate = p_color; @@ -328,7 +317,6 @@ void RenderingServerCanvas::canvas_set_disable_scale(bool p_disable) { } void RenderingServerCanvas::canvas_set_parent(RID p_canvas, RID p_parent, float p_scale) { - Canvas *canvas = canvas_owner.getornull(p_canvas); ERR_FAIL_COND(!canvas); @@ -337,7 +325,6 @@ void RenderingServerCanvas::canvas_set_parent(RID p_canvas, RID p_parent, float } RID RenderingServerCanvas::canvas_item_create() { - Item *canvas_item = memnew(Item); ERR_FAIL_COND_V(!canvas_item, RID()); @@ -345,18 +332,14 @@ RID RenderingServerCanvas::canvas_item_create() { } void RenderingServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); if (canvas_item->parent.is_valid()) { - if (canvas_owner.owns(canvas_item->parent)) { - Canvas *canvas = canvas_owner.getornull(canvas_item->parent); canvas->erase_item(canvas_item); } else if (canvas_item_owner.owns(canvas_item->parent)) { - Item *item_owner = canvas_item_owner.getornull(canvas_item->parent); item_owner->child_items.erase(canvas_item); @@ -370,14 +353,12 @@ void RenderingServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) { if (p_parent.is_valid()) { if (canvas_owner.owns(p_parent)) { - Canvas *canvas = canvas_owner.getornull(p_parent); Canvas::ChildItem ci; ci.item = canvas_item; canvas->child_items.push_back(ci); canvas->children_order_dirty = true; } else if (canvas_item_owner.owns(p_parent)) { - Item *item_owner = canvas_item_owner.getornull(p_parent); item_owner->child_items.push_back(canvas_item); item_owner->children_order_dirty = true; @@ -387,15 +368,14 @@ void RenderingServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) { } } else { - ERR_FAIL_MSG("Invalid parent."); } } canvas_item->parent = p_parent; } -void RenderingServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible) { +void RenderingServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -403,8 +383,8 @@ void RenderingServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible) _mark_ysort_dirty(canvas_item, canvas_item_owner); } -void RenderingServerCanvas::canvas_item_set_light_mask(RID p_item, int p_mask) { +void RenderingServerCanvas::canvas_item_set_light_mask(RID p_item, int p_mask) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -412,43 +392,42 @@ void RenderingServerCanvas::canvas_item_set_light_mask(RID p_item, int p_mask) { } void RenderingServerCanvas::canvas_item_set_transform(RID p_item, const Transform2D &p_transform) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->xform = p_transform; } -void RenderingServerCanvas::canvas_item_set_clip(RID p_item, bool p_clip) { +void RenderingServerCanvas::canvas_item_set_clip(RID p_item, bool p_clip) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->clip = p_clip; } -void RenderingServerCanvas::canvas_item_set_distance_field_mode(RID p_item, bool p_enable) { +void RenderingServerCanvas::canvas_item_set_distance_field_mode(RID p_item, bool p_enable) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->distance_field = p_enable; } -void RenderingServerCanvas::canvas_item_set_custom_rect(RID p_item, bool p_custom_rect, const Rect2 &p_rect) { +void RenderingServerCanvas::canvas_item_set_custom_rect(RID p_item, bool p_custom_rect, const Rect2 &p_rect) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->custom_rect = p_custom_rect; canvas_item->rect = p_rect; } -void RenderingServerCanvas::canvas_item_set_modulate(RID p_item, const Color &p_color) { +void RenderingServerCanvas::canvas_item_set_modulate(RID p_item, const Color &p_color) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->modulate = p_color; } -void RenderingServerCanvas::canvas_item_set_self_modulate(RID p_item, const Color &p_color) { +void RenderingServerCanvas::canvas_item_set_self_modulate(RID p_item, const Color &p_color) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -456,7 +435,6 @@ void RenderingServerCanvas::canvas_item_set_self_modulate(RID p_item, const Colo } void RenderingServerCanvas::canvas_item_set_draw_behind_parent(RID p_item, bool p_enable) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -464,7 +442,6 @@ void RenderingServerCanvas::canvas_item_set_draw_behind_parent(RID p_item, bool } void RenderingServerCanvas::canvas_item_set_update_when_visible(RID p_item, bool p_update) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -472,28 +449,24 @@ void RenderingServerCanvas::canvas_item_set_update_when_visible(RID p_item, bool } void RenderingServerCanvas::canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->texture_filter = p_filter; } void RenderingServerCanvas::canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->texture_repeat = p_repeat; } void RenderingServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandPrimitive *line = canvas_item->alloc_command<Item::CommandPrimitive>(); ERR_FAIL_COND(!line); if (p_width > 1.001) { - Vector2 t = (p_from - p_to).tangent().normalized(); line->points[0] = p_from + t * p_width; line->points[1] = p_from - t * p_width; @@ -512,7 +485,6 @@ void RenderingServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_fro } void RenderingServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) { - ERR_FAIL_COND(p_points.size() < 2); Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -604,7 +576,6 @@ void RenderingServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Po } void RenderingServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) { - ERR_FAIL_COND(p_points.size() < 2); Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -625,7 +596,6 @@ void RenderingServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<P } void RenderingServerCanvas::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -636,7 +606,6 @@ void RenderingServerCanvas::canvas_item_add_rect(RID p_item, const Rect2 &p_rect } void RenderingServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -674,7 +643,6 @@ void RenderingServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_p } void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -690,12 +658,10 @@ void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 } if (p_rect.size.x < 0) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_H; rect->rect.size.x = -rect->rect.size.x; } if (p_rect.size.y < 0) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_V; rect->rect.size.y = -rect->rect.size.y; } @@ -708,7 +674,6 @@ void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 } void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, bool p_clip_uv, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -722,22 +687,18 @@ void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, cons rect->flags = RasterizerCanvas::CANVAS_RECT_REGION; if (p_rect.size.x < 0) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_H; rect->rect.size.x = -rect->rect.size.x; } if (p_src_rect.size.x < 0) { - rect->flags ^= RasterizerCanvas::CANVAS_RECT_FLIP_H; rect->source.size.x = -rect->source.size.x; } if (p_rect.size.y < 0) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_V; rect->rect.size.y = -rect->rect.size.y; } if (p_src_rect.size.y < 0) { - rect->flags ^= RasterizerCanvas::CANVAS_RECT_FLIP_V; rect->source.size.y = -rect->source.size.y; } @@ -753,7 +714,6 @@ void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, cons } void RenderingServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, RS::NinePatchAxisMode p_x_axis_mode, RS::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -772,8 +732,8 @@ void RenderingServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 & style->axis_x = p_x_axis_mode; style->axis_y = p_y_axis_mode; } -void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { +void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { uint32_t pc = p_points.size(); ERR_FAIL_COND(pc == 0 || pc > 4); @@ -804,7 +764,6 @@ void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<P } void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); #ifdef DEBUG_ENABLED @@ -827,7 +786,6 @@ void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Poi } void RenderingServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights, RID p_texture, int p_count, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -850,7 +808,6 @@ void RenderingServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vec } void RenderingServerCanvas::canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -860,7 +817,6 @@ void RenderingServerCanvas::canvas_item_add_set_transform(RID p_item, const Tran } void RenderingServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform, const Color &p_modulate, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -872,8 +828,8 @@ void RenderingServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, m->transform = p_transform; m->modulate = p_modulate; } -void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { +void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -888,7 +844,6 @@ void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particle } void RenderingServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -900,7 +855,6 @@ void RenderingServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RI } void RenderingServerCanvas::canvas_item_add_clip_ignore(RID p_item, bool p_ignore) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -908,8 +862,8 @@ void RenderingServerCanvas::canvas_item_add_clip_ignore(RID p_item, bool p_ignor ERR_FAIL_COND(!ci); ci->ignore = p_ignore; } -void RenderingServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) { +void RenderingServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -917,8 +871,8 @@ void RenderingServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool _mark_ysort_dirty(canvas_item, canvas_item_owner); } -void RenderingServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) { +void RenderingServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) { ERR_FAIL_COND(p_z < RS::CANVAS_ITEM_Z_MIN || p_z > RS::CANVAS_ITEM_Z_MAX); Item *canvas_item = canvas_item_owner.getornull(p_item); @@ -926,8 +880,8 @@ void RenderingServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) { canvas_item->z_index = p_z; } -void RenderingServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) { +void RenderingServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -935,7 +889,6 @@ void RenderingServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item, } void RenderingServerCanvas::canvas_item_attach_skeleton(RID p_item, RID p_skeleton) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -943,7 +896,6 @@ void RenderingServerCanvas::canvas_item_attach_skeleton(RID p_item, RID p_skelet } void RenderingServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); if (bool(canvas_item->copy_back_buffer != nullptr) != p_enable) { @@ -962,14 +914,13 @@ void RenderingServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool } void RenderingServerCanvas::canvas_item_clear(RID p_item) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->clear(); } -void RenderingServerCanvas::canvas_item_set_draw_index(RID p_item, int p_index) { +void RenderingServerCanvas::canvas_item_set_draw_index(RID p_item, int p_index) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -989,7 +940,6 @@ void RenderingServerCanvas::canvas_item_set_draw_index(RID p_item, int p_index) } void RenderingServerCanvas::canvas_item_set_material(RID p_item, RID p_material) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -997,7 +947,6 @@ void RenderingServerCanvas::canvas_item_set_material(RID p_item, RID p_material) } void RenderingServerCanvas::canvas_item_set_use_parent_material(RID p_item, bool p_enable) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -1005,57 +954,54 @@ void RenderingServerCanvas::canvas_item_set_use_parent_material(RID p_item, bool } RID RenderingServerCanvas::canvas_light_create() { - RasterizerCanvas::Light *clight = memnew(RasterizerCanvas::Light); clight->light_internal = RSG::canvas_render->light_create(); return canvas_light_owner.make_rid(clight); } -void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_canvas) { +void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_canvas) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); if (clight->canvas.is_valid()) { - Canvas *canvas = canvas_owner.getornull(clight->canvas); canvas->lights.erase(clight); } - if (!canvas_owner.owns(p_canvas)) + if (!canvas_owner.owns(p_canvas)) { p_canvas = RID(); + } clight->canvas = p_canvas; if (clight->canvas.is_valid()) { - Canvas *canvas = canvas_owner.getornull(clight->canvas); canvas->lights.insert(clight); } } void RenderingServerCanvas::canvas_light_set_enabled(RID p_light, bool p_enabled) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->enabled = p_enabled; } -void RenderingServerCanvas::canvas_light_set_scale(RID p_light, float p_scale) { +void RenderingServerCanvas::canvas_light_set_scale(RID p_light, float p_scale) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->scale = p_scale; } -void RenderingServerCanvas::canvas_light_set_transform(RID p_light, const Transform2D &p_transform) { +void RenderingServerCanvas::canvas_light_set_transform(RID p_light, const Transform2D &p_transform) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->xform = p_transform; } -void RenderingServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture) { +void RenderingServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); @@ -1063,66 +1009,66 @@ void RenderingServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture) clight->version++; RSG::canvas_render->light_set_texture(clight->light_internal, p_texture); } -void RenderingServerCanvas::canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) { +void RenderingServerCanvas::canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->texture_offset = p_offset; } -void RenderingServerCanvas::canvas_light_set_color(RID p_light, const Color &p_color) { +void RenderingServerCanvas::canvas_light_set_color(RID p_light, const Color &p_color) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->color = p_color; } -void RenderingServerCanvas::canvas_light_set_height(RID p_light, float p_height) { +void RenderingServerCanvas::canvas_light_set_height(RID p_light, float p_height) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->height = p_height; } -void RenderingServerCanvas::canvas_light_set_energy(RID p_light, float p_energy) { +void RenderingServerCanvas::canvas_light_set_energy(RID p_light, float p_energy) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->energy = p_energy; } -void RenderingServerCanvas::canvas_light_set_z_range(RID p_light, int p_min_z, int p_max_z) { +void RenderingServerCanvas::canvas_light_set_z_range(RID p_light, int p_min_z, int p_max_z) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->z_min = p_min_z; clight->z_max = p_max_z; } -void RenderingServerCanvas::canvas_light_set_layer_range(RID p_light, int p_min_layer, int p_max_layer) { +void RenderingServerCanvas::canvas_light_set_layer_range(RID p_light, int p_min_layer, int p_max_layer) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->layer_max = p_max_layer; clight->layer_min = p_min_layer; } -void RenderingServerCanvas::canvas_light_set_item_cull_mask(RID p_light, int p_mask) { +void RenderingServerCanvas::canvas_light_set_item_cull_mask(RID p_light, int p_mask) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->item_mask = p_mask; } -void RenderingServerCanvas::canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask) { +void RenderingServerCanvas::canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->item_shadow_mask = p_mask; } -void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) { +void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); @@ -1130,7 +1076,6 @@ void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMo } void RenderingServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); @@ -1143,15 +1088,15 @@ void RenderingServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_ } void RenderingServerCanvas::canvas_light_set_shadow_buffer_size(RID p_light, int p_size) { - ERR_FAIL_COND(p_size < 32 || p_size > 16384); RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); int new_size = next_power_of_2(p_size); - if (new_size == clight->shadow_buffer_size) + if (new_size == clight->shadow_buffer_size) { return; + } clight->shadow_buffer_size = next_power_of_2(p_size); clight->version++; @@ -1160,14 +1105,13 @@ void RenderingServerCanvas::canvas_light_set_shadow_buffer_size(RID p_light, int } void RenderingServerCanvas::canvas_light_set_shadow_filter(RID p_light, RS::CanvasLightShadowFilter p_filter) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->shadow_filter = p_filter; } -void RenderingServerCanvas::canvas_light_set_shadow_color(RID p_light, const Color &p_color) { +void RenderingServerCanvas::canvas_light_set_shadow_color(RID p_light, const Color &p_color) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); @@ -1175,49 +1119,46 @@ void RenderingServerCanvas::canvas_light_set_shadow_color(RID p_light, const Col } void RenderingServerCanvas::canvas_light_set_shadow_smooth(RID p_light, float p_smooth) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->shadow_smooth = p_smooth; } RID RenderingServerCanvas::canvas_light_occluder_create() { - RasterizerCanvas::LightOccluderInstance *occluder = memnew(RasterizerCanvas::LightOccluderInstance); return canvas_light_occluder_owner.make_rid(occluder); } -void RenderingServerCanvas::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) { +void RenderingServerCanvas::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) { RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); if (occluder->canvas.is_valid()) { - Canvas *canvas = canvas_owner.getornull(occluder->canvas); canvas->occluders.erase(occluder); } - if (!canvas_owner.owns(p_canvas)) + if (!canvas_owner.owns(p_canvas)) { p_canvas = RID(); + } occluder->canvas = p_canvas; if (occluder->canvas.is_valid()) { - Canvas *canvas = canvas_owner.getornull(occluder->canvas); canvas->occluders.insert(occluder); } } -void RenderingServerCanvas::canvas_light_occluder_set_enabled(RID p_occluder, bool p_enabled) { +void RenderingServerCanvas::canvas_light_occluder_set_enabled(RID p_occluder, bool p_enabled) { RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); occluder->enabled = p_enabled; } -void RenderingServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder, RID p_polygon) { +void RenderingServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder, RID p_polygon) { RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); @@ -1244,15 +1185,15 @@ void RenderingServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder, RI } } } -void RenderingServerCanvas::canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform) { +void RenderingServerCanvas::canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform) { RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); occluder->xform = p_xform; } -void RenderingServerCanvas::canvas_light_occluder_set_light_mask(RID p_occluder, int p_mask) { +void RenderingServerCanvas::canvas_light_occluder_set_light_mask(RID p_occluder, int p_mask) { RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); @@ -1260,13 +1201,12 @@ void RenderingServerCanvas::canvas_light_occluder_set_light_mask(RID p_occluder, } RID RenderingServerCanvas::canvas_occluder_polygon_create() { - LightOccluderPolygon *occluder_poly = memnew(LightOccluderPolygon); occluder_poly->occluder = RSG::canvas_render->occluder_polygon_create(); return canvas_light_occluder_polygon_owner.make_rid(occluder_poly); } -void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) { +void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) { if (p_shape.size() < 3) { canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon, p_shape); return; @@ -1285,7 +1225,6 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_pol max--; } for (int i = 0; i < max; i++) { - Vector2 a = r[i]; Vector2 b = r[(i + 1) % (lc / 2)]; w[i * 2 + 0] = a; @@ -1295,8 +1234,8 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_pol canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon, lines); } -void RenderingServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon, const Vector<Vector2> &p_shape) { +void RenderingServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon, const Vector<Vector2> &p_shape) { LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_occluder_polygon); ERR_FAIL_COND(!occluder_poly); ERR_FAIL_COND(p_shape.size() & 1); @@ -1306,10 +1245,11 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occ { const Vector2 *r = p_shape.ptr(); for (int i = 0; i < lc; i++) { - if (i == 0) + if (i == 0) { occluder_poly->aabb.position = r[i]; - else + } else { occluder_poly->aabb.expand_to(r[i]); + } } } @@ -1320,7 +1260,6 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occ } void RenderingServerCanvas::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, RS::CanvasOccluderPolygonCullMode p_mode) { - LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_occluder_polygon); ERR_FAIL_COND(!occluder_poly); occluder_poly->cull_mode = p_mode; @@ -1331,14 +1270,11 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_cull_mode(RID p_occluder } bool RenderingServerCanvas::free(RID p_rid) { - if (canvas_owner.owns(p_rid)) { - Canvas *canvas = canvas_owner.getornull(p_rid); ERR_FAIL_COND_V(!canvas, false); while (canvas->viewports.size()) { - RenderingServerViewport::Viewport *vp = RSG::viewport->viewport_owner.getornull(canvas->viewports.front()->get()); ERR_FAIL_COND_V(!vp, true); @@ -1350,17 +1286,14 @@ bool RenderingServerCanvas::free(RID p_rid) { } for (int i = 0; i < canvas->child_items.size(); i++) { - canvas->child_items[i].item->parent = RID(); } for (Set<RasterizerCanvas::Light *>::Element *E = canvas->lights.front(); E; E = E->next()) { - E->get()->canvas = RID(); } for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *E = canvas->occluders.front(); E; E = E->next()) { - E->get()->canvas = RID(); } @@ -1369,18 +1302,14 @@ bool RenderingServerCanvas::free(RID p_rid) { memdelete(canvas); } else if (canvas_item_owner.owns(p_rid)) { - Item *canvas_item = canvas_item_owner.getornull(p_rid); ERR_FAIL_COND_V(!canvas_item, true); if (canvas_item->parent.is_valid()) { - if (canvas_owner.owns(canvas_item->parent)) { - Canvas *canvas = canvas_owner.getornull(canvas_item->parent); canvas->erase_item(canvas_item); } else if (canvas_item_owner.owns(canvas_item->parent)) { - Item *item_owner = canvas_item_owner.getornull(canvas_item->parent); item_owner->child_items.erase(canvas_item); @@ -1391,7 +1320,6 @@ bool RenderingServerCanvas::free(RID p_rid) { } for (int i = 0; i < canvas_item->child_items.size(); i++) { - canvas_item->child_items[i]->parent = RID(); } @@ -1406,14 +1334,14 @@ bool RenderingServerCanvas::free(RID p_rid) { memdelete(canvas_item); } else if (canvas_light_owner.owns(p_rid)) { - RasterizerCanvas::Light *canvas_light = canvas_light_owner.getornull(p_rid); ERR_FAIL_COND_V(!canvas_light, true); if (canvas_light->canvas.is_valid()) { Canvas *canvas = canvas_owner.getornull(canvas_light->canvas); - if (canvas) + if (canvas) { canvas->lights.erase(canvas_light); + } } RSG::canvas_render->free(canvas_light->light_internal); @@ -1422,12 +1350,10 @@ bool RenderingServerCanvas::free(RID p_rid) { memdelete(canvas_light); } else if (canvas_light_occluder_owner.owns(p_rid)) { - RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_rid); ERR_FAIL_COND_V(!occluder, true); if (occluder->polygon.is_valid()) { - LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(occluder->polygon); if (occluder_poly) { occluder_poly->owners.erase(occluder); @@ -1435,7 +1361,6 @@ bool RenderingServerCanvas::free(RID p_rid) { } if (occluder->canvas.is_valid() && canvas_owner.owns(occluder->canvas)) { - Canvas *canvas = canvas_owner.getornull(occluder->canvas); canvas->occluders.erase(occluder); } @@ -1444,13 +1369,11 @@ bool RenderingServerCanvas::free(RID p_rid) { memdelete(occluder); } else if (canvas_light_occluder_polygon_owner.owns(p_rid)) { - LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_rid); ERR_FAIL_COND_V(!occluder_poly, true); RSG::canvas_render->free(occluder_poly->occluder); while (occluder_poly->owners.size()) { - occluder_poly->owners.front()->get()->polygon = RID(); occluder_poly->owners.erase(occluder_poly->owners.front()); } @@ -1465,7 +1388,6 @@ bool RenderingServerCanvas::free(RID p_rid) { } RenderingServerCanvas::RenderingServerCanvas() { - z_list = (RasterizerCanvas::Item **)memalloc(z_range * sizeof(RasterizerCanvas::Item *)); z_last_list = (RasterizerCanvas::Item **)memalloc(z_range * sizeof(RasterizerCanvas::Item *)); @@ -1473,7 +1395,6 @@ RenderingServerCanvas::RenderingServerCanvas() { } RenderingServerCanvas::~RenderingServerCanvas() { - memfree(z_list); memfree(z_last_list); } diff --git a/servers/rendering/rendering_server_canvas.h b/servers/rendering/rendering_server_canvas.h index 9da11462db..59c0d1fa52 100644 --- a/servers/rendering/rendering_server_canvas.h +++ b/servers/rendering/rendering_server_canvas.h @@ -37,7 +37,6 @@ class RenderingServerCanvas { public: struct Item : public RasterizerCanvas::Item { - RID parent; // canvas it belongs to List<Item *>::Element *E; int z_index; @@ -76,26 +75,22 @@ public: }; struct ItemIndexSort { - _FORCE_INLINE_ bool operator()(const Item *p_left, const Item *p_right) const { - return p_left->index < p_right->index; } }; struct ItemPtrSort { - _FORCE_INLINE_ bool operator()(const Item *p_left, const Item *p_right) const { - - if (Math::is_equal_approx(p_left->ysort_pos.y, p_right->ysort_pos.y)) + if (Math::is_equal_approx(p_left->ysort_pos.y, p_right->ysort_pos.y)) { return p_left->ysort_pos.x < p_right->ysort_pos.x; + } return p_left->ysort_pos.y < p_right->ysort_pos.y; } }; struct LightOccluderPolygon { - bool active; Rect2 aabb; RS::CanvasOccluderPolygonCullMode cull_mode; @@ -113,10 +108,8 @@ public: RID_PtrOwner<RasterizerCanvas::LightOccluderInstance> canvas_light_occluder_owner; struct Canvas : public RenderingServerViewport::CanvasBase { - Set<RID> viewports; struct ChildItem { - Point2 mirror; Item *item; bool operator<(const ChildItem &p_item) const { @@ -136,15 +129,17 @@ public: int find_item(Item *p_item) { for (int i = 0; i < child_items.size(); i++) { - if (child_items[i].item == p_item) + if (child_items[i].item == p_item) { return i; + } } return -1; } void erase_item(Item *p_item) { int idx = find_item(p_item); - if (idx >= 0) + if (idx >= 0) { child_items.remove(idx); + } } Canvas() { diff --git a/servers/rendering/rendering_server_raster.cpp b/servers/rendering/rendering_server_raster.cpp index c6f3273339..d30160702b 100644 --- a/servers/rendering/rendering_server_raster.cpp +++ b/servers/rendering/rendering_server_raster.cpp @@ -45,7 +45,6 @@ int RenderingServerRaster::changes = 0; /* BLACK BARS */ void RenderingServerRaster::black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) { - black_margin[MARGIN_LEFT] = p_left; black_margin[MARGIN_TOP] = p_top; black_margin[MARGIN_RIGHT] = p_right; @@ -53,7 +52,6 @@ void RenderingServerRaster::black_bars_set_margins(int p_left, int p_top, int p_ } void RenderingServerRaster::black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom) { - black_image[MARGIN_LEFT] = p_left; black_image[MARGIN_TOP] = p_top; black_image[MARGIN_RIGHT] = p_right; @@ -61,30 +59,32 @@ void RenderingServerRaster::black_bars_set_images(RID p_left, RID p_top, RID p_r } void RenderingServerRaster::_draw_margins() { - RSG::canvas_render->draw_window_margins(black_margin, black_image); }; /* FREE */ void RenderingServerRaster::free(RID p_rid) { - - if (RSG::storage->free(p_rid)) + if (RSG::storage->free(p_rid)) { return; - if (RSG::canvas->free(p_rid)) + } + if (RSG::canvas->free(p_rid)) { return; - if (RSG::viewport->free(p_rid)) + } + if (RSG::viewport->free(p_rid)) { return; - if (RSG::scene->free(p_rid)) + } + if (RSG::scene->free(p_rid)) { return; - if (RSG::scene_render->free(p_rid)) + } + if (RSG::scene_render->free(p_rid)) { return; + } } /* EVENT QUEUING */ void RenderingServerRaster::request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) { - ERR_FAIL_NULL(p_where); FrameDrawnCallbacks fdc; fdc.object = p_where->get_instance_id(); @@ -95,7 +95,6 @@ void RenderingServerRaster::request_frame_drawn_callback(Object *p_where, const } void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) { - //needs to be done before changes is reset to 0, to not force the editor to redraw RS::get_singleton()->emit_signal("frame_pre_draw"); @@ -117,7 +116,6 @@ void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) { RSG::rasterizer->end_frame(p_swap_buffers); while (frame_drawn_callbacks.front()) { - Object *obj = ObjectDB::get_instance(frame_drawn_callbacks.front()->get().object); if (obj) { Callable::CallError ce; @@ -163,18 +161,19 @@ void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) { frame_profile_frame = RSG::storage->get_captured_timestamps_frame(); } + void RenderingServerRaster::sync() { } -bool RenderingServerRaster::has_changed() const { +bool RenderingServerRaster::has_changed() const { return changes > 0; } -void RenderingServerRaster::init() { +void RenderingServerRaster::init() { RSG::rasterizer->initialize(); } -void RenderingServerRaster::finish() { +void RenderingServerRaster::finish() { if (test_cube.is_valid()) { free(test_cube); } @@ -185,17 +184,14 @@ void RenderingServerRaster::finish() { /* STATUS INFORMATION */ int RenderingServerRaster::get_render_info(RenderInfo p_info) { - return RSG::storage->get_render_info(p_info); } String RenderingServerRaster::get_video_adapter_name() const { - return RSG::storage->get_video_adapter_name(); } String RenderingServerRaster::get_video_adapter_vendor() const { - return RSG::storage->get_video_adapter_vendor(); } @@ -214,16 +210,15 @@ Vector<RenderingServer::FrameProfileArea> RenderingServerRaster::get_frame_profi /* TESTING */ void RenderingServerRaster::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) { - redraw_request(); RSG::rasterizer->set_boot_image(p_image, p_color, p_scale, p_use_filter); } + void RenderingServerRaster::set_default_clear_color(const Color &p_color) { RSG::viewport->set_default_clear_color(p_color); } bool RenderingServerRaster::has_feature(Features p_feature) const { - return false; } @@ -235,12 +230,10 @@ RID RenderingServerRaster::get_test_cube() { } bool RenderingServerRaster::has_os_feature(const String &p_feature) const { - return RSG::storage->has_os_feature(p_feature); } void RenderingServerRaster::set_debug_generate_wireframes(bool p_generate) { - RSG::storage->set_debug_generate_wireframes(p_generate); } @@ -255,8 +248,8 @@ bool RenderingServerRaster::is_low_end() const { //return RSG::rasterizer->is_low_end(); return false; } -RenderingServerRaster::RenderingServerRaster() { +RenderingServerRaster::RenderingServerRaster() { RSG::canvas = memnew(RenderingServerCanvas); RSG::viewport = memnew(RenderingServerViewport); RSG::scene = memnew(RenderingServerScene); @@ -274,7 +267,6 @@ RenderingServerRaster::RenderingServerRaster() { } RenderingServerRaster::~RenderingServerRaster() { - memdelete(RSG::canvas); memdelete(RSG::viewport); memdelete(RSG::rasterizer); diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h index f7b963a015..8a3c55118d 100644 --- a/servers/rendering/rendering_server_raster.h +++ b/servers/rendering/rendering_server_raster.h @@ -40,7 +40,6 @@ #include "servers/rendering_server.h" class RenderingServerRaster : public RenderingServer { - enum { MAX_INSTANCE_CULL = 8192, @@ -61,7 +60,6 @@ class RenderingServerRaster : public RenderingServer { RID black_image[4]; struct FrameDrawnCallbacks { - ObjectID object; StringName method; Variant param; @@ -108,8 +106,12 @@ public: m_r m_name(m_type1 arg1, m_type2 arg2) { return BINDBASE->m_name(arg1, arg2); } #define BIND2RC(m_r, m_name, m_type1, m_type2) \ m_r m_name(m_type1 arg1, m_type2 arg2) const { return BINDBASE->m_name(arg1, arg2); } +#define BIND3R(m_r, m_name, m_type1, m_type2, m_type3) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) { return BINDBASE->m_name(arg1, arg2, arg3); } #define BIND3RC(m_r, m_name, m_type1, m_type2, m_type3) \ m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) const { return BINDBASE->m_name(arg1, arg2, arg3); } +#define BIND4R(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) { return BINDBASE->m_name(arg1, arg2, arg3, arg4); } #define BIND4RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \ m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4); } @@ -170,7 +172,7 @@ public: //these also go pass-through BIND0R(RID, texture_2d_placeholder_create) - BIND0R(RID, texture_2d_layered_placeholder_create) + BIND1R(RID, texture_2d_layered_placeholder_create, TextureLayeredType) BIND0R(RID, texture_3d_placeholder_create) BIND1RC(Ref<Image>, texture_2d_get, RID) @@ -404,23 +406,19 @@ public: BIND2(gi_probe_set_anisotropy_strength, RID, float) BIND1RC(float, gi_probe_get_anisotropy_strength, RID) - /* LIGHTMAP CAPTURE */ - - BIND0R(RID, lightmap_capture_create) - - BIND2(lightmap_capture_set_bounds, RID, const AABB &) - BIND1RC(AABB, lightmap_capture_get_bounds, RID) + /* LIGHTMAP */ - BIND2(lightmap_capture_set_octree, RID, const Vector<uint8_t> &) - BIND1RC(Vector<uint8_t>, lightmap_capture_get_octree, RID) + BIND0R(RID, lightmap_create) - BIND2(lightmap_capture_set_octree_cell_transform, RID, const Transform &) - BIND1RC(Transform, lightmap_capture_get_octree_cell_transform, RID) - BIND2(lightmap_capture_set_octree_cell_subdiv, RID, int) - BIND1RC(int, lightmap_capture_get_octree_cell_subdiv, RID) - - BIND2(lightmap_capture_set_energy, RID, float) - BIND1RC(float, lightmap_capture_get_energy, RID) + BIND3(lightmap_set_textures, RID, RID, bool) + BIND2(lightmap_set_probe_bounds, RID, const AABB &) + BIND2(lightmap_set_probe_interior, RID, bool) + BIND5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &) + BIND1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID) + BIND1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID) + BIND1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID) + BIND1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID) + BIND1(lightmap_set_probe_capture_update_speed, float) /* PARTICLES */ @@ -532,6 +530,7 @@ public: BIND2(sky_set_radiance_size, RID, int) BIND2(sky_set_mode, RID, SkyMode) BIND2(sky_set_material, RID, RID) + BIND4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &) BIND0R(RID, environment_create) @@ -565,6 +564,8 @@ public: BIND7(environment_set_fog_depth, RID, bool, float, float, float, bool, float) BIND5(environment_set_fog_height, RID, bool, float, float, float) + BIND3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) + BIND2(screen_space_roughness_limiter_set_active, bool, float) BIND1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality) BIND2(sub_surface_scattering_set_scale, float, float) @@ -605,7 +606,6 @@ public: BIND3(instance_set_blend_shape_weight, RID, int, float) BIND3(instance_set_surface_material, RID, int, RID) BIND2(instance_set_visible, RID, bool) - BIND3(instance_set_use_lightmap, RID, RID, RID) BIND2(instance_set_custom_aabb, RID, AABB) @@ -625,12 +625,15 @@ public: BIND5(instance_geometry_set_draw_range, RID, float, float, float, float) BIND2(instance_geometry_set_as_instance_lod, RID, RID) + BIND4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int) BIND3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &) BIND2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &) BIND2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &) BIND2C(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *) + BIND3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &) + #undef BINDBASE //from now on, calls forwarded to this singleton #define BINDBASE RSG::canvas diff --git a/servers/rendering/rendering_server_scene.cpp b/servers/rendering/rendering_server_scene.cpp index 4f338ee2a5..7b8504036e 100644 --- a/servers/rendering/rendering_server_scene.cpp +++ b/servers/rendering/rendering_server_scene.cpp @@ -39,13 +39,11 @@ /* CAMERA API */ RID RenderingServerScene::camera_create() { - Camera *camera = memnew(Camera); return camera_owner.make_rid(camera); } void RenderingServerScene::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) { - Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->type = Camera::PERSPECTIVE; @@ -55,7 +53,6 @@ void RenderingServerScene::camera_set_perspective(RID p_camera, float p_fovy_deg } void RenderingServerScene::camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) { - Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->type = Camera::ORTHOGONAL; @@ -75,14 +72,12 @@ void RenderingServerScene::camera_set_frustum(RID p_camera, float p_size, Vector } void RenderingServerScene::camera_set_transform(RID p_camera, const Transform &p_transform) { - Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->transform = p_transform.orthonormalized(); } void RenderingServerScene::camera_set_cull_mask(RID p_camera, uint32_t p_layers) { - Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); @@ -90,21 +85,18 @@ void RenderingServerScene::camera_set_cull_mask(RID p_camera, uint32_t p_layers) } void RenderingServerScene::camera_set_environment(RID p_camera, RID p_env) { - Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->env = p_env; } void RenderingServerScene::camera_set_camera_effects(RID p_camera, RID p_fx) { - Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->effects = p_fx; } void RenderingServerScene::camera_set_use_vertical_aspect(RID p_camera, bool p_enable) { - Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->vaspect = p_enable; @@ -113,7 +105,6 @@ void RenderingServerScene::camera_set_use_vertical_aspect(RID p_camera, bool p_e /* SCENARIO API */ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int) { - //RenderingServerScene *self = (RenderingServerScene*)p_self; Instance *A = p_A; Instance *B = p_B; @@ -124,7 +115,6 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan } if (B->base_type == RS::INSTANCE_LIGHT && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -135,14 +125,12 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan List<InstanceLightData::PairInfo>::Element *E = light->geometries.push_back(pinfo); if (geom->can_cast_shadows) { - light->shadow_dirty = true; } geom->lighting_dirty = true; return E; //this element should make freeing faster } else if (B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -156,7 +144,6 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan return E; //this element should make freeing faster } else if (B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -169,21 +156,22 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan geom->decal_dirty = true; return E; //this element should make freeing faster - } else if (B->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - - InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(B->base_data); + } else if (B->base_type == RS::INSTANCE_LIGHTMAP && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); - InstanceLightmapCaptureData::PairInfo pinfo; - pinfo.geometry = A; - pinfo.L = geom->lightmap_captures.push_back(B); - - List<InstanceLightmapCaptureData::PairInfo>::Element *E = lightmap_capture->geometries.push_back(pinfo); - ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture + if (A->dynamic_gi) { + InstanceLightmapData::PairInfo pinfo; + pinfo.geometry = A; + pinfo.L = geom->lightmap_captures.push_back(B); + List<InstanceLightmapData::PairInfo>::Element *E = lightmap_data->geometries.push_back(pinfo); + ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture + return E; //this element should make freeing faster + } else { + return nullptr; + } - return E; //this element should make freeing faster } else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -203,15 +191,14 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan return E; //this element should make freeing faster } else if (B->base_type == RS::INSTANCE_GI_PROBE && A->base_type == RS::INSTANCE_LIGHT) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); return gi_probe->lights.insert(A); } return nullptr; } -void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int, void *udata) { +void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int, void *udata) { //RenderingServerScene *self = (RenderingServerScene*)p_self; Instance *A = p_A; Instance *B = p_B; @@ -222,7 +209,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta } if (B->base_type == RS::INSTANCE_LIGHT && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -237,7 +223,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta geom->lighting_dirty = true; } else if (B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -248,7 +233,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta geom->reflection_dirty = true; } else if (B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -258,19 +242,19 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta decal->geometries.erase(E); geom->decal_dirty = true; - } else if (B->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + } else if (B->base_type == RS::INSTANCE_LIGHTMAP && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + if (udata) { //only for dynamic geometries + InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(B->base_data); + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); - InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(B->base_data); - InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); + List<InstanceLightmapData::PairInfo>::Element *E = reinterpret_cast<List<InstanceLightmapData::PairInfo>::Element *>(udata); - List<InstanceLightmapCaptureData::PairInfo>::Element *E = reinterpret_cast<List<InstanceLightmapCaptureData::PairInfo>::Element *>(udata); - - geom->lightmap_captures.erase(E->get().L); - lightmap_capture->geometries.erase(E); - ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture + geom->lightmap_captures.erase(E->get().L); + lightmap_data->geometries.erase(E); + ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture + } } else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -286,7 +270,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta geom->gi_probes_dirty = true; } else if (B->base_type == RS::INSTANCE_GI_PROBE && A->base_type == RS::INSTANCE_LIGHT) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); Set<Instance *>::Element *E = reinterpret_cast<Set<Instance *>::Element *>(udata); @@ -295,7 +278,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta } RID RenderingServerScene::scenario_create() { - Scenario *scenario = memnew(Scenario); ERR_FAIL_COND_V(!scenario, RID()); RID scenario_rid = scenario_owner.make_rid(scenario); @@ -314,35 +296,30 @@ RID RenderingServerScene::scenario_create() { } void RenderingServerScene::scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) { - Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); scenario->debug = p_debug_mode; } void RenderingServerScene::scenario_set_environment(RID p_scenario, RID p_environment) { - Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); scenario->environment = p_environment; } void RenderingServerScene::scenario_set_camera_effects(RID p_scenario, RID p_camera_effects) { - Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); scenario->camera_effects = p_camera_effects; } void RenderingServerScene::scenario_set_fallback_environment(RID p_scenario, RID p_environment) { - Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); scenario->fallback_environment = p_environment; } void RenderingServerScene::scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) { - Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); RSG::scene_render->reflection_atlas_set_size(scenario->reflection_atlas, p_reflection_size, p_reflection_count); @@ -351,20 +328,21 @@ void RenderingServerScene::scenario_set_reflection_atlas_size(RID p_scenario, in /* INSTANCING API */ void RenderingServerScene::_instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies) { - - if (p_update_aabb) + if (p_update_aabb) { p_instance->update_aabb = true; - if (p_update_dependencies) + } + if (p_update_dependencies) { p_instance->update_dependencies = true; + } - if (p_instance->update_item.in_list()) + if (p_instance->update_item.in_list()) { return; + } _instance_update_list.add(&p_instance->update_item); } RID RenderingServerScene::instance_create() { - Instance *instance = memnew(Instance); ERR_FAIL_COND_V(!instance, RID()); @@ -375,7 +353,6 @@ RID RenderingServerScene::instance_create() { } void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { - Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -391,7 +368,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { switch (instance->base_type) { case RS::INSTANCE_LIGHT: { - InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data); #ifdef DEBUG_ENABLED if (light->geometries.size()) { @@ -405,7 +381,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { RSG::scene_render->free(light->instance); } break; case RS::INSTANCE_REFLECTION_PROBE: { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data); RSG::scene_render->free(reflection_probe->instance); if (reflection_probe->update_list.in_list()) { @@ -413,21 +388,18 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { } } break; case RS::INSTANCE_DECAL: { - InstanceDecalData *decal = static_cast<InstanceDecalData *>(instance->base_data); RSG::scene_render->free(decal->instance); } break; - case RS::INSTANCE_LIGHTMAP_CAPTURE: { - - InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(instance->base_data); + case RS::INSTANCE_LIGHTMAP: { + InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(instance->base_data); //erase dependencies, since no longer a lightmap - while (lightmap_capture->users.front()) { - instance_set_use_lightmap(lightmap_capture->users.front()->get()->self, RID(), RID()); + while (lightmap_data->users.front()) { + instance_geometry_set_lightmap(lightmap_data->users.front()->get()->self, RID(), Rect2(), 0); } } break; case RS::INSTANCE_GI_PROBE: { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data); #ifdef DEBUG_ENABLED if (gi_probe->geometries.size()) { @@ -443,14 +415,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { gi_probe_update_list.remove(&gi_probe->update_element); } - if (instance->lightmap_capture) { - Instance *capture = (Instance *)instance->lightmap_capture; - InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(capture->base_data); - lightmap_capture->users.erase(instance); - instance->lightmap_capture = nullptr; - instance->lightmap = RID(); - } - RSG::scene_render->free(gi_probe->probe_instance); } break; @@ -471,13 +435,11 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { instance->base = RID(); if (p_base.is_valid()) { - instance->base_type = RSG::storage->get_base_type(p_base); ERR_FAIL_COND(instance->base_type == RS::INSTANCE_NONE); switch (instance->base_type) { case RS::INSTANCE_LIGHT: { - InstanceLightData *light = memnew(InstanceLightData); if (scenario && RSG::storage->light_get_type(p_base) == RS::LIGHT_DIRECTIONAL) { @@ -492,7 +454,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { case RS::INSTANCE_MULTIMESH: case RS::INSTANCE_IMMEDIATE: case RS::INSTANCE_PARTICLES: { - InstanceGeometryData *geom = memnew(InstanceGeometryData); instance->base_data = geom; if (instance->base_type == RS::INSTANCE_MESH) { @@ -500,7 +461,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { } } break; case RS::INSTANCE_REFLECTION_PROBE: { - InstanceReflectionProbeData *reflection_probe = memnew(InstanceReflectionProbeData); reflection_probe->owner = instance; instance->base_data = reflection_probe; @@ -508,21 +468,18 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { reflection_probe->instance = RSG::scene_render->reflection_probe_instance_create(p_base); } break; case RS::INSTANCE_DECAL: { - InstanceDecalData *decal = memnew(InstanceDecalData); decal->owner = instance; instance->base_data = decal; decal->instance = RSG::scene_render->decal_instance_create(p_base); } break; - case RS::INSTANCE_LIGHTMAP_CAPTURE: { - - InstanceLightmapCaptureData *lightmap_capture = memnew(InstanceLightmapCaptureData); - instance->base_data = lightmap_capture; - //lightmap_capture->instance = RSG::scene_render->lightmap_capture_instance_create(p_base); + case RS::INSTANCE_LIGHTMAP: { + InstanceLightmapData *lightmap_data = memnew(InstanceLightmapData); + instance->base_data = lightmap_data; + //lightmap_data->instance = RSG::scene_render->lightmap_data_instance_create(p_base); } break; case RS::INSTANCE_GI_PROBE: { - InstanceGIProbeData *gi_probe = memnew(InstanceGIProbeData); instance->base_data = gi_probe; gi_probe->owner = instance; @@ -546,13 +503,12 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { _instance_queue_update(instance, true, true); } -void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) { +void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); if (instance->scenario) { - instance->scenario->instances.remove(&instance->scenario_item); if (instance->octree_id) { @@ -561,9 +517,7 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) } switch (instance->base_type) { - case RS::INSTANCE_LIGHT: { - InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data); #ifdef DEBUG_ENABLED if (light->geometries.size()) { @@ -581,7 +535,6 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) } break; case RS::INSTANCE_GI_PROBE: { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data); #ifdef DEBUG_ENABLED @@ -607,7 +560,6 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) } if (p_scenario.is_valid()) { - Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); @@ -616,9 +568,7 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) scenario->instances.add(&instance->scenario_item); switch (instance->base_type) { - case RS::INSTANCE_LIGHT: { - InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data); if (RSG::storage->light_get_type(instance->base) == RS::LIGHT_DIRECTIONAL) { @@ -626,7 +576,6 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) } } break; case RS::INSTANCE_GI_PROBE: { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data); if (!gi_probe->update_element.in_list()) { gi_probe_update_list.add(&gi_probe->update_element); @@ -639,20 +588,21 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) _instance_queue_update(instance, true, true); } } -void RenderingServerScene::instance_set_layer_mask(RID p_instance, uint32_t p_mask) { +void RenderingServerScene::instance_set_layer_mask(RID p_instance, uint32_t p_mask) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); instance->layer_mask = p_mask; } -void RenderingServerScene::instance_set_transform(RID p_instance, const Transform &p_transform) { +void RenderingServerScene::instance_set_transform(RID p_instance, const Transform &p_transform) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); - if (instance->transform == p_transform) + if (instance->transform == p_transform) { return; //must be checked to avoid worst evil + } #ifdef DEBUG_ENABLED @@ -670,15 +620,15 @@ void RenderingServerScene::instance_set_transform(RID p_instance, const Transfor instance->transform = p_transform; _instance_queue_update(instance, true); } -void RenderingServerScene::instance_attach_object_instance_id(RID p_instance, ObjectID p_id) { +void RenderingServerScene::instance_attach_object_instance_id(RID p_instance, ObjectID p_id) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); instance->object_id = p_id; } -void RenderingServerScene::instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) { +void RenderingServerScene::instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -691,7 +641,6 @@ void RenderingServerScene::instance_set_blend_shape_weight(RID p_instance, int p } void RenderingServerScene::instance_set_surface_material(RID p_instance, int p_surface, RID p_material) { - Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -708,12 +657,12 @@ void RenderingServerScene::instance_set_surface_material(RID p_instance, int p_s } void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible) { - Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); - if (instance->visible == p_visible) + if (instance->visible == p_visible) { return; + } instance->visible = p_visible; @@ -736,9 +685,9 @@ void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible) } } break; - case RS::INSTANCE_LIGHTMAP_CAPTURE: { + case RS::INSTANCE_LIGHTMAP: { if (instance->octree_id && instance->scenario) { - instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_LIGHTMAP_CAPTURE, p_visible ? RS::INSTANCE_GEOMETRY_MASK : 0); + instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_LIGHTMAP, p_visible ? RS::INSTANCE_GEOMETRY_MASK : 0); } } break; @@ -752,49 +701,24 @@ void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible) } } } + inline bool is_geometry_instance(RenderingServer::InstanceType p_type) { return p_type == RS::INSTANCE_MESH || p_type == RS::INSTANCE_MULTIMESH || p_type == RS::INSTANCE_PARTICLES || p_type == RS::INSTANCE_IMMEDIATE; } -void RenderingServerScene::instance_set_use_lightmap(RID p_instance, RID p_lightmap_instance, RID p_lightmap) { - - Instance *instance = instance_owner.getornull(p_instance); - ERR_FAIL_COND(!instance); - - if (instance->lightmap_capture) { - InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(((Instance *)instance->lightmap_capture)->base_data); - lightmap_capture->users.erase(instance); - instance->lightmap = RID(); - instance->lightmap_capture = nullptr; - } - - if (p_lightmap_instance.is_valid()) { - Instance *lightmap_instance = instance_owner.getornull(p_lightmap_instance); - ERR_FAIL_COND(!lightmap_instance); - ERR_FAIL_COND(lightmap_instance->base_type != RS::INSTANCE_LIGHTMAP_CAPTURE); - instance->lightmap_capture = lightmap_instance; - - InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(((Instance *)instance->lightmap_capture)->base_data); - lightmap_capture->users.insert(instance); - instance->lightmap = p_lightmap; - } -} - void RenderingServerScene::instance_set_custom_aabb(RID p_instance, AABB p_aabb) { - Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); ERR_FAIL_COND(!is_geometry_instance(instance->base_type)); if (p_aabb != AABB()) { - // Set custom AABB - if (instance->custom_aabb == nullptr) + if (instance->custom_aabb == nullptr) { instance->custom_aabb = memnew(AABB); + } *instance->custom_aabb = p_aabb; } else { - // Clear custom AABB if (instance->custom_aabb != nullptr) { memdelete(instance->custom_aabb); @@ -802,17 +726,18 @@ void RenderingServerScene::instance_set_custom_aabb(RID p_instance, AABB p_aabb) } } - if (instance->scenario) + if (instance->scenario) { _instance_queue_update(instance, true, false); + } } void RenderingServerScene::instance_attach_skeleton(RID p_instance, RID p_skeleton) { - Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); - if (instance->skeleton == p_skeleton) + if (instance->skeleton == p_skeleton) { return; + } instance->skeleton = p_skeleton; @@ -835,7 +760,6 @@ void RenderingServerScene::instance_set_extra_visibility_margin(RID p_instance, } Vector<ObjectID> RenderingServerScene::instances_cull_aabb(const AABB &p_aabb, RID p_scenario) const { - Vector<ObjectID> instances; Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND_V(!scenario, instances); @@ -847,19 +771,19 @@ Vector<ObjectID> RenderingServerScene::instances_cull_aabb(const AABB &p_aabb, R culled = scenario->octree.cull_aabb(p_aabb, cull, 1024); for (int i = 0; i < culled; i++) { - Instance *instance = cull[i]; ERR_CONTINUE(!instance); - if (instance->object_id.is_null()) + if (instance->object_id.is_null()) { continue; + } instances.push_back(instance->object_id); } return instances; } -Vector<ObjectID> RenderingServerScene::instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const { +Vector<ObjectID> RenderingServerScene::instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const { Vector<ObjectID> instances; Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND_V(!scenario, instances); @@ -872,16 +796,17 @@ Vector<ObjectID> RenderingServerScene::instances_cull_ray(const Vector3 &p_from, for (int i = 0; i < culled; i++) { Instance *instance = cull[i]; ERR_CONTINUE(!instance); - if (instance->object_id.is_null()) + if (instance->object_id.is_null()) { continue; + } instances.push_back(instance->object_id); } return instances; } -Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario) const { +Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario) const { Vector<ObjectID> instances; Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND_V(!scenario, instances); @@ -893,11 +818,11 @@ Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane> culled = scenario->octree.cull_convex(p_convex, cull, 1024); for (int i = 0; i < culled; i++) { - Instance *instance = cull[i]; ERR_CONTINUE(!instance); - if (instance->object_id.is_null()) + if (instance->object_id.is_null()) { continue; + } instances.push_back(instance->object_id); } @@ -906,21 +831,17 @@ Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane> } void RenderingServerScene::instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled) { - Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); //ERR_FAIL_COND(((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK)); switch (p_flags) { - case RS::INSTANCE_FLAG_USE_BAKED_LIGHT: { - instance->baked_light = p_enabled; } break; case RS::INSTANCE_FLAG_USE_DYNAMIC_GI: { - if (p_enabled == instance->dynamic_gi) { //bye, redundant return; @@ -938,7 +859,6 @@ void RenderingServerScene::instance_geometry_set_flag(RID p_instance, RS::Instan } break; case RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE: { - instance->redraw_if_visible = p_enabled; } break; @@ -946,16 +866,16 @@ void RenderingServerScene::instance_geometry_set_flag(RID p_instance, RS::Instan } } } -void RenderingServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) { +void RenderingServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); instance->cast_shadows = p_shadow_casting_setting; _instance_queue_update(instance, false, true); } -void RenderingServerScene::instance_geometry_set_material_override(RID p_instance, RID p_material) { +void RenderingServerScene::instance_geometry_set_material_override(RID p_instance, RID p_material) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -965,11 +885,33 @@ void RenderingServerScene::instance_geometry_set_material_override(RID p_instanc void RenderingServerScene::instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) { } + void RenderingServerScene::instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) { } -void RenderingServerScene::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) { +void RenderingServerScene::instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) { + Instance *instance = instance_owner.getornull(p_instance); + ERR_FAIL_COND(!instance); + + if (instance->lightmap) { + InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(((Instance *)instance->lightmap)->base_data); + lightmap_data->users.erase(instance); + instance->lightmap = nullptr; + } + + Instance *lightmap_instance = instance_owner.getornull(p_lightmap); + + instance->lightmap = lightmap_instance; + instance->lightmap_uv_scale = p_lightmap_uv_scale; + instance->lightmap_slice_index = p_slice_index; + + if (lightmap_instance) { + InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(lightmap_instance->base_data); + lightmap_data->users.insert(instance); + } +} +void RenderingServerScene::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -991,7 +933,6 @@ void RenderingServerScene::instance_geometry_set_shader_parameter(RID p_instance } Variant RenderingServerScene::instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const { - const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!instance, Variant()); @@ -1002,7 +943,6 @@ Variant RenderingServerScene::instance_geometry_get_shader_parameter(RID p_insta } Variant RenderingServerScene::instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const { - const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!instance, Variant()); @@ -1030,11 +970,9 @@ void RenderingServerScene::instance_geometry_get_shader_parameter_list(RID p_ins } void RenderingServerScene::_update_instance(Instance *p_instance) { - p_instance->version++; if (p_instance->base_type == RS::INSTANCE_LIGHT) { - InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data); RSG::scene_render->light_instance_set_transform(light->instance, p_instance->transform); @@ -1042,7 +980,6 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { } if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data); RSG::scene_render->reflection_probe_instance_set_transform(reflection_probe->instance, p_instance->transform); @@ -1050,21 +987,18 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { } if (p_instance->base_type == RS::INSTANCE_DECAL) { - InstanceDecalData *decal = static_cast<InstanceDecalData *>(p_instance->base_data); RSG::scene_render->decal_instance_set_transform(decal->instance, p_instance->transform); } if (p_instance->base_type == RS::INSTANCE_GI_PROBE) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(p_instance->base_data); RSG::scene_render->gi_probe_instance_set_transform_to_data(gi_probe->probe_instance, p_instance->transform); } if (p_instance->base_type == RS::INSTANCE_PARTICLES) { - RSG::storage->particles_set_emission_transform(p_instance->base, p_instance->transform); } @@ -1073,7 +1007,6 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { } if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { - InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); //make sure lights are updated if it casts shadow @@ -1084,16 +1017,28 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { } } - if (!p_instance->lightmap_capture && geom->lightmap_captures.size()) { + if (!p_instance->lightmap && geom->lightmap_captures.size()) { //affected by lightmap captures, must update capture info! _update_instance_lightmap_captures(p_instance); } else { - if (!p_instance->lightmap_capture_data.empty()) { - p_instance->lightmap_capture_data.resize(0); //not in use, clear capture data + if (!p_instance->lightmap_sh.empty()) { + p_instance->lightmap_sh.clear(); //don't need SH + p_instance->lightmap_target_sh.clear(); //don't need SH } } } + if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) { + //if this moved, update the captured objects + InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(p_instance->base_data); + //erase dependencies, since no longer a lightmap + + for (List<InstanceLightmapData::PairInfo>::Element *E = lightmap_data->geometries.front(); E; E = E->next()) { + Instance *geom = E->get().geometry; + _instance_queue_update(geom, true, false); + } + } + p_instance->mirror = p_instance->transform.basis.determinant() < 0.0; AABB new_aabb; @@ -1103,18 +1048,15 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { p_instance->transformed_aabb = new_aabb; if (!p_instance->scenario) { - return; } if (p_instance->octree_id == 0) { - uint32_t base_type = 1 << p_instance->base_type; uint32_t pairable_mask = 0; bool pairable = false; - if (p_instance->base_type == RS::INSTANCE_LIGHT || p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE || p_instance->base_type == RS::INSTANCE_DECAL || p_instance->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE) { - + if (p_instance->base_type == RS::INSTANCE_LIGHT || p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE || p_instance->base_type == RS::INSTANCE_DECAL || p_instance->base_type == RS::INSTANCE_LIGHTMAP) { pairable_mask = p_instance->visible ? RS::INSTANCE_GEOMETRY_MASK : 0; pairable = true; } @@ -1129,7 +1071,6 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { p_instance->octree_id = p_instance->scenario->octree.create(p_instance, new_aabb, 0, pairable, base_type, pairable_mask); } else { - /* if (new_aabb==p_instance->data.transformed_aabb) return; @@ -1140,72 +1081,65 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { } void RenderingServerScene::_update_instance_aabb(Instance *p_instance) { - AABB new_aabb; ERR_FAIL_COND(p_instance->base_type != RS::INSTANCE_NONE && !p_instance->base.is_valid()); switch (p_instance->base_type) { case RenderingServer::INSTANCE_NONE: { - // do nothing } break; case RenderingServer::INSTANCE_MESH: { - - if (p_instance->custom_aabb) + if (p_instance->custom_aabb) { new_aabb = *p_instance->custom_aabb; - else + } else { new_aabb = RSG::storage->mesh_get_aabb(p_instance->base, p_instance->skeleton); + } } break; case RenderingServer::INSTANCE_MULTIMESH: { - - if (p_instance->custom_aabb) + if (p_instance->custom_aabb) { new_aabb = *p_instance->custom_aabb; - else + } else { new_aabb = RSG::storage->multimesh_get_aabb(p_instance->base); + } } break; case RenderingServer::INSTANCE_IMMEDIATE: { - - if (p_instance->custom_aabb) + if (p_instance->custom_aabb) { new_aabb = *p_instance->custom_aabb; - else + } else { new_aabb = RSG::storage->immediate_get_aabb(p_instance->base); + } } break; case RenderingServer::INSTANCE_PARTICLES: { - - if (p_instance->custom_aabb) + if (p_instance->custom_aabb) { new_aabb = *p_instance->custom_aabb; - else + } else { new_aabb = RSG::storage->particles_get_aabb(p_instance->base); + } } break; case RenderingServer::INSTANCE_LIGHT: { - new_aabb = RSG::storage->light_get_aabb(p_instance->base); } break; case RenderingServer::INSTANCE_REFLECTION_PROBE: { - new_aabb = RSG::storage->reflection_probe_get_aabb(p_instance->base); } break; case RenderingServer::INSTANCE_DECAL: { - new_aabb = RSG::storage->decal_get_aabb(p_instance->base); } break; case RenderingServer::INSTANCE_GI_PROBE: { - new_aabb = RSG::storage->gi_probe_get_bounds(p_instance->base); } break; - case RenderingServer::INSTANCE_LIGHTMAP_CAPTURE: { - - new_aabb = RSG::storage->lightmap_capture_get_bounds(p_instance->base); + case RenderingServer::INSTANCE_LIGHTMAP: { + new_aabb = RSG::storage->lightmap_get_aabb(p_instance->base); } break; default: { @@ -1213,247 +1147,92 @@ void RenderingServerScene::_update_instance_aabb(Instance *p_instance) { } // <Zylann> This is why I didn't re-use Instance::aabb to implement custom AABBs - if (p_instance->extra_margin) + if (p_instance->extra_margin) { new_aabb.grow_by(p_instance->extra_margin); + } p_instance->aabb = new_aabb; } -_FORCE_INLINE_ static void _light_capture_sample_octree(const RasterizerStorage::LightmapCaptureOctree *p_octree, int p_cell_subdiv, const Vector3 &p_pos, const Vector3 &p_dir, float p_level, Vector3 &r_color, float &r_alpha) { - - static const Vector3 aniso_normal[6] = { - Vector3(-1, 0, 0), - Vector3(1, 0, 0), - Vector3(0, -1, 0), - Vector3(0, 1, 0), - Vector3(0, 0, -1), - Vector3(0, 0, 1) - }; - - int size = 1 << (p_cell_subdiv - 1); - - int clamp_v = size - 1; - //first of all, clamp - Vector3 pos; - pos.x = CLAMP(p_pos.x, 0, clamp_v); - pos.y = CLAMP(p_pos.y, 0, clamp_v); - pos.z = CLAMP(p_pos.z, 0, clamp_v); - - float level = (p_cell_subdiv - 1) - p_level; - - int target_level; - float level_filter; - if (level <= 0.0) { - level_filter = 0; - target_level = 0; - } else { - target_level = Math::ceil(level); - level_filter = target_level - level; - } - - Vector3 color[2][8]; - float alpha[2][8]; - zeromem(alpha, sizeof(float) * 2 * 8); - - //find cell at given level first - - for (int c = 0; c < 2; c++) { - - int current_level = MAX(0, target_level - c); - int level_cell_size = (1 << (p_cell_subdiv - 1)) >> current_level; - - for (int n = 0; n < 8; n++) { - - int x = int(pos.x); - int y = int(pos.y); - int z = int(pos.z); +void RenderingServerScene::_update_instance_lightmap_captures(Instance *p_instance) { + bool first_set = p_instance->lightmap_sh.size() == 0; + p_instance->lightmap_sh.resize(9); //using SH + p_instance->lightmap_target_sh.resize(9); //using SH + Color *instance_sh = p_instance->lightmap_target_sh.ptrw(); + bool inside = false; + Color accum_sh[9]; + float accum_blend = 0.0; - if (n & 1) - x += level_cell_size; - if (n & 2) - y += level_cell_size; - if (n & 4) - z += level_cell_size; + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); + for (List<Instance *>::Element *E = geom->lightmap_captures.front(); E; E = E->next()) { + Instance *lightmap = E->get(); - int ofs_x = 0; - int ofs_y = 0; - int ofs_z = 0; + bool interior = RSG::storage->lightmap_is_interior(lightmap->base); - x = CLAMP(x, 0, clamp_v); - y = CLAMP(y, 0, clamp_v); - z = CLAMP(z, 0, clamp_v); + if (inside && !interior) { + continue; //we are inside, ignore exteriors + } - int half = size / 2; - uint32_t cell = 0; - for (int i = 0; i < current_level; i++) { + Transform to_bounds = lightmap->transform.affine_inverse(); + Vector3 center = p_instance->transform.xform(p_instance->aabb.position + p_instance->aabb.size * 0.5); //use aabb center - const RasterizerStorage::LightmapCaptureOctree *bc = &p_octree[cell]; + Vector3 lm_pos = to_bounds.xform(center); - int child = 0; - if (x >= ofs_x + half) { - child |= 1; - ofs_x += half; - } - if (y >= ofs_y + half) { - child |= 2; - ofs_y += half; - } - if (z >= ofs_z + half) { - child |= 4; - ofs_z += half; - } + AABB bounds = RSG::storage->lightmap_get_aabb(lightmap->base); + if (!bounds.has_point(lm_pos)) { + continue; //not in this lightmap + } - cell = bc->children[child]; - if (cell == RasterizerStorage::LightmapCaptureOctree::CHILD_EMPTY) - break; + Color sh[9]; + RSG::storage->lightmap_tap_sh_light(lightmap->base, lm_pos, sh); - half >>= 1; + //rotate it + Basis rot = lightmap->transform.basis.orthonormalized(); + for (int i = 0; i < 3; i++) { + float csh[9]; + for (int j = 0; j < 9; j++) { + csh[j] = sh[j][i]; } - - if (cell == RasterizerStorage::LightmapCaptureOctree::CHILD_EMPTY) { - alpha[c][n] = 0; - } else { - alpha[c][n] = p_octree[cell].alpha; - - for (int i = 0; i < 6; i++) { - //anisotropic read light - float amount = p_dir.dot(aniso_normal[i]); - if (amount < 0) - amount = 0; - color[c][n].x += p_octree[cell].light[i][0] / 1024.0 * amount; - color[c][n].y += p_octree[cell].light[i][1] / 1024.0 * amount; - color[c][n].z += p_octree[cell].light[i][2] / 1024.0 * amount; - } + rot.rotate_sh(csh); + for (int j = 0; j < 9; j++) { + sh[j][i] = csh[j]; } - - //print_line("\tlev " + itos(c) + " - " + itos(n) + " alpha: " + rtos(cells[test_cell].alpha) + " col: " + color[c][n]); } - } - - float target_level_size = size >> target_level; - Vector3 pos_fract[2]; - - pos_fract[0].x = Math::fmod(pos.x, target_level_size) / target_level_size; - pos_fract[0].y = Math::fmod(pos.y, target_level_size) / target_level_size; - pos_fract[0].z = Math::fmod(pos.z, target_level_size) / target_level_size; - - target_level_size = size >> MAX(0, target_level - 1); - - pos_fract[1].x = Math::fmod(pos.x, target_level_size) / target_level_size; - pos_fract[1].y = Math::fmod(pos.y, target_level_size) / target_level_size; - pos_fract[1].z = Math::fmod(pos.z, target_level_size) / target_level_size; - - float alpha_interp[2]; - Vector3 color_interp[2]; - - for (int i = 0; i < 2; i++) { - - Vector3 color_x00 = color[i][0].lerp(color[i][1], pos_fract[i].x); - Vector3 color_xy0 = color[i][2].lerp(color[i][3], pos_fract[i].x); - Vector3 blend_z0 = color_x00.lerp(color_xy0, pos_fract[i].y); - - Vector3 color_x0z = color[i][4].lerp(color[i][5], pos_fract[i].x); - Vector3 color_xyz = color[i][6].lerp(color[i][7], pos_fract[i].x); - Vector3 blend_z1 = color_x0z.lerp(color_xyz, pos_fract[i].y); - - color_interp[i] = blend_z0.lerp(blend_z1, pos_fract[i].z); - - float alpha_x00 = Math::lerp(alpha[i][0], alpha[i][1], pos_fract[i].x); - float alpha_xy0 = Math::lerp(alpha[i][2], alpha[i][3], pos_fract[i].x); - float alpha_z0 = Math::lerp(alpha_x00, alpha_xy0, pos_fract[i].y); - - float alpha_x0z = Math::lerp(alpha[i][4], alpha[i][5], pos_fract[i].x); - float alpha_xyz = Math::lerp(alpha[i][6], alpha[i][7], pos_fract[i].x); - float alpha_z1 = Math::lerp(alpha_x0z, alpha_xyz, pos_fract[i].y); - - alpha_interp[i] = Math::lerp(alpha_z0, alpha_z1, pos_fract[i].z); - } - - r_color = color_interp[0].lerp(color_interp[1], level_filter); - r_alpha = Math::lerp(alpha_interp[0], alpha_interp[1], level_filter); - - //print_line("pos: " + p_posf + " level " + rtos(p_level) + " down to " + itos(target_level) + "." + rtos(level_filter) + " color " + r_color + " alpha " + rtos(r_alpha)); -} - -_FORCE_INLINE_ static Color _light_capture_voxel_cone_trace(const RasterizerStorage::LightmapCaptureOctree *p_octree, const Vector3 &p_pos, const Vector3 &p_dir, float p_aperture, int p_cell_subdiv) { - - float bias = 0.0; //no need for bias here - float max_distance = (Vector3(1, 1, 1) * (1 << (p_cell_subdiv - 1))).length(); - - float dist = bias; - float alpha = 0.0; - Vector3 color; - - Vector3 scolor; - float salpha; - - while (dist < max_distance && alpha < 0.95) { - float diameter = MAX(1.0, 2.0 * p_aperture * dist); - _light_capture_sample_octree(p_octree, p_cell_subdiv, p_pos + dist * p_dir, p_dir, log2(diameter), scolor, salpha); - float a = (1.0 - alpha); - color += scolor * a; - alpha += a * salpha; - dist += diameter * 0.5; - } - - return Color(color.x, color.y, color.z, alpha); -} -void RenderingServerScene::_update_instance_lightmap_captures(Instance *p_instance) { - - InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); + Vector3 inner_pos = ((lm_pos - bounds.position) / bounds.size) * 2.0 - Vector3(1.0, 1.0, 1.0); - static const Vector3 cone_traces[12] = { - Vector3(0, 0, 1), - Vector3(0.866025, 0, 0.5), - Vector3(0.267617, 0.823639, 0.5), - Vector3(-0.700629, 0.509037, 0.5), - Vector3(-0.700629, -0.509037, 0.5), - Vector3(0.267617, -0.823639, 0.5), - Vector3(0, 0, -1), - Vector3(0.866025, 0, -0.5), - Vector3(0.267617, 0.823639, -0.5), - Vector3(-0.700629, 0.509037, -0.5), - Vector3(-0.700629, -0.509037, -0.5), - Vector3(0.267617, -0.823639, -0.5) - }; + float blend = MAX(inner_pos.x, MAX(inner_pos.y, inner_pos.z)); + //make blend more rounded + blend = Math::lerp(inner_pos.length(), blend, blend); + blend *= blend; + blend = MAX(0.0, 1.0 - blend); - float cone_aperture = 0.577; // tan(angle) 60 degrees - - if (p_instance->lightmap_capture_data.empty()) { - p_instance->lightmap_capture_data.resize(12); + if (interior && !inside) { + //do not blend, just replace + for (int j = 0; j < 9; j++) { + accum_sh[j] = sh[j] * blend; + } + accum_blend = blend; + inside = true; + } else { + for (int j = 0; j < 9; j++) { + accum_sh[j] += sh[j] * blend; + } + accum_blend += blend; + } } - //print_line("update captures for pos: " + p_instance->transform.origin); - - for (int i = 0; i < 12; i++) - new (&p_instance->lightmap_capture_data.ptrw()[i]) Color; - - //this could use some sort of blending.. - for (List<Instance *>::Element *E = geom->lightmap_captures.front(); E; E = E->next()) { - const Vector<RasterizerStorage::LightmapCaptureOctree> *octree = RSG::storage->lightmap_capture_get_octree_ptr(E->get()->base); - //print_line("octree size: " + itos(octree->size())); - if (octree->size() == 0) - continue; - Transform to_cell_xform = RSG::storage->lightmap_capture_get_octree_cell_transform(E->get()->base); - int cell_subdiv = RSG::storage->lightmap_capture_get_octree_cell_subdiv(E->get()->base); - to_cell_xform = to_cell_xform * E->get()->transform.affine_inverse(); - - const RasterizerStorage::LightmapCaptureOctree *octree_r = octree->ptr(); - - Vector3 pos = to_cell_xform.xform(p_instance->transform.origin); - - for (int i = 0; i < 12; i++) { - - Vector3 dir = to_cell_xform.basis.xform(cone_traces[i]).normalized(); - Color capture = _light_capture_voxel_cone_trace(octree_r, pos, dir, cone_aperture, cell_subdiv); - p_instance->lightmap_capture_data.write[i] += capture; + if (accum_blend > 0.0) { + for (int j = 0; j < 9; j++) { + instance_sh[j] = accum_sh[j] / accum_blend; + if (first_set) { + p_instance->lightmap_sh.write[j] = instance_sh[j]; + } } } } bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario) { - InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data); Transform light_transform = p_instance->transform; @@ -1462,9 +1241,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c bool animated_material_found = false; switch (RSG::storage->light_get_type(p_instance->base)) { - case RS::LIGHT_DIRECTIONAL: { - real_t max_distance = p_cam_projection.get_z_far(); real_t shadow_max = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE); if (shadow_max > 0 && !p_cam_orthogonal) { //its impractical (and leads to unwanted behaviors) to set max distance in orthogonal camera @@ -1489,7 +1266,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c real_t z_min = 1e20; for (int i = 0; i < cull_count; i++) { - Instance *instance = instance_shadow_cull_result[i]; if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { continue; @@ -1552,7 +1328,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c real_t min_distance_bias_scale = pancake_size > 0 ? distances[1] / 10.0 : 0; for (int i = 0; i < splits; i++) { - RENDER_TIMESTAMP("Culling Directional Light split" + itos(i)); // setup a camera matrix for that range! @@ -1561,12 +1336,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c real_t aspect = p_cam_projection.get_aspect(); if (p_cam_orthogonal) { - Vector2 vp_he = p_cam_projection.get_viewport_half_extents(); camera_matrix.set_orthogonal(vp_he.y * 2.0, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); } else { - real_t fov = p_cam_projection.get_fov(); //this is actually yfov, because set aspect tries to keep it camera_matrix.set_perspective(fov, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true); } @@ -1603,25 +1376,30 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c //used for culling for (int j = 0; j < 8; j++) { - real_t d_x = x_vec.dot(endpoints[j]); real_t d_y = y_vec.dot(endpoints[j]); real_t d_z = z_vec.dot(endpoints[j]); - if (j == 0 || d_x < x_min) + if (j == 0 || d_x < x_min) { x_min = d_x; - if (j == 0 || d_x > x_max) + } + if (j == 0 || d_x > x_max) { x_max = d_x; + } - if (j == 0 || d_y < y_min) + if (j == 0 || d_y < y_min) { y_min = d_y; - if (j == 0 || d_y > y_max) + } + if (j == 0 || d_y > y_max) { y_max = d_y; + } - if (j == 0 || d_z < z_min) + if (j == 0 || d_z < z_min) { z_min = d_z; - if (j == 0 || d_z > z_max) + } + if (j == 0 || d_z > z_max) { z_max = d_z; + } } real_t radius = 0; @@ -1632,7 +1410,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c //camera viewport stuff for (int j = 0; j < 8; j++) { - center += endpoints[j]; } center /= 8.0; @@ -1640,10 +1417,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c //center=x_vec*(x_max-x_min)*0.5 + y_vec*(y_max-y_min)*0.5 + z_vec*(z_max-z_min)*0.5; for (int j = 0; j < 8; j++) { - real_t d = center.distance_to(endpoints[j]); - if (d > radius) + if (d > radius) { radius = d; + } } radius *= texture_size / (texture_size - 2.0); //add a texel by each side @@ -1657,11 +1434,9 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c z_min_cam = z_vec.dot(center) - radius; { - float soft_shadow_angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE); if (soft_shadow_angle > 0.0 && pancake_size > 0.0) { - float z_range = (z_vec.dot(center) + radius + pancake_size) - z_min_cam; soft_shadow_expand = Math::tan(Math::deg2rad(soft_shadow_angle)) * z_range; @@ -1714,7 +1489,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c real_t cull_max = 0; for (int j = 0; j < cull_count; j++) { - real_t min, max; Instance *instance = instance_shadow_cull_result[j]; if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { @@ -1741,14 +1515,12 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } if (aspect != 1.0) { - // if the aspect is different, then the radius will become larger. // if this happens, then bias needs to be adjusted too, as depth will increase // to do this, compare the depth of one that would have resulted from a square frustum CameraMatrix camera_matrix_square; if (p_cam_orthogonal) { - Vector2 vp_he = camera_matrix.get_viewport_half_extents(); if (p_cam_vaspect) { camera_matrix_square.set_orthogonal(vp_he.x * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true); @@ -1762,10 +1534,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } else { camera_matrix_square.set_frustum(vp_he.y * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); } - - if (i == 0) { - //print_line("prev he: " + vp_he + " new he: " + camera_matrix_square.get_viewport_half_extents()); - } } Vector3 endpoints_square[8]; // frustum plane endpoints @@ -1775,13 +1543,13 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c real_t z_max_square = 0; for (int j = 0; j < 8; j++) { - center_square += endpoints_square[j]; real_t d_z = z_vec.dot(endpoints_square[j]); - if (j == 0 || d_z > z_max_square) + if (j == 0 || d_z > z_max_square) { z_max_square = d_z; + } } if (cull_max > z_max_square) { @@ -1793,10 +1561,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c real_t radius_square = 0; for (int j = 0; j < 8; j++) { - real_t d = center_square.distance_to(endpoints_square[j]); - if (d > radius_square) + if (d > radius_square) { radius_square = d; + } } radius_square *= texture_size / (texture_size - 2.0); //add a texel by each side @@ -1815,7 +1583,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } { - CameraMatrix ortho_camera; real_t half_x = (x_max_cam - x_min_cam) * 0.5; real_t half_y = (y_max_cam - y_min_cam) * 0.5; @@ -1842,13 +1609,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } break; case RS::LIGHT_OMNI: { - RS::LightOmniShadowMode shadow_mode = RSG::storage->light_omni_get_shadow_mode(p_instance->base); if (shadow_mode == RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !RSG::scene_render->light_instances_can_render_shadow_cube()) { - for (int i = 0; i < 2; i++) { - //using this one ensures that raster deferred will have it RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i)); @@ -1868,7 +1632,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z); for (int j = 0; j < cull_count; j++) { - Instance *instance = instance_shadow_cull_result[j]; if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { cull_count--; @@ -1894,7 +1657,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c cm.set_perspective(90, 1, 0.01, radius); for (int i = 0; i < 6; i++) { - RENDER_TIMESTAMP("Culling Shadow Cube side" + itos(i)); //using this one ensures that raster deferred will have it @@ -1923,7 +1685,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c Plane near_plane(xform.origin, -xform.basis.get_axis(2)); for (int j = 0; j < cull_count; j++) { - Instance *instance = instance_shadow_cull_result[j]; if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { cull_count--; @@ -1948,7 +1709,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } break; case RS::LIGHT_SPOT: { - RENDER_TIMESTAMP("Culling Spot Light"); real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); @@ -1962,7 +1722,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2)); for (int j = 0; j < cull_count; j++) { - Instance *instance = instance_shadow_cull_result[j]; if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { cull_count--; @@ -1999,7 +1758,6 @@ void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID switch (camera->type) { case Camera::ORTHOGONAL: { - camera_matrix.set_orthogonal( camera->size, p_viewport_size.width / (float)p_viewport_size.height, @@ -2009,7 +1767,6 @@ void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID ortho = true; } break; case Camera::PERSPECTIVE: { - camera_matrix.set_perspective( camera->fov, p_viewport_size.width / (float)p_viewport_size.height, @@ -2020,7 +1777,6 @@ void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID } break; case Camera::FRUSTUM: { - camera_matrix.set_frustum( camera->size, p_viewport_size.width / (float)p_viewport_size.height, @@ -2147,6 +1903,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const reflection_probe_cull_count = 0; decal_cull_count = 0; gi_probe_cull_count = 0; + lightmap_cull_count = 0; //light_samplers_culled=0; @@ -2161,9 +1918,10 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const //removed, will replace with culling /* STEP 4 - REMOVE FURTHER CULLED OBJECTS, ADD LIGHTS */ + uint64_t frame_number = RSG::rasterizer->get_frame_number(); + float lightmap_probe_update_speed = RSG::storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time(); for (int i = 0; i < instance_cull_count; i++) { - Instance *ins = instance_cull_result[i]; bool keep = false; @@ -2171,9 +1929,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const if ((camera_layer_mask & ins->layer_mask) == 0) { //failure } else if (ins->base_type == RS::INSTANCE_LIGHT && ins->visible) { - if (light_cull_count < MAX_LIGHTS_CULLED) { - InstanceLightData *light = static_cast<InstanceLightData *>(ins->base_data); if (!light->geometries.empty()) { @@ -2188,9 +1944,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const } } } else if (ins->base_type == RS::INSTANCE_REFLECTION_PROBE && ins->visible) { - if (reflection_probe_cull_count < MAX_REFLECTION_PROBES_CULLED) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(ins->base_data); if (p_reflection_probe != reflection_probe->instance) { @@ -2216,9 +1970,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const } } } else if (ins->base_type == RS::INSTANCE_DECAL && ins->visible) { - if (decal_cull_count < MAX_DECALS_CULLED) { - InstanceDecalData *decal = static_cast<InstanceDecalData *>(ins->base_data); if (!decal->geometries.empty()) { @@ -2229,7 +1981,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const } } else if (ins->base_type == RS::INSTANCE_GI_PROBE && ins->visible) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(ins->base_data); if (!gi_probe->update_element.in_list()) { gi_probe_update_list.add(&gi_probe->update_element); @@ -2239,9 +1990,13 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const gi_probe_instance_cull_result[gi_probe_cull_count] = gi_probe->probe_instance; gi_probe_cull_count++; } + } else if (ins->base_type == RS::INSTANCE_LIGHTMAP && ins->visible) { + if (lightmap_cull_count < MAX_LIGHTMAPS_CULLED) { + lightmap_cull_result[lightmap_cull_count] = ins; + lightmap_cull_count++; + } } else if (((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) && ins->visible && ins->cast_shadows != RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) { - keep = true; InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(ins->base_data); @@ -2268,7 +2023,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const ins->light_instances.resize(geom->lighting.size()); for (List<Instance *>::Element *E = geom->lighting.front(); E; E = E->next()) { - InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data); ins->light_instances.write[l++] = light->instance; @@ -2283,7 +2037,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const ins->reflection_probe_instances.resize(geom->reflection_probes.size()); for (List<Instance *>::Element *E = geom->reflection_probes.front(); E; E = E->next()) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data); ins->reflection_probe_instances.write[l++] = reflection_probe->instance; @@ -2298,7 +2051,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const ins->gi_probe_instances.resize(geom->gi_probes.size()); for (List<Instance *>::Element *E = geom->gi_probes.front(); E; E = E->next()) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(E->get()->base_data); ins->gi_probe_instances.write[l++] = gi_probe->probe_instance; @@ -2307,6 +2059,14 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const geom->gi_probes_dirty = false; } + if (ins->last_frame_pass != frame_number && !ins->lightmap_target_sh.empty() && !ins->lightmap_sh.empty()) { + Color *sh = ins->lightmap_sh.ptrw(); + const Color *target_sh = ins->lightmap_target_sh.ptr(); + for (uint32_t j = 0; j < 9; j++) { + sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed)); + } + } + ins->depth = near_plane.distance_to(ins->transform.origin); ins->depth_layer = CLAMP(int(ins->depth * 16 / z_far), 0, 15); } @@ -2318,9 +2078,9 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const i--; ins->last_render_pass = 0; // make invalid } else { - ins->last_render_pass = render_pass; } + ins->last_frame_pass = frame_number; } /* STEP 5 - PROCESS LIGHTS */ @@ -2330,18 +2090,17 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const // directional lights { - Instance **lights_with_shadow = (Instance **)alloca(sizeof(Instance *) * scenario->directional_lights.size()); int directional_shadow_count = 0; for (List<Instance *>::Element *E = scenario->directional_lights.front(); E; E = E->next()) { - if (light_cull_count + directional_light_count >= MAX_LIGHTS_CULLED) { break; } - if (!E->get()->visible) + if (!E->get()->visible) { continue; + } InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data); @@ -2359,7 +2118,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const RSG::scene_render->set_directional_shadow_count(directional_shadow_count); for (int i = 0; i < directional_shadow_count; i++) { - RENDER_TIMESTAMP(">Rendering Directional Light " + itos(i)); _light_instance_update_shadow(lights_with_shadow[i], p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario); @@ -2373,11 +2131,11 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const //SortArray<Instance*,_InstanceLightsort> sorter; //sorter.sort(light_cull_result,light_cull_count); for (int i = 0; i < light_cull_count; i++) { - Instance *ins = light_cull_result[i]; - if (!p_shadow_atlas.is_valid() || !RSG::storage->light_has_shadow(ins->base)) + if (!p_shadow_atlas.is_valid() || !RSG::storage->light_has_shadow(ins->base)) { continue; + } InstanceLightData *light = static_cast<InstanceLightData *>(ins->base_data); @@ -2393,9 +2151,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const Vector2 vp_half_extents = p_cam_projection.get_viewport_half_extents(); switch (RSG::storage->light_get_type(ins->base)) { - case RS::LIGHT_OMNI: { - float radius = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE); //get two points parallel to near plane @@ -2419,7 +2175,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const coverage = screen_diameter / (vp_half_extents.x + vp_half_extents.y); } break; case RS::LIGHT_SPOT: { - float radius = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE); float angle = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_SPOT_ANGLE); @@ -2472,18 +2227,18 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const } void RenderingServerScene::_render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass) { - Scenario *scenario = scenario_owner.getornull(p_scenario); /* ENVIRONMENT */ RID environment; - if (p_force_environment.is_valid()) //camera has more environment priority + if (p_force_environment.is_valid()) { //camera has more environment priority environment = p_force_environment; - else if (scenario->environment.is_valid()) + } else if (scenario->environment.is_valid()) { environment = scenario->environment; - else + } else { environment = scenario->fallback_environment; + } RID camera_effects; if (p_force_camera_effects.is_valid()) { @@ -2494,27 +2249,26 @@ void RenderingServerScene::_render_scene(RID p_render_buffers, const Transform p /* PROCESS GEOMETRY AND DRAW SCENE */ RENDER_TIMESTAMP("Render Scene "); - RSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, decal_instance_cull_result, decal_cull_count, environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass); + RSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, decal_instance_cull_result, decal_cull_count, (RasterizerScene::InstanceBase **)lightmap_cull_result, lightmap_cull_count, environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass); } void RenderingServerScene::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) { - #ifndef _3D_DISABLED Scenario *scenario = scenario_owner.getornull(p_scenario); RID environment; - if (scenario->environment.is_valid()) + if (scenario->environment.is_valid()) { environment = scenario->environment; - else + } else { environment = scenario->fallback_environment; + } RENDER_TIMESTAMP("Render Empty Scene "); - RSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0); + RSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0); #endif } bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, int p_step) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data); Scenario *scenario = p_instance->scenario; ERR_FAIL_COND_V(!scenario, true); @@ -2522,14 +2276,12 @@ bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, i RenderingServerRaster::redraw_request(); //update, so it updates in editor if (p_step == 0) { - if (!RSG::scene_render->reflection_probe_instance_begin_render(reflection_probe->instance, scenario->reflection_atlas)) { return true; //all full } } if (p_step >= 0 && p_step < 6) { - static const Vector3 view_normals[6] = { Vector3(+1, 0, 0), Vector3(-1, 0, 0), @@ -2569,7 +2321,6 @@ bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, i bool use_shadows = RSG::storage->reflection_probe_renders_shadows(p_instance->base); if (use_shadows) { - shadow_atlas = scenario->reflection_probe_shadow_atlas; } @@ -2587,7 +2338,6 @@ bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, i } void RenderingServerScene::render_probes() { - /* REFLECTION PROBES */ SelfList<InstanceReflectionProbeData> *ref_probe = reflection_probe_render_list.first(); @@ -2595,15 +2345,14 @@ void RenderingServerScene::render_probes() { bool busy = false; while (ref_probe) { - SelfList<InstanceReflectionProbeData> *next = ref_probe->next(); RID base = ref_probe->self()->owner->base; switch (RSG::storage->reflection_probe_get_update_mode(base)) { - case RS::REFLECTION_PROBE_UPDATE_ONCE: { - if (busy) //already rendering something + if (busy) { //already rendering something break; + } bool done = _render_reflection_probe_step(ref_probe->self()->owner, ref_probe->self()->render_step); if (done) { @@ -2615,7 +2364,6 @@ void RenderingServerScene::render_probes() { busy = true; //do not render another one of this kind } break; case RS::REFLECTION_PROBE_UPDATE_ALWAYS: { - int step = 0; bool done = false; while (!done) { @@ -2639,7 +2387,6 @@ void RenderingServerScene::render_probes() { } while (gi_probe) { - SelfList<InstanceGIProbeData> *next = gi_probe->next(); InstanceGIProbeData *probe = gi_probe->self(); @@ -2650,7 +2397,6 @@ void RenderingServerScene::render_probes() { bool cache_dirty = false; int cache_count = 0; { - int light_cache_size = probe->light_cache.size(); const InstanceGIProbeData::LightCache *caches = probe->light_cache.ptr(); const RID *instance_caches = probe->light_instances.ptr(); @@ -2667,7 +2413,6 @@ void RenderingServerScene::render_probes() { } else if (idx >= light_cache_size) { cache_dirty = true; } else { - const InstanceGIProbeData::LightCache *cache = &caches[idx]; if ( @@ -2690,7 +2435,6 @@ void RenderingServerScene::render_probes() { } for (List<Instance *>::Element *E = probe->owner->scenario->directional_lights.front(); E; E = E->next()) { - Instance *instance = E->get(); InstanceLightData *instance_light = (InstanceLightData *)instance->base_data; if (!instance->visible) { @@ -2701,7 +2445,6 @@ void RenderingServerScene::render_probes() { } else if (idx >= light_cache_size) { cache_dirty = true; } else { - const InstanceGIProbeData::LightCache *cache = &caches[idx]; if ( @@ -2808,7 +2551,6 @@ void RenderingServerScene::render_probes() { ins->gi_probe_instances.resize(geom->gi_probes.size()); for (List<Instance *>::Element *F = geom->gi_probes.front(); F; F = F->next()) { - InstanceGIProbeData *gi_probe2 = static_cast<InstanceGIProbeData *>(F->get()->base_data); ins->gi_probe_instances.write[l++] = gi_probe2->probe_instance; @@ -2830,7 +2572,6 @@ void RenderingServerScene::render_probes() { } void RenderingServerScene::_update_instance_shader_parameters_from_material(Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material) { - List<RasterizerStorage::InstanceShaderParam> plist; RSG::storage->material_get_instance_shader_parameters(p_material, &plist); for (List<RasterizerStorage::InstanceShaderParam>::Element *E = plist.front(); E; E = E->next()) { @@ -2859,13 +2600,11 @@ void RenderingServerScene::_update_instance_shader_parameters_from_material(Map< } void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { - if (p_instance->update_aabb) { _update_instance_aabb(p_instance); } if (p_instance->update_dependencies) { - p_instance->instance_increase_version(); if (p_instance->base.is_valid()) { @@ -2892,7 +2631,6 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { } if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { - InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); bool can_cast_shadows = true; @@ -2910,7 +2648,6 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { is_animated = RSG::storage->material_is_animated(p_instance->material_override); _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, p_instance->material_override); } else { - if (p_instance->base_type == RS::INSTANCE_MESH) { RID mesh = p_instance->base; @@ -2918,13 +2655,11 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { bool cast_shadows = false; for (int i = 0; i < p_instance->materials.size(); i++) { - RID mat = p_instance->materials[i].is_valid() ? p_instance->materials[i] : RSG::storage->mesh_surface_get_material(mesh, i); if (!mat.is_valid()) { cast_shadows = true; } else { - if (RSG::storage->material_casts_shadows(mat)) { cast_shadows = true; } @@ -2947,19 +2682,16 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { } else if (p_instance->base_type == RS::INSTANCE_MULTIMESH) { RID mesh = RSG::storage->multimesh_get_mesh(p_instance->base); if (mesh.is_valid()) { - bool cast_shadows = false; int sc = RSG::storage->mesh_get_surface_count(mesh); for (int i = 0; i < sc; i++) { - RID mat = RSG::storage->mesh_surface_get_material(mesh, i); if (!mat.is_valid()) { cast_shadows = true; } else { - if (RSG::storage->material_casts_shadows(mat)) { cast_shadows = true; } @@ -2980,7 +2712,6 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { RSG::storage->base_update_dependency(mesh, p_instance); } } else if (p_instance->base_type == RS::INSTANCE_IMMEDIATE) { - RID mat = RSG::storage->immediate_get_material(p_instance->base); if (!(!mat.is_valid() || RSG::storage->material_casts_shadows(mat))) { @@ -3000,26 +2731,23 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { } } else if (p_instance->base_type == RS::INSTANCE_PARTICLES) { - bool cast_shadows = false; int dp = RSG::storage->particles_get_draw_passes(p_instance->base); for (int i = 0; i < dp; i++) { - RID mesh = RSG::storage->particles_get_draw_pass_mesh(p_instance->base, i); - if (!mesh.is_valid()) + if (!mesh.is_valid()) { continue; + } int sc = RSG::storage->mesh_get_surface_count(mesh); for (int j = 0; j < sc; j++) { - RID mat = RSG::storage->mesh_surface_get_material(mesh, j); if (!mat.is_valid()) { cast_shadows = true; } else { - if (RSG::storage->material_casts_shadows(mat)) { cast_shadows = true; } @@ -3086,26 +2814,21 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { } void RenderingServerScene::update_dirty_instances() { - RSG::storage->update_dirty_resources(); while (_instance_update_list.first()) { - _update_dirty_instance(_instance_update_list.first()->self()); } } bool RenderingServerScene::free(RID p_rid) { - if (camera_owner.owns(p_rid)) { - Camera *camera = camera_owner.getornull(p_rid); camera_owner.free(p_rid); memdelete(camera); } else if (scenario_owner.owns(p_rid)) { - Scenario *scenario = scenario_owner.getornull(p_rid); while (scenario->instances.first()) { @@ -3123,7 +2846,7 @@ bool RenderingServerScene::free(RID p_rid) { Instance *instance = instance_owner.getornull(p_rid); - instance_set_use_lightmap(p_rid, RID(), RID()); + instance_geometry_set_lightmap(p_rid, RID(), Rect2(), 0); instance_set_scenario(p_rid, RID()); instance_set_base(p_rid, RID()); instance_geometry_set_material_override(p_rid, RID()); @@ -3144,10 +2867,13 @@ bool RenderingServerScene::free(RID p_rid) { return true; } +TypedArray<Image> RenderingServerScene::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) { + return RSG::scene_render->bake_render_uv2(p_base, p_material_overrides, p_image_size); +} + RenderingServerScene *RenderingServerScene::singleton = nullptr; RenderingServerScene::RenderingServerScene() { - render_pass = 1; singleton = this; } diff --git a/servers/rendering/rendering_server_scene.h b/servers/rendering/rendering_server_scene.h index eb66cea3aa..f59028603f 100644 --- a/servers/rendering/rendering_server_scene.h +++ b/servers/rendering/rendering_server_scene.h @@ -51,6 +51,7 @@ public: MAX_DECALS_CULLED = 4096, MAX_GI_PROBES_CULLED = 4096, MAX_ROOM_CULL = 32, + MAX_LIGHTMAPS_CULLED = 4096, MAX_EXTERIOR_PORTALS = 128, }; @@ -61,7 +62,6 @@ public: /* CAMERA API */ struct Camera { - enum Type { PERSPECTIVE, ORTHOGONAL, @@ -80,7 +80,6 @@ public: Transform transform; Camera() { - visible_layers = 0xFFFFFFFF; fov = 75; type = PERSPECTIVE; @@ -109,7 +108,6 @@ public: struct Instance; struct Scenario { - RS::ScenarioDebugMode debug; RID self; @@ -143,12 +141,10 @@ public: /* INSTANCING API */ struct InstanceBaseData { - virtual ~InstanceBaseData() {} }; struct Instance : RasterizerScene::InstanceBase { - RID self; //scenario stuff OctreeElementID octree_id; @@ -171,6 +167,8 @@ public: float lod_end_hysteresis; RID lod_instance; + Vector<Color> lightmap_target_sh; //target is used for incrementally changing the SH over time, this avoids pops in some corner cases and when going interior <-> exterior + uint64_t last_render_pass; uint64_t last_frame_pass; @@ -195,7 +193,6 @@ public: Instance() : scenario_item(this), update_item(this) { - octree_id = 0; scenario = nullptr; @@ -220,11 +217,12 @@ public: } ~Instance() { - - if (base_data) + if (base_data) { memdelete(base_data); - if (custom_aabb) + } + if (custom_aabb) { memdelete(custom_aabb); + } } }; @@ -232,7 +230,6 @@ public: void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies = false); struct InstanceGeometryData : public InstanceBaseData { - List<Instance *> lighting; bool lighting_dirty; bool can_cast_shadows; @@ -250,7 +247,6 @@ public: List<Instance *> lightmap_captures; InstanceGeometryData() { - lighting_dirty = false; reflection_dirty = true; can_cast_shadows = true; @@ -261,7 +257,6 @@ public: }; struct InstanceReflectionProbeData : public InstanceBaseData { - Instance *owner; struct PairInfo { @@ -278,14 +273,12 @@ public: InstanceReflectionProbeData() : update_list(this) { - reflection_dirty = true; render_step = -1; } }; struct InstanceDecalData : public InstanceBaseData { - Instance *owner; RID instance; @@ -302,7 +295,6 @@ public: SelfList<InstanceReflectionProbeData>::List reflection_probe_render_list; struct InstanceLightData : public InstanceBaseData { - struct PairInfo { List<Instance *>::Element *L; //light iterator in geometry Instance *geometry; @@ -319,7 +311,6 @@ public: Instance *baked_light; InstanceLightData() { - shadow_dirty = true; D = nullptr; last_version = 0; @@ -328,7 +319,6 @@ public: }; struct InstanceGIProbeData : public InstanceBaseData { - Instance *owner; struct PairInfo { @@ -342,7 +332,6 @@ public: Set<Instance *> lights; struct LightCache { - RS::LightType type; Transform transform; Color color; @@ -374,8 +363,7 @@ public: SelfList<InstanceGIProbeData>::List gi_probe_update_list; - struct InstanceLightmapCaptureData : public InstanceBaseData { - + struct InstanceLightmapData : public InstanceBaseData { struct PairInfo { List<Instance *>::Element *L; //iterator in geometry Instance *geometry; @@ -384,7 +372,7 @@ public: Set<Instance *> users; - InstanceLightmapCaptureData() { + InstanceLightmapData() { } }; @@ -401,6 +389,8 @@ public: int decal_cull_count; RID gi_probe_instance_cull_result[MAX_GI_PROBES_CULLED]; int gi_probe_cull_count; + Instance *lightmap_cull_result[MAX_LIGHTS_CULLED]; + int lightmap_cull_count; RID_PtrOwner<Instance> instance_owner; @@ -414,7 +404,6 @@ public: virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight); virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material); virtual void instance_set_visible(RID p_instance, bool p_visible); - virtual void instance_set_use_lightmap(RID p_instance, RID p_lightmap_instance, RID p_lightmap); virtual void instance_set_custom_aabb(RID p_instance, AABB p_aabb); @@ -434,6 +423,7 @@ public: virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin); virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance); + virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index); void _update_instance_shader_parameters_from_material(Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material); @@ -460,6 +450,8 @@ public: void render_probes(); + TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size); + bool free(RID p_rid); RenderingServerScene(); diff --git a/servers/rendering/rendering_server_viewport.cpp b/servers/rendering/rendering_server_viewport.cpp index 6fb8f6ca63..48be6ca13b 100644 --- a/servers/rendering/rendering_server_viewport.cpp +++ b/servers/rendering/rendering_server_viewport.cpp @@ -36,7 +36,6 @@ #include "rendering_server_scene.h" static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_viewport, RenderingServerCanvas::Canvas *p_canvas, RenderingServerViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) { - Transform2D xf = p_viewport->global_transform; float scale = 1.0; @@ -63,7 +62,6 @@ static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_vi } void RenderingServerViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p_eye) { - RENDER_TIMESTAMP(">Begin Rendering 3D Scene"); Ref<XRInterface> xr_interface; @@ -80,7 +78,6 @@ void RenderingServerViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p } void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye) { - if (p_viewport->measure_render_time) { String rt_id = "vp_begin_" + itos(p_viewport->self.get_id()); RSG::storage->capture_timestamp(rt_id); @@ -95,7 +92,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: Color bgcolor = RSG::storage->get_default_clear_color(); if (!p_viewport->hide_canvas && !p_viewport->disable_environment && RSG::scene->scenario_owner.owns(p_viewport->scenario)) { - RenderingServerScene::Scenario *scenario = RSG::scene->scenario_owner.getornull(p_viewport->scenario); ERR_FAIL_COND(!scenario); if (RSG::scene_render->is_environment(scenario->environment)) { @@ -143,7 +139,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: RENDER_TIMESTAMP("Cull Canvas Lights"); for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { - RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas); Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); @@ -151,7 +146,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: //find lights in canvas for (Set<RasterizerCanvas::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) { - RasterizerCanvas::Light *cl = F->get(); if (cl->enabled && cl->texture.is_valid()) { //not super efficient.. @@ -163,7 +157,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: cl->xform_cache = xf * cl->xform; if (clip_rect.intersects_transformed(cl->xform_cache, cl->rect_cache)) { - cl->filter_next_ptr = lights; lights = cl; // cl->texture_cache = nullptr; @@ -173,7 +166,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: cl->light_shader_xform = cl->xform * scale; //cl->light_shader_pos = cl->xform_cache[2]; if (cl->use_shadow) { - cl->shadows_next_ptr = lights_with_shadow; if (lights_with_shadow == nullptr) { shadow_rect = cl->xform_cache.xform(cl->rect_cache); @@ -209,17 +201,15 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: //make list of occluders for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { - RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas); Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { - - if (!F->get()->enabled) + if (!F->get()->enabled) { continue; + } F->get()->xform_cache = xf * F->get()->xform; if (shadow_rect.intersects_transformed(F->get()->xform_cache, F->get()->aabb_cache)) { - F->get()->next = occluders; occluders = F->get(); } @@ -229,7 +219,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: RasterizerCanvas::Light *light = lights_with_shadow; while (light) { - RENDER_TIMESTAMP("Render Shadow"); RSG::canvas_render->light_update_shadow(light->light_internal, light->xform_cache.affine_inverse(), light->item_shadow_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders); @@ -250,7 +239,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: } for (Map<Viewport::CanvasKey, Viewport::CanvasData *>::Element *E = canvas_map.front(); E; E = E->next()) { - RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get()->canvas); Transform2D xform = _canvas_get_transform(p_viewport, canvas, E->get(), clip_rect.size); @@ -304,7 +292,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: } void RenderingServerViewport::draw_viewports() { - timestamp_vp_map.clear(); // get our xr interface in case we need it @@ -335,8 +322,9 @@ void RenderingServerViewport::draw_viewports() { Viewport *vp = active_viewports[i]; - if (vp->update_mode == RS::VIEWPORT_UPDATE_DISABLED) + if (vp->update_mode == RS::VIEWPORT_UPDATE_DISABLED) { continue; + } if (!vp->render_target.is_valid()) { continue; @@ -368,7 +356,6 @@ void RenderingServerViewport::draw_viewports() { } for (int i = 0; i < active_viewports.size(); i++) { - Viewport *vp = active_viewports[i]; if (vp->last_pass != draw_viewports_pass) { @@ -470,7 +457,6 @@ void RenderingServerViewport::draw_viewports() { } RID RenderingServerViewport::viewport_create() { - Viewport *viewport = memnew(Viewport); RID rid = viewport_owner.make_rid(viewport); @@ -493,7 +479,6 @@ void RenderingServerViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) } void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) { - ERR_FAIL_COND(p_width < 0 && p_height < 0); Viewport *viewport = viewport_owner.getornull(p_viewport); @@ -512,7 +497,6 @@ void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int } void RenderingServerViewport::viewport_set_active(RID p_viewport, bool p_active) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -525,7 +509,6 @@ void RenderingServerViewport::viewport_set_active(RID p_viewport, bool p_active) } void RenderingServerViewport::viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -533,7 +516,6 @@ void RenderingServerViewport::viewport_set_parent_viewport(RID p_viewport, RID p } void RenderingServerViewport::viewport_set_clear_mode(RID p_viewport, RS::ViewportClearMode p_clear_mode) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -541,7 +523,6 @@ void RenderingServerViewport::viewport_set_clear_mode(RID p_viewport, RS::Viewpo } void RenderingServerViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect, DisplayServer::WindowID p_screen) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -549,7 +530,6 @@ void RenderingServerViewport::viewport_attach_to_screen(RID p_viewport, const Re // If using GLES2 we can optimize this operation by rendering directly to system_fbo // instead of rendering to fbo and copying to system_fbo after if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) { - RSG::storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y); RSG::storage->render_target_set_position(viewport->render_target, p_rect.position.x, p_rect.position.y); } @@ -557,10 +537,8 @@ void RenderingServerViewport::viewport_attach_to_screen(RID p_viewport, const Re viewport->viewport_to_screen_rect = p_rect; viewport->viewport_to_screen = p_screen; } else { - // if render_direct_to_screen was used, reset size and position if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) { - RSG::storage->render_target_set_position(viewport->render_target, 0, 0); RSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y); } @@ -574,12 +552,12 @@ void RenderingServerViewport::viewport_set_render_direct_to_screen(RID p_viewpor Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); - if (p_enable == viewport->viewport_render_direct_to_screen) + if (p_enable == viewport->viewport_render_direct_to_screen) { return; + } // if disabled, reset render_target size and position if (!p_enable) { - RSG::storage->render_target_set_position(viewport->render_target, 0, 0); RSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y); } @@ -589,14 +567,12 @@ void RenderingServerViewport::viewport_set_render_direct_to_screen(RID p_viewpor // if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unnecessary buffer allocation if (RSG::rasterizer->is_low_end() && viewport->viewport_to_screen_rect != Rect2() && p_enable) { - RSG::storage->render_target_set_size(viewport->render_target, viewport->viewport_to_screen_rect.size.x, viewport->viewport_to_screen_rect.size.y); RSG::storage->render_target_set_position(viewport->render_target, viewport->viewport_to_screen_rect.position.x, viewport->viewport_to_screen_rect.position.y); } } void RenderingServerViewport::viewport_set_update_mode(RID p_viewport, RS::ViewportUpdateMode p_mode) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -604,7 +580,6 @@ void RenderingServerViewport::viewport_set_update_mode(RID p_viewport, RS::Viewp } RID RenderingServerViewport::viewport_get_texture(RID p_viewport) const { - const Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND_V(!viewport, RID()); @@ -612,21 +587,20 @@ RID RenderingServerViewport::viewport_get_texture(RID p_viewport) const { } void RenderingServerViewport::viewport_set_hide_scenario(RID p_viewport, bool p_hide) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->hide_scenario = p_hide; } -void RenderingServerViewport::viewport_set_hide_canvas(RID p_viewport, bool p_hide) { +void RenderingServerViewport::viewport_set_hide_canvas(RID p_viewport, bool p_hide) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->hide_canvas = p_hide; } -void RenderingServerViewport::viewport_set_disable_environment(RID p_viewport, bool p_disable) { +void RenderingServerViewport::viewport_set_disable_environment(RID p_viewport, bool p_disable) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -634,21 +608,20 @@ void RenderingServerViewport::viewport_set_disable_environment(RID p_viewport, b } void RenderingServerViewport::viewport_attach_camera(RID p_viewport, RID p_camera) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->camera = p_camera; } -void RenderingServerViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) { +void RenderingServerViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->scenario = p_scenario; } -void RenderingServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) { +void RenderingServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -664,7 +637,6 @@ void RenderingServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canva } void RenderingServerViewport::viewport_remove_canvas(RID p_viewport, RID p_canvas) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -674,16 +646,16 @@ void RenderingServerViewport::viewport_remove_canvas(RID p_viewport, RID p_canva viewport->canvas_map.erase(p_canvas); canvas->viewports.erase(p_viewport); } -void RenderingServerViewport::viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) { +void RenderingServerViewport::viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); ERR_FAIL_COND(!viewport->canvas_map.has(p_canvas)); viewport->canvas_map[p_canvas].transform = p_offset; } -void RenderingServerViewport::viewport_set_transparent_background(RID p_viewport, bool p_enabled) { +void RenderingServerViewport::viewport_set_transparent_background(RID p_viewport, bool p_enabled) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -692,14 +664,13 @@ void RenderingServerViewport::viewport_set_transparent_background(RID p_viewport } void RenderingServerViewport::viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->global_transform = p_transform; } -void RenderingServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) { +void RenderingServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -709,7 +680,6 @@ void RenderingServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p } void RenderingServerViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -719,7 +689,6 @@ void RenderingServerViewport::viewport_set_shadow_atlas_size(RID p_viewport, int } void RenderingServerViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -727,7 +696,6 @@ void RenderingServerViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID } void RenderingServerViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -754,18 +722,17 @@ void RenderingServerViewport::viewport_set_screen_space_aa(RID p_viewport, RS::V } int RenderingServerViewport::viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfo p_info) { - ERR_FAIL_INDEX_V(p_info, RS::VIEWPORT_RENDER_INFO_MAX, -1); Viewport *viewport = viewport_owner.getornull(p_viewport); - if (!viewport) + if (!viewport) { return 0; //there should be a lock here.. + } return viewport->render_info[p_info]; } void RenderingServerViewport::viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -773,7 +740,6 @@ void RenderingServerViewport::viewport_set_debug_draw(RID p_viewport, RS::Viewpo } void RenderingServerViewport::viewport_set_measure_render_time(RID p_viewport, bool p_enable) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -781,7 +747,6 @@ void RenderingServerViewport::viewport_set_measure_render_time(RID p_viewport, b } float RenderingServerViewport::viewport_get_measured_render_time_cpu(RID p_viewport) const { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND_V(!viewport, 0); @@ -789,7 +754,6 @@ float RenderingServerViewport::viewport_get_measured_render_time_cpu(RID p_viewp } float RenderingServerViewport::viewport_get_measured_render_time_gpu(RID p_viewport) const { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND_V(!viewport, 0); @@ -797,9 +761,7 @@ float RenderingServerViewport::viewport_get_measured_render_time_gpu(RID p_viewp } bool RenderingServerViewport::free(RID p_rid) { - if (viewport_owner.owns(p_rid)) { - Viewport *viewport = viewport_owner.getornull(p_rid); RSG::storage->free(viewport->render_target); @@ -825,7 +787,6 @@ bool RenderingServerViewport::free(RID p_rid) { } void RenderingServerViewport::handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time) { - RID *vp = timestamp_vp_map.getptr(p_timestamp); if (!vp) { return; diff --git a/servers/rendering/rendering_server_viewport.h b/servers/rendering/rendering_server_viewport.h index fcba7886c5..0b90646e4f 100644 --- a/servers/rendering/rendering_server_viewport.h +++ b/servers/rendering/rendering_server_viewport.h @@ -43,7 +43,6 @@ public: }; struct Viewport { - RID self; RID parent; @@ -89,12 +88,12 @@ public: bool transparent_bg; struct CanvasKey { - int64_t stacking; RID canvas; bool operator<(const CanvasKey &p_canvas) const { - if (stacking == p_canvas.stacking) + if (stacking == p_canvas.stacking) { return canvas < p_canvas.canvas; + } return stacking < p_canvas.stacking; } CanvasKey() { @@ -109,7 +108,6 @@ public: }; struct CanvasData { - CanvasBase *canvas; Transform2D transform; int layer; @@ -154,12 +152,10 @@ public: struct ViewportSort { _FORCE_INLINE_ bool operator()(const Viewport *p_left, const Viewport *p_right) const { - bool left_to_screen = p_left->viewport_to_screen_rect.size != Size2(); bool right_to_screen = p_right->viewport_to_screen_rect.size != Size2(); if (left_to_screen == right_to_screen) { - return p_right->parent == p_left->self; } return (right_to_screen ? 0 : 1) < (left_to_screen ? 0 : 1); diff --git a/servers/rendering/rendering_server_wrap_mt.cpp b/servers/rendering/rendering_server_wrap_mt.cpp index 4ca13dbef9..9aa6593cbe 100644 --- a/servers/rendering/rendering_server_wrap_mt.cpp +++ b/servers/rendering/rendering_server_wrap_mt.cpp @@ -34,32 +34,26 @@ #include "servers/display_server.h" void RenderingServerWrapMT::thread_exit() { - exit = true; } void RenderingServerWrapMT::thread_draw(bool p_swap_buffers, double frame_step) { - if (!atomic_decrement(&draw_pending)) { - rendering_server->draw(p_swap_buffers, frame_step); } } void RenderingServerWrapMT::thread_flush() { - atomic_decrement(&draw_pending); } void RenderingServerWrapMT::_thread_callback(void *_instance) { - RenderingServerWrapMT *vsmt = reinterpret_cast<RenderingServerWrapMT *>(_instance); vsmt->thread_loop(); } void RenderingServerWrapMT::thread_loop() { - server_thread = Thread::get_caller_id(); DisplayServer::get_singleton()->make_rendering_thread(); @@ -81,33 +75,25 @@ void RenderingServerWrapMT::thread_loop() { /* EVENT QUEUING */ void RenderingServerWrapMT::sync() { - if (create_thread) { - atomic_increment(&draw_pending); command_queue.push_and_sync(this, &RenderingServerWrapMT::thread_flush); } else { - command_queue.flush_all(); //flush all pending from other threads } } void RenderingServerWrapMT::draw(bool p_swap_buffers, double frame_step) { - if (create_thread) { - atomic_increment(&draw_pending); command_queue.push(this, &RenderingServerWrapMT::thread_draw, p_swap_buffers, frame_step); } else { - rendering_server->draw(p_swap_buffers, frame_step); } } void RenderingServerWrapMT::init() { - if (create_thread) { - print_verbose("RenderingServerWrapMT: Creating render thread"); DisplayServer::get_singleton()->release_rendering_thread(); if (create_thread) { @@ -119,13 +105,11 @@ void RenderingServerWrapMT::init() { } print_verbose("RenderingServerWrapMT: Finished render thread"); } else { - rendering_server->init(); } } void RenderingServerWrapMT::finish() { - sky_free_cached_ids(); shader_free_cached_ids(); material_free_cached_ids(); @@ -138,7 +122,7 @@ void RenderingServerWrapMT::finish() { spot_light_free_cached_ids(); reflection_probe_free_cached_ids(); gi_probe_free_cached_ids(); - lightmap_capture_free_cached_ids(); + lightmap_free_cached_ids(); particles_free_cached_ids(); camera_free_cached_ids(); viewport_free_cached_ids(); @@ -152,7 +136,6 @@ void RenderingServerWrapMT::finish() { canvas_occluder_polygon_free_cached_ids(); if (thread) { - command_queue.push(this, &RenderingServerWrapMT::thread_exit); Thread::wait_to_finish(thread); memdelete(thread); @@ -164,7 +147,6 @@ void RenderingServerWrapMT::finish() { } void RenderingServerWrapMT::set_use_vsync_callback(bool p_enable) { - singleton_mt->call_set_use_vsync(p_enable); } @@ -172,7 +154,6 @@ RenderingServerWrapMT *RenderingServerWrapMT::singleton_mt = nullptr; RenderingServerWrapMT::RenderingServerWrapMT(RenderingServer *p_contained, bool p_create_thread) : command_queue(p_create_thread) { - singleton_mt = this; DisplayServer::switch_vsync_function = set_use_vsync_callback; //as this goes to another thread, make sure it goes properly @@ -191,7 +172,6 @@ RenderingServerWrapMT::RenderingServerWrapMT(RenderingServer *p_contained, bool } RenderingServerWrapMT::~RenderingServerWrapMT() { - memdelete(rendering_server); //finish(); } diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index d4e58485b8..a746aa52b2 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -36,7 +36,6 @@ #include "servers/rendering_server.h" class RenderingServerWrapMT : public RenderingServer { - // the real visual server mutable RenderingServer *rendering_server; @@ -92,7 +91,7 @@ public: //these also go pass-through virtual RID texture_2d_placeholder_create() { return rendering_server->texture_2d_placeholder_create(); } - virtual RID texture_2d_layered_placeholder_create() { return rendering_server->texture_2d_layered_placeholder_create(); } + virtual RID texture_2d_layered_placeholder_create(TextureLayeredType p_type) { return rendering_server->texture_2d_layered_placeholder_create(p_type); } virtual RID texture_3d_placeholder_create() { return rendering_server->texture_3d_placeholder_create(); } FUNC1RC(Ref<Image>, texture_2d_get, RID) @@ -324,19 +323,17 @@ public: /* LIGHTMAP CAPTURE */ - FUNCRID(lightmap_capture) - - FUNC2(lightmap_capture_set_bounds, RID, const AABB &) - FUNC1RC(AABB, lightmap_capture_get_bounds, RID) + FUNCRID(lightmap) + FUNC3(lightmap_set_textures, RID, RID, bool) + FUNC2(lightmap_set_probe_bounds, RID, const AABB &) + FUNC2(lightmap_set_probe_interior, RID, bool) + FUNC5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &) + FUNC1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID) + FUNC1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID) + FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID) + FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID) - FUNC2(lightmap_capture_set_octree, RID, const Vector<uint8_t> &) - FUNC1RC(Vector<uint8_t>, lightmap_capture_get_octree, RID) - FUNC2(lightmap_capture_set_octree_cell_transform, RID, const Transform &) - FUNC1RC(Transform, lightmap_capture_get_octree_cell_transform, RID) - FUNC2(lightmap_capture_set_octree_cell_subdiv, RID, int) - FUNC1RC(int, lightmap_capture_get_octree_cell_subdiv, RID) - FUNC2(lightmap_capture_set_energy, RID, float) - FUNC1RC(float, lightmap_capture_get_energy, RID) + FUNC1(lightmap_set_probe_capture_update_speed, float) /* PARTICLES */ @@ -442,6 +439,7 @@ public: FUNC2(sky_set_radiance_size, RID, int) FUNC2(sky_set_mode, RID, SkyMode) FUNC2(sky_set_material, RID, RID) + FUNC4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &) /* ENVIRONMENT API */ @@ -478,6 +476,8 @@ public: FUNC7(environment_set_fog_depth, RID, bool, float, float, float, bool, float) FUNC5(environment_set_fog_height, RID, bool, float, float, float) + FUNC3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) + FUNC2(screen_space_roughness_limiter_set_active, bool, float) FUNC1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality) FUNC2(sub_surface_scattering_set_scale, float, float) @@ -511,7 +511,6 @@ public: FUNC3(instance_set_blend_shape_weight, RID, int, float) FUNC3(instance_set_surface_material, RID, int, RID) FUNC2(instance_set_visible, RID, bool) - FUNC3(instance_set_use_lightmap, RID, RID, RID) FUNC2(instance_set_custom_aabb, RID, AABB) @@ -531,12 +530,17 @@ public: FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float) FUNC2(instance_geometry_set_as_instance_lod, RID, RID) + FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int) FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &) FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &) FUNC2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &) FUNC2SC(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *) + /* BAKE */ + + FUNC3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &) + /* CANVAS (2D) */ FUNCRID(canvas) diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 2a5492d93f..2ec65b7ea8 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -34,22 +34,18 @@ #include "servers/rendering_server.h" static bool _is_text_char(CharType c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; } static bool _is_number(CharType c) { - return (c >= '0' && c <= '9'); } static bool _is_hex(CharType c) { - return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); } String ShaderLanguage::get_operator_text(Operator p_op) { - static const char *op_names[OP_MAX] = { "==", "!=", "<", @@ -132,6 +128,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = { "TYPE_ISAMPLER3D", "TYPE_USAMPLER3D", "TYPE_SAMPLERCUBE", + "TYPE_SAMPLERCUBEARRAY", "INTERPOLATION_FLAT", "INTERPOLATION_SMOOTH", "CONST", @@ -225,7 +222,6 @@ const char *ShaderLanguage::token_names[TK_MAX] = { }; String ShaderLanguage::get_token_text(Token p_token) { - String name = token_names[p_token.type]; if (p_token.type == TK_INT_CONSTANT || p_token.type == TK_REAL_CONSTANT) { name += "(" + rtos(p_token.constant) + ")"; @@ -239,7 +235,6 @@ String ShaderLanguage::get_token_text(Token p_token) { } ShaderLanguage::Token ShaderLanguage::_make_token(TokenType p_type, const StringName &p_text) { - Token tk; tk.type = p_type; tk.text = p_text; @@ -283,6 +278,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = { { TK_TYPE_ISAMPLER3D, "isampler3D" }, { TK_TYPE_USAMPLER3D, "usampler3D" }, { TK_TYPE_SAMPLERCUBE, "samplerCube" }, + { TK_TYPE_SAMPLERCUBEARRAY, "samplerCubeArray" }, { TK_INTERPOLATION_FLAT, "flat" }, { TK_INTERPOLATION_SMOOTH, "smooth" }, { TK_CONST, "const" }, @@ -338,13 +334,11 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = { }; ShaderLanguage::Token ShaderLanguage::_get_token() { - #define GETCHAR(m_idx) (((char_idx + m_idx) < code.length()) ? code[char_idx + m_idx] : CharType(0)) while (true) { char_idx++; switch (GETCHAR(-1)) { - case 0: return _make_token(TK_EOF); case 0xFFFF: @@ -357,7 +351,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { tk_line++; continue; case '/': { - switch (GETCHAR(0)) { case '*': { // block comment @@ -405,7 +398,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { continue; //a comment, continue to next token } break; case '=': { - if (GETCHAR(0) == '=') { char_idx++; return _make_token(TK_OP_EQUAL); @@ -494,7 +486,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_OP_BIT_AND); } break; case '|': { - if (GETCHAR(0) == '=') { char_idx++; return _make_token(TK_OP_ASSIGN_BIT_OR); @@ -506,7 +497,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { } break; case '*': { - if (GETCHAR(0) == '=') { char_idx++; return _make_token(TK_OP_ASSIGN_MUL); @@ -514,12 +504,10 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_OP_MUL); } break; case '+': { - if (GETCHAR(0) == '=') { char_idx++; return _make_token(TK_OP_ASSIGN_ADD); } else if (GETCHAR(0) == '+') { - char_idx++; return _make_token(TK_OP_INCREMENT); } @@ -527,12 +515,10 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_OP_ADD); } break; case '-': { - if (GETCHAR(0) == '=') { char_idx++; return _make_token(TK_OP_ASSIGN_SUB); } else if (GETCHAR(0) == '-') { - char_idx++; return _make_token(TK_OP_DECREMENT); } @@ -540,7 +526,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_OP_SUB); } break; case '%': { - if (GETCHAR(0) == '=') { char_idx++; return _make_token(TK_OP_ASSIGN_MOD); @@ -549,7 +534,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_OP_MOD); } break; default: { - char_idx--; //go back one, since we have no idea what this is if (_is_number(GETCHAR(0)) || (GETCHAR(0) == '.' && _is_number(GETCHAR(1)))) { @@ -565,32 +549,38 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { while (true) { if (GETCHAR(i) == '.') { - if (period_found || exponent_found || hexa_found || float_suffix_found) + if (period_found || exponent_found || hexa_found || float_suffix_found) { return _make_token(TK_ERROR, "Invalid numeric constant"); + } period_found = true; } else if (GETCHAR(i) == 'x') { - if (hexa_found || str.length() != 1 || str[0] != '0') + if (hexa_found || str.length() != 1 || str[0] != '0') { return _make_token(TK_ERROR, "Invalid numeric constant"); + } hexa_found = true; } else if (GETCHAR(i) == 'e') { - if (hexa_found || exponent_found || float_suffix_found) + if (hexa_found || exponent_found || float_suffix_found) { return _make_token(TK_ERROR, "Invalid numeric constant"); + } exponent_found = true; } else if (GETCHAR(i) == 'f') { - if (hexa_found || exponent_found) + if (hexa_found || exponent_found) { return _make_token(TK_ERROR, "Invalid numeric constant"); + } float_suffix_found = true; } else if (_is_number(GETCHAR(i))) { - if (float_suffix_found) + if (float_suffix_found) { return _make_token(TK_ERROR, "Invalid numeric constant"); + } } else if (hexa_found && _is_hex(GETCHAR(i))) { - } else if ((GETCHAR(i) == '-' || GETCHAR(i) == '+') && exponent_found) { - if (sign_found) + if (sign_found) { return _make_token(TK_ERROR, "Invalid numeric constant"); + } sign_found = true; - } else + } else { break; + } str += CharType(GETCHAR(i)); i++; @@ -646,10 +636,11 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { char_idx += str.length(); Token tk; - if (period_found || exponent_found || float_suffix_found) + if (period_found || exponent_found || float_suffix_found) { tk.type = TK_REAL_CONSTANT; - else + } else { tk.type = TK_INT_CONSTANT; + } if (hexa_found) { tk.constant = (double)str.hex_to_int64(true); @@ -672,7 +663,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { String str; while (_is_text_char(GETCHAR(0))) { - str += CharType(GETCHAR(0)); char_idx++; } @@ -682,9 +672,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { int idx = 0; while (keyword_list[idx].text) { - if (str == keyword_list[idx].text) { - return _make_token(keyword_list[idx].token); } idx++; @@ -695,10 +683,11 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_IDENTIFIER, str); } - if (GETCHAR(0) > 32) + if (GETCHAR(0) > 32) { return _make_token(TK_ERROR, "Tokenizer: Unknown character #" + itos(GETCHAR(0)) + ": '" + String::chr(GETCHAR(0)) + "'"); - else + } else { return _make_token(TK_ERROR, "Tokenizer: Unknown character #" + itos(GETCHAR(0))); + } } break; } @@ -710,7 +699,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { } String ShaderLanguage::token_debug(const String &p_code) { - clear(); code = p_code; @@ -719,7 +707,6 @@ String ShaderLanguage::token_debug(const String &p_code) { Token tk = _get_token(); while (tk.type != TK_EOF && tk.type != TK_ERROR) { - output += itos(tk_line) + ": " + get_token_text(tk) + "\n"; tk = _get_token(); } @@ -752,7 +739,6 @@ bool ShaderLanguage::is_token_variable_datatype(TokenType p_type) { } bool ShaderLanguage::is_token_datatype(TokenType p_type) { - return ( p_type == TK_TYPE_VOID || p_type == TK_TYPE_BOOL || @@ -783,31 +769,29 @@ bool ShaderLanguage::is_token_datatype(TokenType p_type) { p_type == TK_TYPE_SAMPLER3D || p_type == TK_TYPE_ISAMPLER3D || p_type == TK_TYPE_USAMPLER3D || - p_type == TK_TYPE_SAMPLERCUBE); + p_type == TK_TYPE_SAMPLERCUBE || + p_type == TK_TYPE_SAMPLERCUBEARRAY); } ShaderLanguage::DataType ShaderLanguage::get_token_datatype(TokenType p_type) { - return DataType(p_type - TK_TYPE_VOID); } bool ShaderLanguage::is_token_interpolation(TokenType p_type) { - return ( p_type == TK_INTERPOLATION_FLAT || p_type == TK_INTERPOLATION_SMOOTH); } ShaderLanguage::DataInterpolation ShaderLanguage::get_token_interpolation(TokenType p_type) { - - if (p_type == TK_INTERPOLATION_FLAT) + if (p_type == TK_INTERPOLATION_FLAT) { return INTERPOLATION_FLAT; - else + } else { return INTERPOLATION_SMOOTH; + } } bool ShaderLanguage::is_token_precision(TokenType p_type) { - return ( p_type == TK_PRECISION_LOW || p_type == TK_PRECISION_MID || @@ -815,13 +799,13 @@ bool ShaderLanguage::is_token_precision(TokenType p_type) { } ShaderLanguage::DataPrecision ShaderLanguage::get_token_precision(TokenType p_type) { - - if (p_type == TK_PRECISION_LOW) + if (p_type == TK_PRECISION_LOW) { return PRECISION_LOWP; - else if (p_type == TK_PRECISION_HIGH) + } else if (p_type == TK_PRECISION_HIGH) { return PRECISION_HIGHP; - else + } else { return PRECISION_MEDIUMP; + } } String ShaderLanguage::get_precision_name(DataPrecision p_type) { @@ -839,9 +823,7 @@ String ShaderLanguage::get_precision_name(DataPrecision p_type) { } String ShaderLanguage::get_datatype_name(DataType p_type) { - switch (p_type) { - case TYPE_VOID: return "void"; case TYPE_BOOL: @@ -902,6 +884,8 @@ String ShaderLanguage::get_datatype_name(DataType p_type) { return "usampler3D"; case TYPE_SAMPLERCUBE: return "samplerCube"; + case TYPE_SAMPLERCUBEARRAY: + return "samplerCubeArray"; case TYPE_STRUCT: return "struct"; case TYPE_MAX: @@ -912,12 +896,10 @@ String ShaderLanguage::get_datatype_name(DataType p_type) { } bool ShaderLanguage::is_token_nonvoid_datatype(TokenType p_type) { - return is_token_datatype(p_type) && p_type != TK_TYPE_VOID; } void ShaderLanguage::clear() { - current_function = StringName(); completion_type = COMPLETION_NONE; @@ -939,9 +921,7 @@ void ShaderLanguage::clear() { } bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size, StringName *r_struct_name) { - if (p_builtin_types.has(p_identifier)) { - if (r_data_type) { *r_data_type = p_builtin_types[p_identifier].type; } @@ -958,7 +938,6 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea FunctionNode *function = nullptr; while (p_block) { - if (p_block->variables.has(p_identifier)) { if (r_data_type) { *r_data_type = p_block->variables[p_identifier].type; @@ -1045,9 +1024,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea } for (int i = 0; i < shader->functions.size(); i++) { - - if (!shader->functions[i].callable) + if (!shader->functions[i].callable) { continue; + } if (shader->functions[i].name == p_identifier) { if (r_data_type) { @@ -1064,7 +1043,6 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea } bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type) { - bool valid = false; DataType ret_type = TYPE_VOID; @@ -1097,7 +1075,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type } break; case OP_NOT: { - DataType na = p_op->arguments[0]->get_datatype(); valid = na == TYPE_BOOL; ret_type = TYPE_BOOL; @@ -1236,7 +1213,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type case OP_ASSIGN_SHIFT_RIGHT: case OP_SHIFT_LEFT: case OP_SHIFT_RIGHT: { - DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1298,7 +1274,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type case OP_ASSIGN_SUB: case OP_ASSIGN_MUL: case OP_ASSIGN_DIV: { - DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1358,7 +1333,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type case OP_BIT_AND: case OP_BIT_OR: case OP_BIT_XOR: { - /* * The bitwise operators and (&), exclusive-or (^), and inclusive-or (|). The operands must be of type * signed or unsigned integers or integer vectors. The operands cannot be vectors of differing size. If @@ -1438,8 +1412,9 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type } } - if (r_ret_type) + if (r_ret_type) { *r_ret_type = ret_type; + } return valid; } @@ -2046,6 +2021,7 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER3D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true }, { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER3D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true }, { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true }, + { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBEARRAY, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true }, { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false }, { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false }, @@ -2067,6 +2043,8 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true }, { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false }, { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false }, + { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false }, + { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false }, { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true }, { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true }, @@ -2097,6 +2075,7 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true }, { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true }, { "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false }, + { "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false }, { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true }, { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true }, @@ -2128,6 +2107,7 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true }, { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true }, { "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true }, + { "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true }, { "dFdx", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true }, { "dFdx", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true }, @@ -2160,7 +2140,6 @@ const ShaderLanguage::BuiltinFuncOutArgs ShaderLanguage::builtin_func_out_args[] }; bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str) { - ERR_FAIL_COND_V(p_func->op != OP_CALL && p_func->op != OP_CONSTRUCT, false); Vector<DataType> args; @@ -2186,18 +2165,15 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin int idx = 0; while (builtin_func_defs[idx].name) { - if (completion_class != builtin_func_defs[idx].tag) { idx++; continue; } if (name == builtin_func_defs[idx].name) { - failed_builtin = true; bool fail = false; for (int i = 0; i < argcount; i++) { - if (get_scalar_type(args[i]) == args[i] && p_func->arguments[i + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[i + 1]), builtin_func_defs[idx].args[i])) { //all good, but needs implicit conversion later } else if (args[i] != builtin_func_defs[idx].args[i]) { @@ -2216,20 +2192,18 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin } } - if (!fail && argcount < 4 && builtin_func_defs[idx].args[argcount] != TYPE_VOID) + if (!fail && argcount < 4 && builtin_func_defs[idx].args[argcount] != TYPE_VOID) { fail = true; //make sure the number of arguments matches + } if (!fail) { - //make sure its not an out argument used in the wrong way int outarg_idx = 0; while (builtin_func_out_args[outarg_idx].name) { - if (String(name) == builtin_func_out_args[outarg_idx].name) { int arg_idx = builtin_func_out_args[outarg_idx].argument; if (arg_idx < argcount) { - if (p_func->arguments[arg_idx + 1]->type != Node::TYPE_VARIABLE && p_func->arguments[arg_idx + 1]->type != Node::TYPE_MEMBER && p_func->arguments[arg_idx + 1]->type != Node::TYPE_ARRAY) { _set_error("Argument " + itos(arg_idx + 1) + " of function '" + String(name) + "' is not a variable, array or member."); return false; @@ -2317,7 +2291,6 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin } //implicitly convert values if possible for (int i = 0; i < argcount; i++) { - if (get_scalar_type(args[i]) != args[i] || args[i] == builtin_func_defs[idx].args[i] || p_func->arguments[i + 1]->type != Node::TYPE_CONSTANT) { //can't do implicit conversion here continue; @@ -2334,8 +2307,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin p_func->arguments.write[i + 1] = conversion; } - if (r_ret_type) + if (r_ret_type) { *r_ret_type = builtin_func_defs[idx].rettype; + } return true; } @@ -2346,7 +2320,6 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin } if (unsupported_builtin) { - String arglist = ""; for (int i = 0; i < argcount; i++) { if (i > 0) { @@ -2363,8 +2336,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin if (failed_builtin) { String err = "Invalid arguments for built-in function: " + String(name) + "("; for (int i = 0; i < argcount; i++) { - if (i > 0) + if (i > 0) { err += ","; + } if (p_func->arguments[i + 1]->type == Node::TYPE_CONSTANT && p_func->arguments[i + 1]->get_datatype() == TYPE_INT && static_cast<ConstantNode *>(p_func->arguments[i + 1])->values[0].sint < 0) { err += "-"; @@ -2382,7 +2356,6 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin BlockNode *block = p_block; while (block) { - if (block->parent_function) { exclude_function = block->parent_function->name; } @@ -2395,9 +2368,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin } for (int i = 0; i < shader->functions.size(); i++) { - - if (name != shader->functions[i].name) + if (name != shader->functions[i].name) { continue; + } if (!shader->functions[i].callable) { _set_error("Function '" + String(name) + " can't be called from source code."); @@ -2406,8 +2379,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin FunctionNode *pfunc = shader->functions[i].function; - if (pfunc->arguments.size() != args.size()) + if (pfunc->arguments.size() != args.size()) { continue; + } bool fail = false; @@ -2425,10 +2399,8 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin } if (!fail) { - //implicitly convert values if possible for (int k = 0; k < args.size(); k++) { - if (get_scalar_type(args[k]) != args[k] || args[k] == pfunc->arguments[k].type || p_func->arguments[k + 1]->type != Node::TYPE_CONSTANT) { //can't do implicit conversion here continue; @@ -2472,7 +2444,6 @@ bool ShaderLanguage::_compare_datatypes_in_nodes(Node *a, Node *b) const { } bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg) { - TkPos pos = _get_tkpos(); Token tk = _get_token(); @@ -2483,16 +2454,13 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<Str _set_tkpos(pos); while (true) { - if (r_complete_arg) { pos = _get_tkpos(); tk = _get_token(); if (tk.type == TK_CURSOR) { - *r_complete_arg = p_func->arguments.size() - 1; } else { - _set_tkpos(pos); } } @@ -2500,7 +2468,6 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<Str Node *arg = _parse_and_reduce_expression(p_block, p_builtin_types); if (!arg) { - return false; } @@ -2509,7 +2476,6 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<Str tk = _get_token(); if (tk.type == TK_PARENTHESIS_CLOSE) { - return true; } else if (tk.type != TK_COMMA) { // something is broken @@ -2522,7 +2488,6 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<Str } bool ShaderLanguage::is_token_operator(TokenType p_type) { - return (p_type == TK_OP_EQUAL || p_type == TK_OP_NOT_EQUAL || p_type == TK_OP_LESS || @@ -2561,7 +2526,6 @@ bool ShaderLanguage::is_token_operator(TokenType p_type) { } bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_type, ConstantNode::Value *p_value) { - if (p_constant->datatype == p_to_type) { if (p_value) { for (int i = 0; i < p_constant->values.size(); i++) { @@ -2570,13 +2534,11 @@ bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_ty } return true; } else if (p_constant->datatype == TYPE_INT && p_to_type == TYPE_FLOAT) { - if (p_value) { p_value->real = p_constant->values[0].sint; } return true; } else if (p_constant->datatype == TYPE_UINT && p_to_type == TYPE_FLOAT) { - if (p_value) { p_value->real = p_constant->values[0].uint; } @@ -2590,7 +2552,6 @@ bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_ty } return true; } else if (p_constant->datatype == TYPE_UINT && p_to_type == TYPE_INT) { - if (p_constant->values[0].uint > 0x7FFFFFFF) { return false; } @@ -2598,17 +2559,16 @@ bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_ty p_value->sint = p_constant->values[0].uint; } return true; - } else + } else { return false; + } } bool ShaderLanguage::is_scalar_type(DataType p_type) { - return p_type == TYPE_BOOL || p_type == TYPE_INT || p_type == TYPE_UINT || p_type == TYPE_FLOAT; } bool ShaderLanguage::is_sampler_type(DataType p_type) { - return p_type == TYPE_SAMPLER2D || p_type == TYPE_ISAMPLER2D || p_type == TYPE_USAMPLER2D || @@ -2618,7 +2578,8 @@ bool ShaderLanguage::is_sampler_type(DataType p_type) { p_type == TYPE_SAMPLER3D || p_type == TYPE_ISAMPLER3D || p_type == TYPE_USAMPLER3D || - p_type == TYPE_SAMPLERCUBE; + p_type == TYPE_SAMPLERCUBE || + p_type == TYPE_SAMPLERCUBEARRAY; } Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, ShaderLanguage::ShaderNode::Uniform::Hint p_hint) { @@ -2712,7 +2673,8 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C case ShaderLanguage::TYPE_USAMPLER2DARRAY: case ShaderLanguage::TYPE_USAMPLER2D: case ShaderLanguage::TYPE_USAMPLER3D: - case ShaderLanguage::TYPE_SAMPLERCUBE: { + case ShaderLanguage::TYPE_SAMPLERCUBE: + case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: { // Texture types, likely not relevant here. break; } @@ -2767,7 +2729,6 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform case ShaderLanguage::TYPE_UVEC2: case ShaderLanguage::TYPE_UVEC3: case ShaderLanguage::TYPE_UVEC4: { - pi.type = Variant::PACKED_INT32_ARRAY; } break; case ShaderLanguage::TYPE_FLOAT: { @@ -2803,7 +2764,6 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform case ShaderLanguage::TYPE_SAMPLER2D: case ShaderLanguage::TYPE_ISAMPLER2D: case ShaderLanguage::TYPE_USAMPLER2D: { - pi.type = Variant::OBJECT; pi.hint = PROPERTY_HINT_RESOURCE_TYPE; pi.hint_string = "Texture2D"; @@ -2811,10 +2771,9 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform case ShaderLanguage::TYPE_SAMPLER2DARRAY: case ShaderLanguage::TYPE_ISAMPLER2DARRAY: case ShaderLanguage::TYPE_USAMPLER2DARRAY: { - pi.type = Variant::OBJECT; pi.hint = PROPERTY_HINT_RESOURCE_TYPE; - pi.hint_string = "TextureArray"; + pi.hint_string = "TextureLayered"; } break; case ShaderLanguage::TYPE_SAMPLER3D: case ShaderLanguage::TYPE_ISAMPLER3D: @@ -2823,11 +2782,11 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform pi.hint = PROPERTY_HINT_RESOURCE_TYPE; pi.hint_string = "Texture3D"; } break; - case ShaderLanguage::TYPE_SAMPLERCUBE: { - + case ShaderLanguage::TYPE_SAMPLERCUBE: + case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: { pi.type = Variant::OBJECT; pi.hint = PROPERTY_HINT_RESOURCE_TYPE; - pi.hint_string = "CubeMap"; + pi.hint_string = "TextureLayered"; } break; case ShaderLanguage::TYPE_STRUCT: { // FIXME: Implement this. @@ -2878,6 +2837,7 @@ uint32_t ShaderLanguage::get_type_size(DataType p_type) { case TYPE_ISAMPLER3D: case TYPE_USAMPLER3D: case TYPE_SAMPLERCUBE: + case TYPE_SAMPLERCUBEARRAY: return 4; //not really, but useful for indices case TYPE_STRUCT: // FIXME: Implement. @@ -2889,13 +2849,11 @@ uint32_t ShaderLanguage::get_type_size(DataType p_type) { } void ShaderLanguage::get_keyword_list(List<String> *r_keywords) { - Set<String> kws; int idx = 0; while (keyword_list[idx].text) { - kws.insert(keyword_list[idx].text); idx++; } @@ -2903,7 +2861,6 @@ void ShaderLanguage::get_keyword_list(List<String> *r_keywords) { idx = 0; while (builtin_func_defs[idx].name) { - kws.insert(builtin_func_defs[idx].name); idx++; @@ -2915,13 +2872,11 @@ void ShaderLanguage::get_keyword_list(List<String> *r_keywords) { } void ShaderLanguage::get_builtin_funcs(List<String> *r_keywords) { - Set<String> kws; int idx = 0; while (builtin_func_defs[idx].name) { - kws.insert(builtin_func_defs[idx].name); idx++; @@ -2933,7 +2888,6 @@ void ShaderLanguage::get_builtin_funcs(List<String> *r_keywords) { } ShaderLanguage::DataType ShaderLanguage::get_scalar_type(DataType p_type) { - static const DataType scalar_types[] = { TYPE_VOID, TYPE_BOOL, @@ -2996,7 +2950,6 @@ int ShaderLanguage::get_cardinality(DataType p_type) { } bool ShaderLanguage::_get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier) { - identifier = StringName(); TkPos pos = { 0, 0 }; @@ -3010,7 +2963,6 @@ bool ShaderLanguage::_get_completable_identifier(BlockNode *p_block, CompletionT } if (tk.type == TK_CURSOR) { - completion_type = p_type; completion_line = tk_line; completion_block = p_block; @@ -3053,9 +3005,7 @@ bool ShaderLanguage::_is_operator_assign(Operator p_op) const { } bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message) { - if (p_node->type == Node::TYPE_OPERATOR) { - OperatorNode *op = static_cast<OperatorNode *>(p_node); if (op->op == OP_INDEX) { @@ -3066,42 +3016,45 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI return _validate_assign(op->arguments[1], p_builtin_types, r_message); } else if (op->op == OP_CALL) { - if (r_message) + if (r_message) { *r_message = RTR("Assignment to function."); + } return false; } } else if (p_node->type == Node::TYPE_MEMBER) { - MemberNode *member = static_cast<MemberNode *>(p_node); if (member->has_swizzling_duplicates) { - if (r_message) + if (r_message) { *r_message = RTR("Swizzling assignment contains duplicates."); + } return false; } return _validate_assign(member->owner, p_builtin_types, r_message); } else if (p_node->type == Node::TYPE_VARIABLE) { - VariableNode *var = static_cast<VariableNode *>(p_node); if (shader->uniforms.has(var->name)) { - if (r_message) + if (r_message) { *r_message = RTR("Assignment to uniform."); + } return false; } if (shader->varyings.has(var->name) && current_function != String("vertex")) { - if (r_message) + if (r_message) { *r_message = RTR("Varyings can only be assigned in vertex function."); + } return false; } if (shader->constants.has(var->name) || var->is_const) { - if (r_message) + if (r_message) { *r_message = RTR("Constants cannot be modified."); + } return false; } @@ -3109,33 +3062,34 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI return true; } } else if (p_node->type == Node::TYPE_ARRAY) { - ArrayNode *arr = static_cast<ArrayNode *>(p_node); if (arr->is_const) { - if (r_message) + if (r_message) { *r_message = RTR("Constants cannot be modified."); + } return false; } if (shader->varyings.has(arr->name) && current_function != String("vertex")) { - if (r_message) + if (r_message) { *r_message = RTR("Varyings can only be assigned in vertex function."); + } return false; } return true; } - if (r_message) + if (r_message) { *r_message = "Assignment to constant expression."; + } return false; } bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringName p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat) { for (int i = 0; shader->functions.size(); i++) { if (shader->functions[i].name == p_name) { - ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false); FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument]; if (arg->tex_builtin_check) { @@ -3146,12 +3100,10 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringNam if (arg->tex_argument_filter == p_filter && arg->tex_argument_repeat == p_repeat) { return true; } else { - _set_error("Sampler argument #" + itos(p_argument) + " of function '" + String(p_name) + "' called more than once using textures that differ in either filter or repeat setting."); return false; } } else { - arg->tex_argument_check = true; arg->tex_argument_filter = p_filter; arg->tex_argument_repeat = p_repeat; @@ -3168,10 +3120,10 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringNam } ERR_FAIL_V(false); //bug? function not found } + bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin) { for (int i = 0; shader->functions.size(); i++) { if (shader->functions[i].name == p_name) { - ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false); FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument]; if (arg->tex_argument_check) { @@ -3186,7 +3138,6 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa return false; } } else { - arg->tex_builtin_check = true; arg->tex_builtin = p_builtin; @@ -3205,13 +3156,11 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa } ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types) { - Vector<Expression> expression; //Vector<TokenType> operators; while (true) { - Node *expr = nullptr; TkPos prepos = _get_tkpos(); Token tk = _get_token(); @@ -3223,19 +3172,18 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons //handle subexpression expr = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!expr) + if (!expr) { return nullptr; + } tk = _get_token(); if (tk.type != TK_PARENTHESIS_CLOSE) { - _set_error("Expected ')' in expression"); return nullptr; } } else if (tk.type == TK_REAL_CONSTANT) { - ConstantNode *constant = alloc_node<ConstantNode>(); ConstantNode::Value v; v.real = tk.constant; @@ -3244,7 +3192,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = constant; } else if (tk.type == TK_INT_CONSTANT) { - ConstantNode *constant = alloc_node<ConstantNode>(); ConstantNode::Value v; v.sint = tk.constant; @@ -3253,7 +3200,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = constant; } else if (tk.type == TK_TRUE) { - //handle true constant ConstantNode *constant = alloc_node<ConstantNode>(); ConstantNode::Value v; @@ -3263,7 +3209,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = constant; } else if (tk.type == TK_FALSE) { - //handle false constant ConstantNode *constant = alloc_node<ConstantNode>(); ConstantNode::Value v; @@ -3273,7 +3218,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = constant; } else if (tk.type == TK_TYPE_VOID) { - //make sure void is not used in expression _set_error("Void value not allowed in Expression"); return nullptr; @@ -3284,7 +3228,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons func->op = OP_CONSTRUCT; if (is_token_precision(tk.type)) { - func->return_precision_cache = get_token_precision(tk.type); tk = _get_token(); } @@ -3311,8 +3254,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons completion_argument = carg; } - if (!ok) + if (!ok) { return nullptr; + } if (!_validate_function_call(p_block, p_builtin_types, func, &func->return_cache, &func->struct_name)) { _set_error("No matching constructor found for: '" + String(funcname->name) + "'"); @@ -3322,7 +3266,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = _reduce_expression(p_block, func); } else if (tk.type == TK_IDENTIFIER) { - _set_tkpos(prepos); StringName identifier; @@ -3339,7 +3282,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons tk = _get_token(); if (tk.type == TK_PARENTHESIS_OPEN) { - if (struct_init) { //a struct constructor const StringName &name = identifier; @@ -3356,7 +3298,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons Node *nexpr; if (pstruct->members[i]->array_size != 0) { - DataType type = pstruct->members[i]->get_datatype(); String struct_name = pstruct->members[i]->struct_name; int array_size = pstruct->members[i]->array_size; @@ -3372,7 +3313,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (tk.type == TK_CURLY_BRACKET_OPEN) { auto_size = true; } else { - if (shader->structs.has(tk.text)) { type2 = TYPE_STRUCT; struct_name2 = tk.text; @@ -3455,7 +3395,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization while (true) { - Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); if (!n) { return nullptr; @@ -3477,10 +3416,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons an->initializer.push_back(n); break; } else { - if (auto_size) + if (auto_size) { _set_error("Expected '}' or ','"); - else + } else { _set_error("Expected ')' or ','"); + } return nullptr; } } @@ -3575,8 +3515,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons completion_argument = carg; } - if (!ok) + if (!ok) { return nullptr; + } if (!_validate_function_call(p_block, p_builtin_types, func, &func->return_cache, &func->struct_name)) { _set_error("No matching function found for: '" + String(funcname->name) + "'"); @@ -3589,14 +3530,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons FunctionNode *call_function = shader->functions[function_index].function; if (call_function) { - //get current base function FunctionNode *base_function = nullptr; { BlockNode *b = p_block; while (b) { - if (b->parent_function) { base_function = b->parent_function; break; @@ -3718,7 +3657,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons return nullptr; } } else { - if (!_find_identifier(p_block, false, p_builtin_types, identifier, &data_type, &ident_type, &is_const, &array_size, &struct_name)) { _set_error("Unknown identifier in expression: " + String(identifier)); return nullptr; @@ -3746,14 +3684,16 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons p_block->block_tag = SubClassTag::TAG_ARRAY; call_expression = _parse_and_reduce_expression(p_block, p_builtin_types); p_block->block_tag = SubClassTag::TAG_GLOBAL; - if (!call_expression) + if (!call_expression) { return nullptr; + } data_type = call_expression->get_datatype(); } else { // indexing index_expression = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!index_expression) + if (!index_expression) { return nullptr; + } if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) { _set_error("Only integer expressions are allowed for indexing"); @@ -3790,7 +3730,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = arrname; } else { - VariableNode *varname = alloc_node<VariableNode>(); varname->name = identifier; varname->datatype_cache = data_type; @@ -3802,7 +3741,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } else if (tk.type == TK_OP_ADD) { continue; //this one does nothing } else if (tk.type == TK_OP_SUB || tk.type == TK_OP_NOT || tk.type == TK_OP_BIT_INVERT || tk.type == TK_OP_INCREMENT || tk.type == TK_OP_DECREMENT) { - Expression e; e.is_op = true; @@ -3847,9 +3785,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (tk.type == TK_CURSOR) { //do nothing } else if (tk.type == TK_IDENTIFIER) { - } else if (tk.type == TK_PERIOD) { - DataType dt = expr->get_datatype(); String st = expr->get_datatype_name(); @@ -3904,7 +3840,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons case TYPE_IVEC2: case TYPE_UVEC2: case TYPE_VEC2: { - int l = ident.length(); if (l == 1) { member_type = DataType(dt - 1); @@ -3921,7 +3856,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons const CharType *c = ident.ptr(); for (int i = 0; i < l; i++) { - switch (c[i]) { case 'r': case 'g': @@ -3970,7 +3904,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons case TYPE_IVEC3: case TYPE_UVEC3: case TYPE_VEC3: { - int l = ident.length(); if (l == 1) { member_type = DataType(dt - 2); @@ -3987,7 +3920,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons const CharType *c = ident.ptr(); for (int i = 0; i < l; i++) { - switch (c[i]) { case 'r': case 'g': @@ -4039,7 +3971,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons case TYPE_IVEC4: case TYPE_UVEC4: case TYPE_VEC4: { - int l = ident.length(); if (l == 1) { member_type = DataType(dt - 3); @@ -4056,7 +3987,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons const CharType *c = ident.ptr(); for (int i = 0; i < l; i++) { - switch (c[i]) { case 'r': case 'g': @@ -4135,16 +4065,15 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons mn->has_swizzling_duplicates = repeated; if (array_size > 0) { - tk = _get_token(); if (tk.type == TK_PERIOD) { _set_error("Nested array length() is not yet implemented"); return nullptr; } else if (tk.type == TK_BRACKET_OPEN) { - Node *index_expression = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!index_expression) + if (!index_expression) { return nullptr; + } if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) { _set_error("Only integer expressions are allowed for indexing"); @@ -4190,10 +4119,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons */ } else if (tk.type == TK_BRACKET_OPEN) { - Node *index = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!index) + if (!index) { return nullptr; + } if (index->get_datatype() != TYPE_INT && index->get_datatype() != TYPE_UINT) { _set_error("Only integer datatypes are allowed for indexing"); @@ -4323,7 +4252,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } } else if (tk.type == TK_OP_INCREMENT || tk.type == TK_OP_DECREMENT) { - OperatorNode *op = alloc_node<OperatorNode>(); op->op = tk.type == TK_OP_DECREMENT ? OP_POST_DECREMENT : OP_POST_INCREMENT; op->arguments.push_back(expr); @@ -4339,7 +4267,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } expr = op; } else { - _set_tkpos(pos2); break; } @@ -4354,12 +4281,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons tk = _get_token(); if (is_token_operator(tk.type)) { - Expression o; o.is_op = true; switch (tk.type) { - case TK_OP_EQUAL: o.op = OP_EQUAL; break; @@ -4470,16 +4395,13 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons /* Reduce the set set of expressions and place them in an operator tree, respecting precedence */ while (expression.size() > 1) { - int next_op = -1; int min_priority = 0xFFFFF; bool is_unary = false; bool is_ternary = false; for (int i = 0; i < expression.size(); i++) { - if (!expression[i].is_op) { - continue; } @@ -4623,10 +4545,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons // OK! create operator.. // OK! create operator.. if (is_unary) { - int expr_pos = next_op; while (expression[expr_pos].is_op) { - expr_pos++; if (expr_pos == expression.size()) { //can happen.. @@ -4637,11 +4557,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons //consecutively do unary operators for (int i = expr_pos - 1; i >= next_op; i--) { - OperatorNode *op = alloc_node<OperatorNode>(); op->op = expression[i].op; if ((op->op == OP_INCREMENT || op->op == OP_DECREMENT) && !_validate_assign(expression[i + 1].node, p_builtin_types)) { - _set_error("Can't use increment/decrement operator in constant expression."); return nullptr; } @@ -4651,11 +4569,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expression.write[i].node = op; if (!_validate_operator(op, &op->return_cache)) { - String at; for (int j = 0; j < op->arguments.size(); j++) { - if (j > 0) + if (j > 0) { at += " and "; + } at += get_datatype_name(op->arguments[j]->get_datatype()); } _set_error("Invalid arguments to unary operator '" + get_operator_text(op->op) + "' :" + at); @@ -4665,7 +4583,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } } else if (is_ternary) { - if (next_op < 1 || next_op >= (expression.size() - 1)) { _set_error("Parser bug..."); ERR_FAIL_V(nullptr); @@ -4685,11 +4602,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expression.write[next_op - 1].is_op = false; expression.write[next_op - 1].node = op; if (!_validate_operator(op, &op->return_cache)) { - String at; for (int i = 0; i < op->arguments.size(); i++) { - if (i > 0) + if (i > 0) { at += " and "; + } at += get_datatype_name(op->arguments[i]->get_datatype()); } _set_error("Invalid argument to ternary ?: operator: " + at); @@ -4701,7 +4618,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } } else { - if (next_op < 1 || next_op >= (expression.size() - 1)) { _set_error("Parser bug..."); ERR_FAIL_V(nullptr); @@ -4711,16 +4627,13 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons op->op = expression[next_op].op; if (expression[next_op - 1].is_op) { - _set_error("Parser bug..."); ERR_FAIL_V(nullptr); } if (_is_operator_assign(op->op)) { - String assign_message; if (!_validate_assign(expression[next_op - 1].node, p_builtin_types, &assign_message)) { - _set_error(assign_message); return nullptr; } @@ -4742,11 +4655,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons //replace all 3 nodes by this operator and make it an expression if (!_validate_operator(op, &op->return_cache)) { - String at; for (int i = 0; i < op->arguments.size(); i++) { - if (i > 0) + if (i > 0) { at += " and "; + } if (op->arguments[i]->get_datatype() == TYPE_STRUCT) { at += op->arguments[i]->get_datatype_name(); } else { @@ -4766,15 +4679,14 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node) { - - if (p_node->type != Node::TYPE_OPERATOR) + if (p_node->type != Node::TYPE_OPERATOR) { return p_node; + } //for now only reduce simple constructors OperatorNode *op = static_cast<OperatorNode *>(p_node); if (op->op == OP_CONSTRUCT) { - ERR_FAIL_COND_V(op->arguments[0]->type != Node::TYPE_VARIABLE, p_node); DataType type = op->get_datatype(); @@ -4784,7 +4696,6 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha Vector<ConstantNode::Value> values; for (int i = 1; i < op->arguments.size(); i++) { - op->arguments.write[i] = _reduce_expression(p_block, op->arguments[i]); if (op->arguments[i]->type == Node::TYPE_CONSTANT) { ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[i]); @@ -4794,7 +4705,6 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha values.push_back(cn->values[j]); } } else if (get_scalar_type(cn->datatype) == cn->datatype) { - ConstantNode::Value v; if (!convert_constant(cn, base, &v)) { return p_node; @@ -4838,10 +4748,8 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha cn->values = values; return cn; } else if (op->op == OP_NEGATE) { - op->arguments.write[0] = _reduce_expression(p_block, op->arguments[0]); if (op->arguments[0]->type == Node::TYPE_CONSTANT) { - ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[0]); DataType base = get_scalar_type(cn->datatype); @@ -4849,7 +4757,6 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha Vector<ConstantNode::Value> values; for (int i = 0; i < cn->values.size(); i++) { - ConstantNode::Value nv; switch (base) { case TYPE_BOOL: { @@ -4881,10 +4788,10 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha } ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types) { - ShaderLanguage::Node *expr = _parse_expression(p_block, p_builtin_types); - if (!expr) //errored + if (!expr) { //errored return nullptr; + } expr = _reduce_expression(p_block, expr); @@ -4892,9 +4799,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_ } Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one, bool p_can_break, bool p_can_continue) { - while (true) { - TkPos pos = _get_tkpos(); Token tk = _get_token(); @@ -4970,7 +4875,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui Node *vardecl = nullptr; while (true) { - if (tk.type != TK_IDENTIFIER) { _set_error("Expected identifier after type"); return ERR_PARSE_ERROR; @@ -5023,7 +4927,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui if (tk.type == TK_BRACKET_CLOSE) { unknown_size = true; } else { - if (tk.type != TK_INT_CONSTANT || ((int)tk.constant) <= 0) { _set_error("Expected integer constant > 0 or ']'"); return ERR_PARSE_ERROR; @@ -5043,7 +4946,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui tk = _get_token(); if (tk.type == TK_OP_ASSIGN) { - if (RenderingServer::get_singleton()->is_low_end()) { _set_error("Array initialization is supported only on high-end platform!"); return ERR_PARSE_ERROR; @@ -5052,7 +4954,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui tk = _get_token(); if (tk.type != TK_CURLY_BRACKET_OPEN) { - if (unknown_size) { _set_error("Expected '{'"); return ERR_PARSE_ERROR; @@ -5181,7 +5082,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization while (true) { - Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); if (!n) { return ERR_PARSE_ERROR; @@ -5208,10 +5108,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui decl.initializer.push_back(n); break; } else { - if (curly) + if (curly) { _set_error("Expected '}' or ','"); - else + } else { _set_error("Expected ')' or ','"); + } return ERR_PARSE_ERROR; } } @@ -5237,7 +5138,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui node->declarations.push_back(decl); } else if (tk.type == TK_OP_ASSIGN) { - VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>(); if (is_struct) { node->struct_name = struct_name; @@ -5255,8 +5155,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui //variable created with assignment! must parse an expression Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!n) + if (!n) { return ERR_PARSE_ERROR; + } if (node->is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) { _set_error("Expected constant expression after '='"); return ERR_PARSE_ERROR; @@ -5328,8 +5229,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui ControlFlowNode *cf = alloc_node<ControlFlowNode>(); cf->flow_op = FLOW_OP_IF; Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!n) + if (!n) { return ERR_PARSE_ERROR; + } if (n->get_datatype() != TYPE_BOOL) { _set_error("Expected boolean expression"); @@ -5349,13 +5251,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui p_block->statements.push_back(cf); Error err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue); - if (err) + if (err) { return err; + } pos = _get_tkpos(); tk = _get_token(); if (tk.type == TK_CF_ELSE) { - block = alloc_node<BlockNode>(); block->parent_block = p_block; cf->blocks.push_back(block); @@ -5365,7 +5267,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui _set_tkpos(pos); //rollback } } else if (tk.type == TK_CF_SWITCH) { - if (RenderingServer::get_singleton()->is_low_end()) { _set_error("\"switch\" operator is supported only on high-end platform!"); return ERR_PARSE_ERROR; @@ -5380,8 +5281,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui ControlFlowNode *cf = alloc_node<ControlFlowNode>(); cf->flow_op = FLOW_OP_SWITCH; Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!n) + if (!n) { return ERR_PARSE_ERROR; + } if (n->get_datatype() != TYPE_INT) { _set_error("Expected integer expression"); return ERR_PARSE_ERROR; @@ -5508,13 +5410,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui p_block->statements.push_back(cf); Error err = _parse_block(case_block, p_builtin_types, false, true, false); - if (err) + if (err) { return err; + } return OK; } else if (tk.type == TK_CF_DEFAULT) { - if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_CASE) { _set_tkpos(pos); return OK; @@ -5542,8 +5444,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui p_block->statements.push_back(cf); Error err = _parse_block(default_block, p_builtin_types, false, true, false); - if (err) + if (err) { return err; + } return OK; @@ -5554,13 +5457,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui BlockNode *do_block = nullptr; if (is_do) { - do_block = alloc_node<BlockNode>(); do_block->parent_block = p_block; Error err = _parse_block(do_block, p_builtin_types, true, true, true); - if (err) + if (err) { return err; + } tk = _get_token(); if (tk.type != TK_CF_WHILE) { @@ -5582,8 +5485,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui cf->flow_op = FLOW_OP_WHILE; } Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!n) + if (!n) { return ERR_PARSE_ERROR; + } tk = _get_token(); if (tk.type != TK_PARENTHESIS_CLOSE) { @@ -5598,10 +5502,10 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui p_block->statements.push_back(cf); Error err = _parse_block(block, p_builtin_types, true, true, true); - if (err) + if (err) { return err; + } } else { - cf->expressions.push_back(n); cf->blocks.push_back(do_block); p_block->statements.push_back(cf); @@ -5633,8 +5537,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui } Node *n = _parse_and_reduce_expression(init_block, p_builtin_types); - if (!n) + if (!n) { return ERR_PARSE_ERROR; + } if (n->get_datatype() != TYPE_BOOL) { _set_error("Middle expression is expected to be boolean."); @@ -5650,8 +5555,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui cf->expressions.push_back(n); n = _parse_and_reduce_expression(init_block, p_builtin_types); - if (!n) + if (!n) { return ERR_PARSE_ERROR; + } cf->expressions.push_back(n); @@ -5667,11 +5573,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui p_block->statements.push_back(cf); Error err = _parse_block(block, p_builtin_types, true, true, true); - if (err) + if (err) { return err; + } } else if (tk.type == TK_CF_RETURN) { - //check return type BlockNode *b = p_block; while (b && !b->parent_function) { @@ -5697,8 +5603,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui } else { _set_tkpos(pos); //rollback, wants expression Node *expr = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!expr) + if (!expr) { return ERR_PARSE_ERROR; + } if (b->parent_function->return_type != expr->get_datatype()) { _set_error("Expected return expression of type '" + get_datatype_name(b->parent_function->return_type) + "'"); @@ -5724,7 +5631,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui block = block->parent_block; } } else if (tk.type == TK_CF_DISCARD) { - //check return type BlockNode *b = p_block; while (b && !b->parent_function) { @@ -5752,7 +5658,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui p_block->statements.push_back(flow); } else if (tk.type == TK_CF_BREAK) { - if (!p_can_break) { //all is good _set_error("Breaking is not allowed here"); @@ -5779,7 +5684,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui } } else if (tk.type == TK_CF_CONTINUE) { - if (!p_can_continue) { //all is good _set_error("Continuing is not allowed here"); @@ -5798,12 +5702,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui p_block->statements.push_back(flow); } else { - //nothing else, so expression _set_tkpos(pos); //rollback Node *expr = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!expr) + if (!expr) { return ERR_PARSE_ERROR; + } p_block->statements.push_back(expr); tk = _get_token(); @@ -5813,15 +5717,15 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui } } - if (p_just_one) + if (p_just_one) { break; + } } return OK; } String ShaderLanguage::_get_shader_type_list(const Set<String> &p_shader_types) const { - // Return a list of shader types as an human-readable string String valid_types; for (const Set<String>::Element *E = p_shader_types.front(); E; E = E->next()) { @@ -5877,7 +5781,6 @@ Error ShaderLanguage::_validate_datatype(DataType p_type) { } Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types) { - Token tk = _get_token(); if (tk.type != TK_SHADER_TYPE) { @@ -5915,12 +5818,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL; while (tk.type != TK_EOF) { - switch (tk.type) { case TK_RENDER_MODE: { - while (true) { - StringName mode; _get_completable_identifier(nullptr, COMPLETION_RENDER_MODE, mode); @@ -6082,7 +5982,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } break; case TK_GLOBAL: { - tk = _get_token(); if (tk.type != TK_UNIFORM) { _set_error("Expected 'uniform' after 'global'"); @@ -6104,7 +6003,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct [[fallthrough]]; case TK_UNIFORM: case TK_VARYING: { - bool uniform = tk.type == TK_UNIFORM; DataPrecision precision = PRECISION_DEFAULT; DataInterpolation interpolation = INTERPOLATION_SMOOTH; @@ -6158,7 +6056,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } if (uniform) { - if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL) { //validate global uniform DataType gvtype = global_var_get_type_func(name); @@ -6185,7 +6082,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } } else { - if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL && (type == TYPE_MAT2 || type == TYPE_MAT3 || type == TYPE_MAT4)) { + if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE && (type == TYPE_MAT2 || type == TYPE_MAT3 || type == TYPE_MAT4)) { _set_error("Uniforms with 'instance' qualifiers can't be of matrix type."); return ERR_PARSE_ERROR; } @@ -6238,7 +6135,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } uniform2.hint = ShaderNode::Uniform::HINT_COLOR; } else if (tk.type == TK_HINT_RANGE) { - uniform2.hint = ShaderNode::Uniform::HINT_RANGE; if (type != TYPE_FLOAT && type != TYPE_INT) { _set_error("Range hint is for float and int only"); @@ -6317,7 +6213,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } } else if (tk.type == TK_HINT_INSTANCE_INDEX) { - if (custom_instance_index != -1) { _set_error("Can only specify 'instance_index' once."); return ERR_PARSE_ERROR; @@ -6399,10 +6294,10 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct //reset scope for next uniform if (tk.type == TK_OP_ASSIGN) { - Node *expr = _parse_and_reduce_expression(nullptr, Map<StringName, BuiltInInfo>()); - if (!expr) + if (!expr) { return ERR_PARSE_ERROR; + } if (expr->type != Node::TYPE_CONSTANT) { _set_error("Expected constant expression after '='"); return ERR_PARSE_ERROR; @@ -6428,7 +6323,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } } else { - ShaderNode::Varying varying; varying.type = type; varying.precision = precision; @@ -6494,7 +6388,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct is_struct = true; struct_name = tk.text; } else { - if (!is_token_datatype(tk.type)) { _set_error("Expected constant, function, uniform or varying"); return ERR_PARSE_ERROR; @@ -6554,7 +6447,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct constant.initializer = nullptr; if (tk.type == TK_OP_ASSIGN) { - if (!is_constant) { _set_error("Expected 'const' keyword before constant definition"); return ERR_PARSE_ERROR; @@ -6562,8 +6454,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct //variable created with assignment! must parse an expression Node *expr = _parse_and_reduce_expression(nullptr, Map<StringName, BuiltInInfo>()); - if (!expr) + if (!expr) { return ERR_PARSE_ERROR; + } if (expr->type == Node::TYPE_OPERATOR && ((OperatorNode *)expr)->op == OP_CALL) { _set_error("Expected constant expression after '='"); return ERR_PARSE_ERROR; @@ -6798,11 +6691,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct current_function = name; Error err = _parse_block(func_node->body, builtin_types); - if (err) + if (err) { return err; + } if (func_node->return_type != DataType::TYPE_VOID) { - BlockNode *block = func_node->body; if (_find_last_flow_op_in_block(block, FlowOperation::FLOW_OP_RETURN) != OK) { _set_error("Expected at least one return statement in a non-void function."); @@ -6820,7 +6713,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } bool ShaderLanguage::has_builtin(const Map<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name) { - if (p_functions.has("vertex")) { if (p_functions["vertex"].built_ins.has(p_name)) { return true; @@ -6840,7 +6732,6 @@ bool ShaderLanguage::has_builtin(const Map<StringName, ShaderLanguage::FunctionI } Error ShaderLanguage::_find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOperation p_op) { - bool found = false; for (int i = p_flow->blocks.size() - 1; i >= 0; i--) { @@ -6859,11 +6750,9 @@ Error ShaderLanguage::_find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOper } Error ShaderLanguage::_find_last_flow_op_in_block(BlockNode *p_block, FlowOperation p_op) { - bool found = false; for (int i = p_block->statements.size() - 1; i >= 0; i--) { - if (p_block->statements[i]->type == Node::TYPE_CONTROL_FLOW) { ControlFlowNode *flow = (ControlFlowNode *)p_block->statements[i]; if (flow->flow_op == p_op) { @@ -6892,7 +6781,6 @@ Error ShaderLanguage::_find_last_flow_op_in_block(BlockNode *p_block, FlowOperat // skips over whitespace and /* */ and // comments static int _get_first_ident_pos(const String &p_code) { - int idx = 0; #define GETCHAR(m_idx) (((idx + m_idx) < p_code.length()) ? p_code[idx + m_idx] : CharType(0)) @@ -6901,8 +6789,9 @@ static int _get_first_ident_pos(const String &p_code) { if (GETCHAR(0) == '/' && GETCHAR(1) == '/') { idx += 2; while (true) { - if (GETCHAR(0) == 0) + if (GETCHAR(0) == 0) { return 0; + } if (GETCHAR(0) == '\n') { idx++; break; // loop @@ -6912,8 +6801,9 @@ static int _get_first_ident_pos(const String &p_code) { } else if (GETCHAR(0) == '/' && GETCHAR(1) == '*') { idx += 2; while (true) { - if (GETCHAR(0) == 0) + if (GETCHAR(0) == 0) { return 0; + } if (GETCHAR(0) == '*' && GETCHAR(1) == '/') { idx += 2; break; // loop @@ -6938,13 +6828,11 @@ static int _get_first_ident_pos(const String &p_code) { } String ShaderLanguage::get_shader_type(const String &p_code) { - bool reading_type = false; String cur_identifier; for (int i = _get_first_ident_pos(p_code); i < p_code.length(); i++) { - if (p_code[i] == ';') { break; @@ -6966,14 +6854,14 @@ String ShaderLanguage::get_shader_type(const String &p_code) { } } - if (reading_type) + if (reading_type) { return cur_identifier; + } return String(); } Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func) { - clear(); code = p_code; @@ -6991,7 +6879,6 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Functi } Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint) { - clear(); code = p_code; @@ -7003,7 +6890,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct _parse_shader(p_functions, p_render_modes, p_shader_types); switch (completion_type) { - case COMPLETION_NONE: { //do nothing return OK; @@ -7017,7 +6903,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct return OK; } break; case COMPLETION_STRUCT: { - if (shader->structs.has(completion_struct)) { StructNode *node = shader->structs[completion_struct].shader_struct; for (int i = 0; i < node->members.size(); i++) { @@ -7029,7 +6914,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct return OK; } break; case COMPLETION_MAIN_FUNCTION: { - for (const Map<StringName, FunctionInfo>::Element *E = p_functions.front(); E; E = E->next()) { ScriptCodeCompletionOption option(E->key(), ScriptCodeCompletionOption::KIND_FUNCTION); r_options->push_back(option); @@ -7039,7 +6923,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } break; case COMPLETION_IDENTIFIER: case COMPLETION_FUNCTION_CALL: { - bool comp_ident = completion_type == COMPLETION_IDENTIFIER; Map<String, ScriptCodeCompletionOption::Kind> matches; StringName skip_function; @@ -7049,7 +6932,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct while (block) { if (comp_ident) { for (const Map<StringName, BlockNode::Variable>::Element *E = block->variables.front(); E; E = E->next()) { - if (E->get().line < completion_line) { matches.insert(E->key(), ScriptCodeCompletionOption::KIND_VARIABLE); } @@ -7097,8 +6979,9 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } for (int i = 0; i < shader->functions.size(); i++) { - if (!shader->functions[i].callable || shader->functions[i].name == skip_function) + if (!shader->functions[i].callable || shader->functions[i].name == skip_function) { continue; + } matches.insert(String(shader->functions[i].name), ScriptCodeCompletionOption::KIND_FUNCTION); } @@ -7141,12 +7024,11 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct return OK; } break; case COMPLETION_CALL_ARGUMENTS: { - for (int i = 0; i < shader->functions.size(); i++) { - if (!shader->functions[i].callable) + if (!shader->functions[i].callable) { continue; + } if (shader->functions[i].name == completion_function) { - String calltip; calltip += get_datatype_name(shader->functions[i].function->return_type); @@ -7155,11 +7037,11 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct calltip += "("; for (int j = 0; j < shader->functions[i].function->arguments.size(); j++) { - - if (j > 0) + if (j > 0) { calltip += ", "; - else + } else { calltip += " "; + } if (j == completion_argument) { calltip += CharType(0xFFFF); @@ -7182,8 +7064,9 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } } - if (shader->functions[i].function->arguments.size()) + if (shader->functions[i].function->arguments.size()) { calltip += " "; + } calltip += ")"; r_call_hint = calltip; @@ -7197,7 +7080,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct bool low_end = RenderingServer::get_singleton()->is_low_end(); while (builtin_func_defs[idx].name) { - if (low_end && builtin_func_defs[idx].high_end) { idx++; continue; @@ -7214,14 +7096,14 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } if (completion_function == builtin_func_defs[idx].name) { - if (builtin_func_defs[idx].tag != completion_class) { idx++; continue; } - if (calltip.length()) + if (calltip.length()) { calltip += "\n"; + } calltip += get_datatype_name(builtin_func_defs[idx].rettype); calltip += " "; @@ -7230,14 +7112,15 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct bool found_arg = false; for (int i = 0; i < 4; i++) { - - if (builtin_func_defs[idx].args[i] == TYPE_VOID) + if (builtin_func_defs[idx].args[i] == TYPE_VOID) { break; + } - if (i > 0) + if (i > 0) { calltip += ", "; - else + } else { calltip += " "; + } if (i == completion_argument) { calltip += CharType(0xFFFF); @@ -7256,8 +7139,9 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct found_arg = true; } - if (found_arg) + if (found_arg) { calltip += " "; + } calltip += ")"; } idx++; @@ -7269,7 +7153,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } break; case COMPLETION_INDEX: { - const char colv[4] = { 'r', 'g', 'b', 'a' }; const char coordv[4] = { 'x', 'y', 'z', 'w' }; const char coordt[4] = { 's', 't', 'p', 'q' }; @@ -7288,7 +7171,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct case TYPE_IVEC3: case TYPE_UVEC3: case TYPE_VEC3: { - limit = 3; } break; @@ -7296,7 +7178,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct case TYPE_IVEC4: case TYPE_UVEC4: case TYPE_VEC4: { - limit = 4; } break; @@ -7326,27 +7207,22 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } String ShaderLanguage::get_error_text() { - return error_str; } int ShaderLanguage::get_error_line() { - return error_line; } ShaderLanguage::ShaderNode *ShaderLanguage::get_shader() { - return shader; } ShaderLanguage::ShaderLanguage() { - nodes = nullptr; completion_class = TAG_GLOBAL; } ShaderLanguage::~ShaderLanguage() { - clear(); } diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 973e1c4937..020a5e3e6f 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -40,7 +40,6 @@ #include "core/variant.h" class ShaderLanguage { - public: enum TokenType { TK_EMPTY, @@ -79,6 +78,7 @@ public: TK_TYPE_ISAMPLER3D, TK_TYPE_USAMPLER3D, TK_TYPE_SAMPLERCUBE, + TK_TYPE_SAMPLERCUBEARRAY, TK_INTERPOLATION_FLAT, TK_INTERPOLATION_SMOOTH, TK_CONST, @@ -218,6 +218,7 @@ public: TYPE_ISAMPLER3D, TYPE_USAMPLER3D, TYPE_SAMPLERCUBE, + TYPE_SAMPLERCUBEARRAY, TYPE_STRUCT, TYPE_MAX }; @@ -326,7 +327,7 @@ public: }; struct Node { - Node *next; + Node *next = nullptr; enum Type { TYPE_SHADER, @@ -350,7 +351,6 @@ public: virtual String get_datatype_name() const { return ""; } Node(Type t) : - next(nullptr), type(t) {} virtual ~Node() {} }; @@ -366,41 +366,35 @@ public: Node *nodes; struct OperatorNode : public Node { - DataType return_cache; - DataPrecision return_precision_cache; - Operator op; + DataType return_cache = TYPE_VOID; + DataPrecision return_precision_cache = PRECISION_DEFAULT; + Operator op = OP_EQUAL; StringName struct_name; Vector<Node *> arguments; virtual DataType get_datatype() const { return return_cache; } virtual String get_datatype_name() const { return String(struct_name); } OperatorNode() : - Node(TYPE_OPERATOR), - return_cache(TYPE_VOID), - return_precision_cache(PRECISION_DEFAULT), - op(OP_EQUAL), - struct_name("") {} + Node(TYPE_OPERATOR) {} }; struct VariableNode : public Node { - DataType datatype_cache; + DataType datatype_cache = TYPE_VOID; StringName name; StringName struct_name; virtual DataType get_datatype() const { return datatype_cache; } virtual String get_datatype_name() const { return String(struct_name); } - bool is_const; + bool is_const = false; VariableNode() : - Node(TYPE_VARIABLE), - datatype_cache(TYPE_VOID), - is_const(false) {} + Node(TYPE_VARIABLE) {} }; struct VariableDeclarationNode : public Node { - DataPrecision precision; - DataType datatype; + DataPrecision precision = PRECISION_DEFAULT; + DataType datatype = TYPE_VOID; String struct_name; - bool is_const; + bool is_const = false; struct Declaration { StringName name; @@ -411,47 +405,38 @@ public: virtual DataType get_datatype() const { return datatype; } VariableDeclarationNode() : - Node(TYPE_VARIABLE_DECLARATION), - precision(PRECISION_DEFAULT), - datatype(TYPE_VOID), - is_const(false) {} + Node(TYPE_VARIABLE_DECLARATION) {} }; struct ArrayNode : public Node { - DataType datatype_cache; + DataType datatype_cache = TYPE_VOID; StringName struct_name; StringName name; - Node *index_expression; - Node *call_expression; - bool is_const; + Node *index_expression = nullptr; + Node *call_expression = nullptr; + bool is_const = false; virtual DataType get_datatype() const { return datatype_cache; } virtual String get_datatype_name() const { return String(struct_name); } ArrayNode() : - Node(TYPE_ARRAY), - datatype_cache(TYPE_VOID), - index_expression(nullptr), - call_expression(nullptr), - is_const(false) {} + Node(TYPE_ARRAY) {} }; struct ArrayConstructNode : public Node { - DataType datatype; + DataType datatype = TYPE_VOID; String struct_name; Vector<Node *> initializer; ArrayConstructNode() : - Node(TYPE_ARRAY_CONSTRUCT), - datatype(TYPE_VOID) { - } + Node(TYPE_ARRAY_CONSTRUCT) {} }; struct ArrayDeclarationNode : public Node { - DataPrecision precision; - DataType datatype; + DataPrecision precision = PRECISION_DEFAULT; + DataType datatype = TYPE_VOID; String struct_name; - bool is_const; + bool is_const = false; struct Declaration { StringName name; @@ -463,14 +448,11 @@ public: virtual DataType get_datatype() const { return datatype; } ArrayDeclarationNode() : - Node(TYPE_ARRAY_DECLARATION), - precision(PRECISION_DEFAULT), - datatype(TYPE_VOID), - is_const(false) {} + Node(TYPE_ARRAY_DECLARATION) {} }; struct ConstantNode : public Node { - DataType datatype; + DataType datatype = TYPE_VOID; union Value { bool boolean; @@ -483,15 +465,14 @@ public: virtual DataType get_datatype() const { return datatype; } ConstantNode() : - Node(TYPE_CONSTANT), - datatype(TYPE_VOID) {} + Node(TYPE_CONSTANT) {} }; struct FunctionNode; struct BlockNode : public Node { - FunctionNode *parent_function; - BlockNode *parent_block; + FunctionNode *parent_function = nullptr; + BlockNode *parent_block = nullptr; enum BlockType { BLOCK_TYPE_STANDART, @@ -501,8 +482,8 @@ public: BLOCK_TYPE_DEFAULT, }; - int block_type; - SubClassTag block_tag; + int block_type = BLOCK_TYPE_STANDART; + SubClassTag block_tag = SubClassTag::TAG_GLOBAL; struct Variable { DataType type; @@ -515,63 +496,48 @@ public: Map<StringName, Variable> variables; List<Node *> statements; - bool single_statement; + bool single_statement = false; BlockNode() : - Node(TYPE_BLOCK), - parent_function(nullptr), - parent_block(nullptr), - block_type(BLOCK_TYPE_STANDART), - block_tag(SubClassTag::TAG_GLOBAL), - single_statement(false) {} + Node(TYPE_BLOCK) {} }; struct ControlFlowNode : public Node { - FlowOperation flow_op; + FlowOperation flow_op = FLOW_OP_IF; Vector<Node *> expressions; Vector<BlockNode *> blocks; ControlFlowNode() : - Node(TYPE_CONTROL_FLOW), - flow_op(FLOW_OP_IF) {} + Node(TYPE_CONTROL_FLOW) {} }; struct MemberNode : public Node { - DataType basetype; - bool basetype_const; + DataType basetype = TYPE_VOID; + bool basetype_const = false; StringName base_struct_name; DataPrecision precision; - DataType datatype; - int array_size; + DataType datatype = TYPE_VOID; + int array_size = 0; StringName struct_name; StringName name; - Node *owner; - Node *index_expression; - bool has_swizzling_duplicates; + Node *owner = nullptr; + Node *index_expression = nullptr; + bool has_swizzling_duplicates = false; virtual DataType get_datatype() const { return datatype; } virtual String get_datatype_name() const { return String(struct_name); } MemberNode() : - Node(TYPE_MEMBER), - basetype(TYPE_VOID), - basetype_const(false), - datatype(TYPE_VOID), - array_size(0), - owner(nullptr), - index_expression(nullptr), - has_swizzling_duplicates(false) {} + Node(TYPE_MEMBER) {} }; struct StructNode : public Node { - List<MemberNode *> members; StructNode() : Node(TYPE_STRUCT) {} }; struct FunctionNode : public Node { - struct Argument { ArgumentQualifier qualifier; StringName name; @@ -589,23 +555,18 @@ public: }; StringName name; - DataType return_type; + DataType return_type = TYPE_VOID; StringName return_struct_name; - DataPrecision return_precision; + DataPrecision return_precision = PRECISION_DEFAULT; Vector<Argument> arguments; - BlockNode *body; - bool can_discard; + BlockNode *body = nullptr; + bool can_discard = false; FunctionNode() : - Node(TYPE_FUNCTION), - return_type(TYPE_VOID), - return_precision(PRECISION_DEFAULT), - body(nullptr), - can_discard(false) {} + Node(TYPE_FUNCTION) {} }; struct ShaderNode : public Node { - struct Constant { StringName name; DataType type; @@ -627,16 +588,12 @@ public: }; struct Varying { - DataType type; - DataInterpolation interpolation; - DataPrecision precision; - int array_size; + DataType type = TYPE_VOID; + DataInterpolation interpolation = INTERPOLATION_FLAT; + DataPrecision precision = PRECISION_DEFAULT; + int array_size = 0; - Varying() : - type(TYPE_VOID), - interpolation(INTERPOLATION_FLAT), - precision(PRECISION_DEFAULT), - array_size(0) {} + Varying() {} }; struct Uniform { @@ -665,27 +622,19 @@ public: SCOPE_GLOBAL, }; - int order; - int texture_order; - DataType type; - DataPrecision precision; + int order = 0; + int texture_order = 0; + DataType type = TYPE_VOID; + DataPrecision precision = PRECISION_DEFAULT; Vector<ConstantNode::Value> default_value; - Scope scope; - Hint hint; - TextureFilter filter; - TextureRepeat repeat; + Scope scope = SCOPE_LOCAL; + Hint hint = HINT_NONE; + TextureFilter filter = FILTER_DEFAULT; + TextureRepeat repeat = REPEAT_DEFAULT; float hint_range[3]; - int instance_index; - - Uniform() : - order(0), - texture_order(0), - type(TYPE_VOID), - precision(PRECISION_DEFAULT), - hint(HINT_NONE), - filter(FILTER_DEFAULT), - repeat(REPEAT_DEFAULT), - instance_index(0) { + int instance_index = 0; + + Uniform() { hint_range[0] = 0.0f; hint_range[1] = 1.0f; hint_range[2] = 0.001f; @@ -765,12 +714,10 @@ public: static void get_builtin_funcs(List<String> *r_keywords); struct BuiltInInfo { - DataType type; - bool constant; + DataType type = TYPE_VOID; + bool constant = false; - BuiltInInfo() : - type(TYPE_VOID), - constant(false) {} + BuiltInInfo() {} BuiltInInfo(DataType p_type, bool p_constant = false) : type(p_type), @@ -823,8 +770,9 @@ private: } void _set_error(const String &p_str) { - if (error_set) + if (error_set) { return; + } error_line = tk_line; error_set = true; diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index 78bbd73db4..2601efa9e2 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -31,12 +31,10 @@ #include "shader_types.h" const Map<StringName, ShaderLanguage::FunctionInfo> &ShaderTypes::get_functions(RS::ShaderMode p_mode) { - return shader_modes[p_mode].functions; } const Vector<StringName> &ShaderTypes::get_modes(RS::ShaderMode p_mode) { - return shader_modes[p_mode].modes; } @@ -47,7 +45,6 @@ const Set<String> &ShaderTypes::get_types() { ShaderTypes *ShaderTypes::singleton = nullptr; static ShaderLanguage::BuiltInInfo constt(ShaderLanguage::DataType p_type) { - return ShaderLanguage::BuiltInInfo(p_type, true); } diff --git a/servers/rendering/shader_types.h b/servers/rendering/shader_types.h index 499a761265..7d8057a5c6 100644 --- a/servers/rendering/shader_types.h +++ b/servers/rendering/shader_types.h @@ -36,9 +36,7 @@ #include "shader_language.h" class ShaderTypes { - struct Type { - Map<StringName, ShaderLanguage::FunctionInfo> functions; Vector<StringName> modes; }; |