summaryrefslogtreecommitdiff
path: root/servers/visual
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2019-07-27 10:23:24 -0300
committerJuan Linietsky <reduzio@gmail.com>2020-02-11 11:53:29 +0100
commit0586e184490fd132f99acb1a67c788959cfdbade (patch)
tree194972ba608705445c9ee084f908e183a9792760 /servers/visual
parent8bbbb973361f367a4888629c571fb6f43581269d (diff)
Custom material support seems complete.
Diffstat (limited to 'servers/visual')
-rw-r--r--servers/visual/SCsub2
-rw-r--r--servers/visual/rasterizer.cpp (renamed from servers/visual/rasterizer/rasterizer.cpp)0
-rw-r--r--servers/visual/rasterizer.h (renamed from servers/visual/rasterizer/rasterizer.h)0
-rw-r--r--servers/visual/rasterizer_rd/SCsub (renamed from servers/visual/rasterizer/SCsub)0
-rw-r--r--servers/visual/rasterizer_rd/effects_rd.cpp142
-rw-r--r--servers/visual/rasterizer_rd/effects_rd.h87
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp (renamed from servers/visual/rasterizer/rasterizer_canvas_rd.cpp)43
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_canvas_rd.h (renamed from servers/visual/rasterizer/rasterizer_canvas_rd.h)18
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_rd.cpp (renamed from servers/visual/rasterizer/rasterizer_rd.cpp)0
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_rd.h (renamed from servers/visual/rasterizer/rasterizer_rd.h)8
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp (renamed from servers/visual/rasterizer/rasterizer_scene_forward_rd.cpp)0
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h (renamed from servers/visual/rasterizer/rasterizer_scene_forward_rd.h)2
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp (renamed from servers/visual/rasterizer/rasterizer_storage_rd.cpp)133
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_storage_rd.h (renamed from servers/visual/rasterizer/rasterizer_storage_rd.h)28
-rw-r--r--servers/visual/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp (renamed from servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.cpp)3
-rw-r--r--servers/visual/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h (renamed from servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h)0
-rw-r--r--servers/visual/rasterizer_rd/shader_compiler_rd.cpp (renamed from servers/visual/rasterizer/shader_compiler_rd.cpp)1
-rw-r--r--servers/visual/rasterizer_rd/shader_compiler_rd.h (renamed from servers/visual/rasterizer/shader_compiler_rd.h)0
-rw-r--r--servers/visual/rasterizer_rd/shader_rd.cpp (renamed from servers/visual/rasterizer/shader_rd.cpp)11
-rw-r--r--servers/visual/rasterizer_rd/shader_rd.h (renamed from servers/visual/rasterizer/shader_rd.h)2
-rw-r--r--servers/visual/rasterizer_rd/shaders/SCsub (renamed from servers/visual/rasterizer/shaders/SCsub)1
-rw-r--r--servers/visual/rasterizer_rd/shaders/blur.glsl274
-rw-r--r--servers/visual/rasterizer_rd/shaders/blur_inc.glsl35
-rw-r--r--servers/visual/rasterizer_rd/shaders/canvas.glsl (renamed from servers/visual/rasterizer/shaders/canvas.glsl)8
-rw-r--r--servers/visual/rasterizer_rd/shaders/canvas_occlusion.glsl (renamed from servers/visual/rasterizer/shaders/canvas_occlusion.glsl)0
-rw-r--r--servers/visual/rasterizer_rd/shaders/canvas_uniforms_inc.glsl (renamed from servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl)12
-rw-r--r--servers/visual/rendering_device.h32
-rw-r--r--servers/visual/visual_server_canvas.h2
-rw-r--r--servers/visual/visual_server_globals.h2
-rw-r--r--servers/visual/visual_server_raster.h2
-rw-r--r--servers/visual/visual_server_scene.h2
-rw-r--r--servers/visual/visual_server_viewport.h2
32 files changed, 788 insertions, 64 deletions
diff --git a/servers/visual/SCsub b/servers/visual/SCsub
index 9aa395db70..fca18bfea0 100644
--- a/servers/visual/SCsub
+++ b/servers/visual/SCsub
@@ -4,4 +4,4 @@ Import('env')
env.add_source_files(env.servers_sources, "*.cpp")
-SConscript("rasterizer/SCsub")
+SConscript("rasterizer_rd/SCsub")
diff --git a/servers/visual/rasterizer/rasterizer.cpp b/servers/visual/rasterizer.cpp
index 64b5c88699..64b5c88699 100644
--- a/servers/visual/rasterizer/rasterizer.cpp
+++ b/servers/visual/rasterizer.cpp
diff --git a/servers/visual/rasterizer/rasterizer.h b/servers/visual/rasterizer.h
index c8b756fb4a..c8b756fb4a 100644
--- a/servers/visual/rasterizer/rasterizer.h
+++ b/servers/visual/rasterizer.h
diff --git a/servers/visual/rasterizer/SCsub b/servers/visual/rasterizer_rd/SCsub
index cc17feeb05..cc17feeb05 100644
--- a/servers/visual/rasterizer/SCsub
+++ b/servers/visual/rasterizer_rd/SCsub
diff --git a/servers/visual/rasterizer_rd/effects_rd.cpp b/servers/visual/rasterizer_rd/effects_rd.cpp
new file mode 100644
index 0000000000..1566fac5b0
--- /dev/null
+++ b/servers/visual/rasterizer_rd/effects_rd.cpp
@@ -0,0 +1,142 @@
+#include "effects_rd.h"
+
+RID EffectsRD::_get_uniform_set_from_texture(RID p_texture) {
+
+ 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)) {
+ return uniform_set;
+ }
+ }
+
+ Vector<RD::Uniform> uniforms;
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.binding = 0;
+ u.ids.push_back(default_sampler);
+ u.ids.push_back(p_texture);
+ uniforms.push_back(u);
+ //any thing with the same configuration (one texture in binding 0 for set 0), is good
+ RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, blur.shader.version_get_shader(blur.shader_version, 0), 0);
+
+ texture_to_uniform_set_cache[p_texture] = uniform_set;
+
+ return uniform_set;
+}
+
+void EffectsRD::copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region) {
+
+ zeromem(&blur.push_constant, sizeof(BlurPushConstant));
+
+ if (p_region != Rect2()) {
+ blur.push_constant.flags = BLUR_FLAG_USE_BLUR_SECTION;
+ blur.push_constant.section[0] = p_region.position.x;
+ blur.push_constant.section[1] = p_region.position.y;
+ blur.push_constant.section[2] = p_region.size.width;
+ blur.push_constant.section[3] = p_region.size.height;
+ }
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH);
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_SIMPLY_COPY].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_source_rd_texture), 0);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_list_end();
+}
+
+void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, const Rect2 &p_region) {
+
+ zeromem(&blur.push_constant, sizeof(BlurPushConstant));
+
+ uint32_t base_flags = 0;
+ if (p_region != Rect2()) {
+ base_flags = BLUR_FLAG_USE_BLUR_SECTION;
+ blur.push_constant.section[0] = p_region.position.x;
+ blur.push_constant.section[1] = p_region.position.y;
+ blur.push_constant.section[2] = p_region.size.width;
+ blur.push_constant.section[3] = p_region.size.height;
+ }
+
+ blur.push_constant.pixel_size[0] = p_pixel_size.x;
+ blur.push_constant.pixel_size[1] = p_pixel_size.y;
+
+ //HORIZONTAL
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer_half, RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH);
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_GAUSSIAN_BLUR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer_half)));
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
+
+ blur.push_constant.flags = base_flags | BLUR_FLAG_HORIZONTAL;
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
+
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_list_end();
+
+ //VERTICAL
+ draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH);
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_GAUSSIAN_BLUR].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_rd_texture_half), 0);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
+
+ blur.push_constant.flags = base_flags;
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
+
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_list_end();
+}
+
+EffectsRD::EffectsRD() {
+
+ // Initialize blur
+ Vector<String> blur_modes;
+ blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n");
+ blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n");
+ blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n");
+ blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n");
+ blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n");
+ blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n");
+ blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n#define DOF_NEAR_BLUR_MERGE\n");
+ blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n#define DOF_NEAR_BLUR_MERGE\n");
+ blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n#define DOF_NEAR_BLUR_MERGE\n");
+ blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_LOW\n");
+ blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_MEDIUM\n");
+ blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_HIGH\n");
+ blur_modes.push_back("\n#define MODE_SSAO_MERGE\n");
+ blur_modes.push_back("\n#define MODE_SIMPLE_COPY\n");
+
+ blur.shader.initialize(blur_modes);
+ zeromem(&blur.push_constant, sizeof(BlurPushConstant));
+ blur.shader_version = blur.shader.version_create();
+
+ for (int i = 0; i < BLUR_MODE_MAX; i++) {
+ blur.pipelines[i].setup(blur.shader.version_get_shader(blur.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ }
+
+ RD::SamplerState sampler;
+ sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR;
+ sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
+ sampler.max_lod = 0;
+
+ default_sampler = RD::get_singleton()->sampler_create(sampler);
+
+ { //create index array for copy shaders
+ PoolVector<uint8_t> pv;
+ pv.resize(6 * 4);
+ {
+ PoolVector<uint8_t>::Write w = pv.write();
+ int *p32 = (int *)w.ptr();
+ p32[0] = 0;
+ p32[1] = 1;
+ p32[2] = 2;
+ p32[3] = 0;
+ p32[4] = 2;
+ p32[5] = 3;
+ }
+ index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv);
+ index_array = RD::get_singleton()->index_array_create(index_buffer, 0, 6);
+ }
+}
+
+EffectsRD::~EffectsRD() {
+}
diff --git a/servers/visual/rasterizer_rd/effects_rd.h b/servers/visual/rasterizer_rd/effects_rd.h
new file mode 100644
index 0000000000..ed1bc288de
--- /dev/null
+++ b/servers/visual/rasterizer_rd/effects_rd.h
@@ -0,0 +1,87 @@
+#ifndef EFFECTS_RD_H
+#define EFFECTS_RD_H
+
+#include "render_pipeline_vertex_format_cache_rd.h"
+#include "shaders/blur.glsl.gen.h"
+
+class EffectsRD {
+
+ enum BlurMode {
+ BLUR_MODE_GAUSSIAN_BLUR,
+ BLUR_MODE_GAUSSIAN_GLOW,
+ BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE,
+ BLUR_MODE_DOF_NEAR_LOW,
+ BLUR_MODE_DOF_NEAR_MEDIUM,
+ BLUR_MODE_DOF_NEAR_HIGH,
+ BLUR_MODE_DOF_NEAR_MERGE_LOW,
+ BLUR_MODE_DOF_NEAR_MERGE_MEDIUM,
+ BLUR_MODE_DOF_NEAR_MERGE_HIGH,
+ BLUR_MODE_DOF_FAR_LOW,
+ BLUR_MODE_DOF_FAR_MEDIUM,
+ BLUR_MODE_DOF_FAR_HIGH,
+ BLUR_MODE_SSAO_MERGE,
+ BLUR_MODE_SIMPLY_COPY,
+ BLUR_MODE_MAX,
+
+ };
+
+ enum {
+ BLUR_FLAG_HORIZONTAL = (1 << 0),
+ BLUR_FLAG_USE_BLUR_SECTION = (1 << 1),
+ BLUR_FLAG_USE_ORTHOGONAL_PROJECTION = (1 << 2),
+ BLUR_FLAG_DOF_NEAR_FIRST_TAP = (1 << 3),
+ BLUR_FLAG_GLOW_FIRST_PASS = (1 << 4)
+ };
+
+ struct BlurPushConstant {
+ float section[4];
+ float pixel_size[2];
+ uint32_t flags;
+ uint32_t pad;
+ //glow
+ float glow_strength;
+ float glow_bloom;
+ float glow_hdr_threshold;
+ float glow_hdr_scale;
+ float glow_exposure;
+ float glow_white;
+ float glow_luminance_cap;
+ float glow_auto_exposure_grey;
+ //dof
+ float dof_begin;
+ float dof_end;
+ float dof_radius;
+ float dof_pad;
+
+ float dof_dir[2];
+ float camera_z_far;
+ float camera_z_near;
+
+ float ssao_color[4];
+ };
+
+ struct Blur {
+ BlurPushConstant push_constant;
+ BlurShaderRD shader;
+ RID shader_version;
+ RenderPipelineVertexFormatCacheRD pipelines[BLUR_MODE_MAX];
+
+ } blur;
+
+ RID default_sampler;
+ RID index_buffer;
+ RID index_array;
+
+ Map<RID, RID> texture_to_uniform_set_cache;
+
+ RID _get_uniform_set_from_texture(RID p_texture);
+
+public:
+ void copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region);
+ void gaussian_blur(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, const Rect2 &p_region);
+
+ EffectsRD();
+ ~EffectsRD();
+};
+
+#endif // EFFECTS_RD_H
diff --git a/servers/visual/rasterizer/rasterizer_canvas_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp
index d9cd19e0cb..9dd8f7ce50 100644
--- a/servers/visual/rasterizer/rasterizer_canvas_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp
@@ -1303,7 +1303,7 @@ 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) {
+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 = NULL;
@@ -1323,6 +1323,9 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH, clear_colors);
+ if (p_screen_uniform_set.is_valid()) {
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_screen_uniform_set, 3);
+ }
RID prev_material;
PipelineVariants *pipeline_variants = &shader.pipeline_variants;
@@ -1348,18 +1351,16 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
if (ci->material != prev_material) {
- MaterialData *material_data;
+ MaterialData *material_data = NULL;
if (ci->material.is_valid()) {
material_data = (MaterialData *)storage->material_get_data(ci->material, RasterizerStorageRD::SHADER_TYPE_2D);
- print_line("has material data");
}
if (material_data) {
- if (material_data->shader_data->version.is_valid()) {
+ 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()) {
- print_line("bound uniform set");
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material_data->uniform_set, 1);
}
} else {
@@ -1370,7 +1371,6 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
}
}
- print_line("go render");
_render_item(draw_list, ci, fb_format, canvas_transform_inverse, current_clip, p_lights, pipeline_variants);
prev_material = ci->material;
@@ -1410,6 +1410,10 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
state_buffer.canvas_modulate[2] = p_modulate.b;
state_buffer.canvas_modulate[3] = p_modulate.a;
+ Size2 render_target_size = storage->render_target_get_size(p_to_render_target);
+ state_buffer.screen_pixel_size[0] = 1.0 / render_target_size.x;
+ state_buffer.screen_pixel_size[1] = 1.0 / render_target_size.y;
+
state_buffer.time = state.time;
RD::get_singleton()->buffer_update(state.canvas_state_buffer, 0, sizeof(State::Buffer), &state_buffer, true);
}
@@ -1480,6 +1484,7 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
Item *ci = p_item_list;
Rect2 back_buffer_rect;
bool backbuffer_copy = false;
+ RID screen_uniform_set;
while (ci) {
@@ -1493,19 +1498,27 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
}
}
- if (!material_screen_texture_found && ci->material.is_valid()) {
+ if (ci->material.is_valid()) {
MaterialData *md = (MaterialData *)storage->material_get_data(ci->material, RasterizerStorageRD::SHADER_TYPE_2D);
- if (md->shader_data->uses_screen_texture) {
- backbuffer_copy = true;
- back_buffer_rect = Rect2();
+ if (md && md->shader_data->valid && md->shader_data->uses_screen_texture) {
+ if (!material_screen_texture_found) {
+ backbuffer_copy = true;
+ back_buffer_rect = Rect2();
+ }
+ if (screen_uniform_set.is_null()) {
+ RID backbuffer_shader = shader.canvas_shader.version_get_shader(md->shader_data->version, 0); //any version is fine
+ screen_uniform_set = storage->render_target_get_back_buffer_uniform_set(p_to_render_target, backbuffer_shader);
+ }
}
}
if (backbuffer_copy) {
//render anything pending, including clearing if no items
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, screen_uniform_set);
item_count = 0;
+ storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect);
+
backbuffer_copy = false;
material_screen_texture_found = true; //after a backbuffer copy, screen texture makes no further copies
}
@@ -1513,7 +1526,7 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
items[item_count++] = ci;
if (!ci->next || item_count == MAX_RENDER_ITEMS - 1) {
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, screen_uniform_set);
//then reset
item_count = 0;
}
@@ -1771,7 +1784,6 @@ void RasterizerCanvasRD::occluder_polygon_set_cull_mode(RID p_occluder, VS::Canv
void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
//compile
- print_line("shader set code?");
code = p_code;
valid = false;
ubo_size = 0;
@@ -1787,7 +1799,7 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
int light_mode = LIGHT_MODE_NORMAL;
int blend_mode = BLEND_MODE_MIX;
- bool uses_screen_texture = false;
+ uses_screen_texture = false;
ShaderCompilerRD::IdentifierActions actions;
@@ -1833,6 +1845,7 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
print_line("\n**light_code:\n" + gen_code.light);
#endif
canvas_singleton->shader.canvas_shader.version_set_code(version, gen_code.uniforms, gen_code.vertex_global, gen_code.vertex, gen_code.fragment_global, gen_code.light, gen_code.fragment, gen_code.defines);
+ ERR_FAIL_COND(!canvas_singleton->shader.canvas_shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
ubo_offsets = gen_code.uniform_offsets;
@@ -2304,6 +2317,8 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
actions.base_texture_binding_index = 2;
actions.texture_layout_set = 1;
actions.base_uniform_string = "material.";
+ actions.default_filter = ShaderLanguage::FILTER_LINEAR;
+ actions.default_repeat = ShaderLanguage::REPEAT_DISABLE;
shader.compiler.initialize(actions);
}
diff --git a/servers/visual/rasterizer/rasterizer_canvas_rd.h b/servers/visual/rasterizer_rd/rasterizer_canvas_rd.h
index 851b891ec4..edb8007f5c 100644
--- a/servers/visual/rasterizer/rasterizer_canvas_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_canvas_rd.h
@@ -1,13 +1,13 @@
#ifndef RASTERIZER_CANVAS_RD_H
#define RASTERIZER_CANVAS_RD_H
-#include "servers/visual/rasterizer/rasterizer.h"
-#include "servers/visual/rasterizer/rasterizer_storage_rd.h"
-#include "servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h"
-#include "servers/visual/rasterizer/shader_compiler_rd.h"
-#include "servers/visual/rasterizer/shaders/canvas.glsl.gen.h"
-#include "servers/visual/rasterizer/shaders/canvas_occlusion.glsl.gen.h"
+#include "servers/visual/rasterizer.h"
+#include "servers/visual/rasterizer_rd/rasterizer_storage_rd.h"
+#include "servers/visual/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h"
#include "servers/visual/rendering_device.h"
+#include "servers/visual/rasterizer_rd/shader_compiler_rd.h"
+#include "servers/visual/rasterizer_rd/shaders/canvas.glsl.gen.h"
+#include "servers/visual/rasterizer_rd/shaders/canvas_occlusion.glsl.gen.h"
class RasterizerCanvasRD : public RasterizerCanvas {
@@ -382,8 +382,10 @@ class RasterizerCanvasRD : public RasterizerCanvas {
float screen_transform[16];
float canvas_normal_transform[16];
float canvas_modulate[4];
+ float screen_pixel_size[2];
float time;
- float pad[3];
+ float pad;
+
//uint32_t light_count;
//uint32_t pad[3];
};
@@ -433,7 +435,7 @@ class RasterizerCanvasRD : public RasterizerCanvas {
Size2i _bind_texture_binding(TextureBindingID p_binding, RenderingDevice::DrawListID p_draw_list, uint32_t &flags);
void _render_item(RenderingDevice::DrawListID p_draw_list, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, PipelineVariants *p_pipeline_variants);
- void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights);
+ void _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);
_FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4);
_FORCE_INLINE_ void _update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3);
diff --git a/servers/visual/rasterizer/rasterizer_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_rd.cpp
index d1c7549409..d1c7549409 100644
--- a/servers/visual/rasterizer/rasterizer_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_rd.cpp
diff --git a/servers/visual/rasterizer/rasterizer_rd.h b/servers/visual/rasterizer_rd/rasterizer_rd.h
index 2c51dc7300..749d5c23ad 100644
--- a/servers/visual/rasterizer/rasterizer_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_rd.h
@@ -2,10 +2,10 @@
#define RASTERIZER_RD_H
#include "core/os/os.h"
-#include "servers/visual/rasterizer/rasterizer.h"
-#include "servers/visual/rasterizer/rasterizer_canvas_rd.h"
-#include "servers/visual/rasterizer/rasterizer_scene_forward_rd.h"
-#include "servers/visual/rasterizer/rasterizer_storage_rd.h"
+#include "servers/visual/rasterizer.h"
+#include "servers/visual/rasterizer_rd/rasterizer_canvas_rd.h"
+#include "servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h"
+#include "servers/visual/rasterizer_rd/rasterizer_storage_rd.h"
class RasterizerRD : public Rasterizer {
protected:
RasterizerCanvasRD *canvas;
diff --git a/servers/visual/rasterizer/rasterizer_scene_forward_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp
index 56d100ba08..56d100ba08 100644
--- a/servers/visual/rasterizer/rasterizer_scene_forward_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp
diff --git a/servers/visual/rasterizer/rasterizer_scene_forward_rd.h b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h
index 03cadb5ba4..264de6e4a1 100644
--- a/servers/visual/rasterizer/rasterizer_scene_forward_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h
@@ -1,7 +1,7 @@
#ifndef RASTERIZER_SCENE_FORWARD_RD_H
#define RASTERIZER_SCENE_FORWARD_RD_H
-#include "servers/visual/rasterizer/rasterizer.h"
+#include "servers/visual/rasterizer.h"
class RasterizerSceneForwardRD : public RasterizerScene {
public:
diff --git a/servers/visual/rasterizer/rasterizer_storage_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
index 5783379738..fef3418d53 100644
--- a/servers/visual/rasterizer/rasterizer_storage_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
@@ -507,7 +507,7 @@ RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) {
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_RETRIEVE_BIT;
+ 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);
@@ -792,7 +792,6 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) {
Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND(!shader);
- print_line("yey set code?");
shader->code = p_code;
String mode_string = ShaderLanguage::get_shader_type(p_code);
@@ -1662,6 +1661,21 @@ void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) {
RD::get_singleton()->free(rt->color);
}
+ if (rt->backbuffer.is_valid()) {
+ RD::get_singleton()->free(rt->backbuffer);
+ rt->backbuffer = RID();
+ rt->backbuffer_fb = RID();
+ for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
+ //just erase copies, since the rest are erased by dependency
+ RD::get_singleton()->free(rt->backbuffer_mipmaps[i].mipmap_copy);
+ }
+ rt->backbuffer_mipmaps.clear();
+ if (rt->backbuffer_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rt->backbuffer_uniform_set)) {
+ RD::get_singleton()->free(rt->backbuffer_uniform_set);
+ }
+ rt->backbuffer_uniform_set = RID();
+ }
+
rt->framebuffer = RID();
rt->color = RID();
}
@@ -1696,7 +1710,7 @@ void RasterizerStorageRD::_update_render_target(RenderTarget *rt) {
rd_format.mipmaps = 1;
rd_format.type = RD::TEXTURE_TYPE_2D;
rd_format.samples = RD::TEXTURE_SAMPLES_1;
- rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_RETRIEVE_BIT;
+ rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
rd_format.shareable_formats.push_back(rt->color_format);
rd_format.shareable_formats.push_back(rt->color_format_srgb);
}
@@ -1755,6 +1769,56 @@ void RasterizerStorageRD::_update_render_target(RenderTarget *rt) {
}
}
+void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
+ ERR_FAIL_COND(rt->backbuffer.is_valid());
+
+ uint32_t mipmaps_required = Image::get_image_required_mipmaps(rt->size.width, rt->size.height, Image::FORMAT_RGBA8);
+ RD::TextureFormat tf;
+ tf.format = rt->color_format;
+ tf.width = rt->size.width;
+ tf.height = rt->size.height;
+ tf.type = RD::TEXTURE_TYPE_2D;
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ tf.mipmaps = mipmaps_required;
+
+ rt->backbuffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ {
+ Vector<RID> backbuffer_att;
+ RID backbuffer_fb_tex = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, 0);
+ backbuffer_att.push_back(backbuffer_fb_tex);
+ rt->backbuffer_fb = RD::get_singleton()->framebuffer_create(backbuffer_att);
+ }
+
+ //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);
+ Vector<RID> mm_fb_at;
+ mm_fb_at.push_back(mm.mipmap);
+ mm.mipmap_fb = RD::get_singleton()->framebuffer_create(mm_fb_at);
+ }
+
+ {
+ Size2 mm_size = Image::get_image_mipmap_size(tf.width, tf.height, Image::FORMAT_RGBA8, i);
+
+ RD::TextureFormat mmtf = tf;
+ mmtf.width = mm_size.width;
+ mmtf.height = mm_size.height;
+ mmtf.mipmaps = 1;
+
+ mm.mipmap_copy = RD::get_singleton()->texture_create(mmtf, RD::TextureView());
+ Vector<RID> mm_fb_at;
+ mm_fb_at.push_back(mm.mipmap_copy);
+ mm.mipmap_copy_fb = RD::get_singleton()->framebuffer_create(mm_fb_at);
+ }
+
+ rt->backbuffer_mipmaps.push_back(mm);
+ }
+}
+
RID RasterizerStorageRD::render_target_create() {
RenderTarget render_target;
@@ -1866,6 +1930,65 @@ void RasterizerStorageRD::render_target_do_clear_request(RID p_render_target) {
rt->clear_requested = false;
}
+void RasterizerStorageRD::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region) {
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND(!rt);
+ if (!rt->backbuffer.is_valid()) {
+ _create_render_target_backbuffer(rt);
+ }
+
+ Rect2i region = p_region;
+ Rect2 blur_region;
+ if (region == Rect2i()) {
+ region.size = rt->size;
+ } else {
+ blur_region = region;
+ blur_region.position /= rt->size;
+ blur_region.size /= rt->size;
+ }
+
+ //single texture copy for backbuffer
+ RD::get_singleton()->texture_copy(rt->color, rt->backbuffer, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true);
+ //effects.copy(rt->color, rt->backbuffer_fb, blur_region);
+
+ //then mipmap blur
+ RID prev_texture = rt->color; //use color, not backbuffer, as bb has mipmaps.
+ Vector2 pixel_size = Vector2(1.0 / rt->size.width, 1.0 / rt->size.height);
+
+ for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
+ pixel_size *= 2.0; //go halfway
+ const RenderTarget::BackbufferMipmap &mm = rt->backbuffer_mipmaps[i];
+ effects.gaussian_blur(prev_texture, mm.mipmap_copy_fb, mm.mipmap_copy, mm.mipmap_fb, pixel_size, blur_region);
+ prev_texture = mm.mipmap;
+ }
+}
+
+RID RasterizerStorageRD::render_target_get_back_buffer_uniform_set(RID p_render_target, RID p_base_shader) {
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND_V(!rt, RID());
+
+ if (!rt->backbuffer.is_valid()) {
+ _create_render_target_backbuffer(rt);
+ }
+
+ if (rt->backbuffer_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rt->backbuffer_uniform_set)) {
+ return rt->backbuffer_uniform_set; //if still valid, return/reuse it.
+ }
+
+ //create otherwise
+ Vector<RD::Uniform> uniforms;
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 0;
+ u.ids.push_back(rt->backbuffer);
+ uniforms.push_back(u);
+
+ rt->backbuffer_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_base_shader, 3);
+ ERR_FAIL_COND_V(!rt->backbuffer_uniform_set.is_valid(), RID());
+
+ return rt->backbuffer_uniform_set;
+}
+
void RasterizerStorageRD::update_dirty_resources() {
_update_queued_materials();
}
@@ -1930,6 +2053,10 @@ bool RasterizerStorageRD::free(RID p_rid) {
return true;
}
+EffectsRD *RasterizerStorageRD::get_effects() {
+ return &effects;
+}
+
RasterizerStorageRD::RasterizerStorageRD() {
material_update_list = NULL;
diff --git a/servers/visual/rasterizer/rasterizer_storage_rd.h b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
index d875738481..c2f60c08b3 100644
--- a/servers/visual/rasterizer/rasterizer_storage_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
@@ -2,9 +2,11 @@
#define RASTERIZER_STORAGE_RD_H
#include "core/rid_owner.h"
-#include "servers/visual/rasterizer/rasterizer.h"
-#include "servers/visual/rasterizer/shader_compiler_rd.h"
+#include "servers/visual/rasterizer.h"
+#include "servers/visual/rasterizer_rd/effects_rd.h"
#include "servers/visual/rendering_device.h"
+#include "servers/visual/rasterizer_rd/shader_compiler_rd.h"
+
class RasterizerStorageRD : public RasterizerStorage {
public:
enum ShaderType {
@@ -168,6 +170,19 @@ private:
bool flags[RENDER_TARGET_FLAG_MAX];
+ RID backbuffer; //used for effects
+ RID backbuffer_fb;
+
+ struct BackbufferMipmap {
+ RID mipmap;
+ RID mipmap_fb;
+ RID mipmap_copy;
+ RID mipmap_copy_fb;
+ };
+
+ Vector<BackbufferMipmap> backbuffer_mipmaps;
+ RID backbuffer_uniform_set;
+
//texture generated for this owner (nor RD).
RID texture;
bool was_used;
@@ -181,6 +196,11 @@ private:
void _clear_render_target(RenderTarget *rt);
void _update_render_target(RenderTarget *rt);
+ void _create_render_target_backbuffer(RenderTarget *rt);
+
+ /* EFFECTS */
+
+ EffectsRD effects;
public:
/* TEXTURE API */
@@ -687,6 +707,8 @@ public:
void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value);
bool render_target_was_used(RID p_render_target);
void render_target_set_as_unused(RID p_render_target);
+ void render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region);
+ RID render_target_get_back_buffer_uniform_set(RID p_render_target, RID p_base_shader);
virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color);
virtual bool render_target_is_clear_requested(RID p_render_target);
@@ -723,6 +745,8 @@ public:
static RasterizerStorage *base_singleton;
+ EffectsRD *get_effects();
+
RasterizerStorageRD();
~RasterizerStorageRD();
};
diff --git a/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.cpp b/servers/visual/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp
index 2c2d6e9ca0..2108d14b2e 100644
--- a/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.cpp
+++ b/servers/visual/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp
@@ -10,7 +10,7 @@ RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_ve
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].vertex_id = p_vertex_format_id;
versions[version_count].pipeline = pipeline;
version_count++;
return pipeline;
@@ -33,6 +33,7 @@ void RenderPipelineVertexFormatCacheRD::_clear() {
void RenderPipelineVertexFormatCacheRD::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) {
ERR_FAIL_COND(p_shader.is_null());
+ _clear();
shader = p_shader;
render_primitive = p_primitive;
rasterization_state = p_rasterization_state;
diff --git a/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h b/servers/visual/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h
index cdbfda05f1..cdbfda05f1 100644
--- a/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h
+++ b/servers/visual/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h
diff --git a/servers/visual/rasterizer/shader_compiler_rd.cpp b/servers/visual/rasterizer_rd/shader_compiler_rd.cpp
index 789e4ca057..76b1a288e6 100644
--- a/servers/visual/rasterizer/shader_compiler_rd.cpp
+++ b/servers/visual/rasterizer_rd/shader_compiler_rd.cpp
@@ -681,6 +681,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
sampler_name = actions.custom_samplers[texture_uniform];
} else {
if (shader->uniforms.has(texture_uniform)) {
+ print_line("shader from texture uniform " + itos(shader->uniforms[texture_uniform].filter) + ", " + itos(shader->uniforms[texture_uniform].repeat));
sampler_name = _get_sampler_name(shader->uniforms[texture_uniform].filter, shader->uniforms[texture_uniform].repeat);
} else {
bool found = false;
diff --git a/servers/visual/rasterizer/shader_compiler_rd.h b/servers/visual/rasterizer_rd/shader_compiler_rd.h
index 3572a73a2d..3572a73a2d 100644
--- a/servers/visual/rasterizer/shader_compiler_rd.h
+++ b/servers/visual/rasterizer_rd/shader_compiler_rd.h
diff --git a/servers/visual/rasterizer/shader_rd.cpp b/servers/visual/rasterizer_rd/shader_rd.cpp
index f210908e39..d4b3db60ac 100644
--- a/servers/visual/rasterizer/shader_rd.cpp
+++ b/servers/visual/rasterizer_rd/shader_rd.cpp
@@ -303,6 +303,17 @@ void ShaderRD::version_set_code(RID p_version, const String &p_uniforms, const S
}
}
+bool ShaderRD::version_is_valid(RID p_version) {
+ Version *version = version_owner.getornull(p_version);
+ ERR_FAIL_COND_V(!version, false);
+
+ if (version->dirty) {
+ _compile_version(version);
+ }
+
+ return version->valid;
+}
+
bool ShaderRD::version_free(RID p_version) {
if (version_owner.owns(p_version)) {
diff --git a/servers/visual/rasterizer/shader_rd.h b/servers/visual/rasterizer_rd/shader_rd.h
index c7a8cdaa37..558675935d 100644
--- a/servers/visual/rasterizer/shader_rd.h
+++ b/servers/visual/rasterizer_rd/shader_rd.h
@@ -113,6 +113,8 @@ public:
return version->variants[p_variant];
}
+ bool version_is_valid(RID p_version);
+
bool version_free(RID p_version);
void initialize(const Vector<String> &p_variant_defines, const String &p_general_defines = "");
diff --git a/servers/visual/rasterizer/shaders/SCsub b/servers/visual/rasterizer_rd/shaders/SCsub
index 37290e997f..a8e1dafb47 100644
--- a/servers/visual/rasterizer/shaders/SCsub
+++ b/servers/visual/rasterizer_rd/shaders/SCsub
@@ -5,3 +5,4 @@ Import('env')
if 'RD_GLSL' in env['BUILDERS']:
env.RD_GLSL('canvas.glsl');
env.RD_GLSL('canvas_occlusion.glsl');
+ env.RD_GLSL('blur.glsl');
diff --git a/servers/visual/rasterizer_rd/shaders/blur.glsl b/servers/visual/rasterizer_rd/shaders/blur.glsl
new file mode 100644
index 0000000000..830d4d7d94
--- /dev/null
+++ b/servers/visual/rasterizer_rd/shaders/blur.glsl
@@ -0,0 +1,274 @@
+/* clang-format off */
+[vertex]
+/* clang-format on */
+
+#version 450
+
+/* clang-format off */
+VERSION_DEFINES
+/* clang-format on */
+
+#include "blur_inc.glsl"
+
+layout(location =0) out vec2 uv_interp;
+
+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];
+
+ if (bool(blur.flags&FLAG_USE_BLUR_SECTION)) {
+ uv_interp = blur.section.xy + uv_interp * blur.section.zw;
+ }
+
+ gl_Position = vec4( uv_interp *2.0 - 1.0, 0.0, 1.0);
+
+}
+
+/* clang-format off */
+[fragment]
+/* clang-format on */
+
+#version 450
+
+/* clang-format off */
+VERSION_DEFINES
+/* clang-format on */
+
+#include "blur_inc.glsl"
+
+layout(location =0) in vec2 uv_interp;
+
+layout( set=0, binding=0 ) uniform sampler2D source_color;
+
+#ifdef MODE_SSAO_MERGE
+layout( set=1, binding=0 ) uniform sampler2D source_ssao;
+#endif
+
+#ifdef GLOW_USE_AUTO_EXPOSURE
+layout( set=1, binding=0 ) uniform sampler2D source_auto_exposure;
+#endif
+
+
+layout(location = 0) out vec4 frag_color;
+
+//DOF
+#if defined(MODE_DOF_FAR_BLUR) || defined(MODE_DOF_NEAR_BLUR)
+
+layout( set=1, binding=0 ) uniform sampler2D dof_source_depth;
+
+#ifdef DOF_NEAR_BLUR_MERGE
+layout( set=2, binding=0 ) uniform sampler2D source_dof_original;
+#endif
+
+#ifdef DOF_QUALITY_LOW
+const int dof_kernel_size = 5;
+const int dof_kernel_from = 2;
+const float dof_kernel[5] = float[](0.153388, 0.221461, 0.250301, 0.221461, 0.153388);
+#endif
+
+#ifdef DOF_QUALITY_MEDIUM
+const int dof_kernel_size = 11;
+const int dof_kernel_from = 5;
+const float dof_kernel[11] = float[](0.055037, 0.072806, 0.090506, 0.105726, 0.116061, 0.119726, 0.116061, 0.105726, 0.090506, 0.072806, 0.055037);
+
+#endif
+
+#ifdef DOF_QUALITY_HIGH
+const int dof_kernel_size = 21;
+const int dof_kernel_from = 10;
+const float dof_kernel[21] = float[](0.028174, 0.032676, 0.037311, 0.041944, 0.046421, 0.050582, 0.054261, 0.057307, 0.059587, 0.060998, 0.061476, 0.060998, 0.059587, 0.057307, 0.054261, 0.050582, 0.046421, 0.041944, 0.037311, 0.032676, 0.028174);
+#endif
+
+#endif
+
+
+void main() {
+
+#ifdef MODE_GAUSSIAN_BLUR
+
+ //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect
+
+ if (bool(blur.flags&FLAG_HORIZONTAL)) {
+
+ vec2 pix_size = blur.pixel_size;
+ pix_size *= 0.5; //reading from larger buffer, so use more samples
+ vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.214607;
+ color += texture(source_color, uv_interp + vec2(1.0, 0.0) * pix_size) * 0.189879;
+ color += texture(source_color, uv_interp + vec2(2.0, 0.0) * pix_size) * 0.131514;
+ color += texture(source_color, uv_interp + vec2(3.0, 0.0) * pix_size) * 0.071303;
+ color += texture(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size) * 0.189879;
+ color += texture(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size) * 0.131514;
+ color += texture(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size) * 0.071303;
+ frag_color = color;
+ } else {
+
+ vec2 pix_size = blur.pixel_size;
+ vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.38774;
+ color += texture(source_color, uv_interp + vec2(0.0, 1.0) * pix_size) * 0.24477;
+ color += texture(source_color, uv_interp + vec2(0.0, 2.0) * pix_size) * 0.06136;
+ color += texture(source_color, uv_interp + vec2(0.0, -1.0) * pix_size) * 0.24477;
+ color += texture(source_color, uv_interp + vec2(0.0, -2.0) * pix_size) * 0.06136;
+ frag_color = color;
+ }
+#endif
+
+
+
+#ifdef MODE_GAUSSIAN_GLOW
+
+ //Glow uses larger sigma 1 for a more rounded blur effect
+
+ if (bool(blur.flags&FLAG_HORIZONTAL)) {
+
+ vec2 pix_size = blur.pixel_size;
+ pix_size *= 0.5; //reading from larger buffer, so use more samples
+ vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.174938;
+ color += texture(source_color, uv_interp + vec2(1.0, 0.0) * pix_size) * 0.165569;
+ color += texture(source_color, uv_interp + vec2(2.0, 0.0) * pix_size) * 0.140367;
+ color += texture(source_color, uv_interp + vec2(3.0, 0.0) * pix_size) * 0.106595;
+ color += texture(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size) * 0.165569;
+ color += texture(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size) * 0.140367;
+ color += texture(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size) * 0.106595;
+ color *= blur.glow_strength;
+ frag_color = color;
+ } else {
+
+ vec2 pix_size = blur.pixel_size;
+ vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.288713;
+ color += texture(source_color, uv_interp + vec2(0.0, 1.0) * pix_size) * 0.233062;
+ color += texture(source_color, uv_interp + vec2(0.0, 2.0) * pix_size) * 0.122581;
+ color += texture(source_color, uv_interp + vec2(0.0, -1.0) * pix_size) * 0.233062;
+ color += texture(source_color, uv_interp + vec2(0.0, -2.0) * pix_size) * 0.122581;
+ color *= blur.glow_strength;
+ frag_color = color;
+ }
+
+
+ if (bool(blur.flags&FLAG_GLOW_FIRST_PASS)) {
+#ifdef GLOW_USE_AUTO_EXPOSURE
+
+ frag_color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / blur.glow_auto_exposure_grey;
+#endif
+ frag_color *= blur.glow_exposure;
+
+ float luminance = max(frag_color.r, max(frag_color.g, frag_color.b));
+ float feedback = max(smoothstep(blur.glow_hdr_threshold, blur.glow_hdr_threshold + blur.glow_hdr_scale, luminance), blur.glow_bloom);
+
+ frag_color = min(frag_color * feedback, vec4(blur.glow_luminance_cap));
+ }
+
+
+#endif
+
+#ifdef MODE_DOF_FAR_BLUR
+
+ vec4 color_accum = vec4(0.0);
+
+ float depth = texture(dof_source_depth, uv_interp, 0.0).r;
+ depth = depth * 2.0 - 1.0;
+
+ if (bool(blur.flags&FLAG_USE_ORTHOGONAL_PROJECTION)) {
+ depth = ((depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0;
+ } else {
+ depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - depth * (blur.camera_z_far - blur.camera_z_near));
+ }
+
+ float amount = smoothstep(blur.dof_begin, blur.dof_end, depth);
+ float k_accum = 0.0;
+
+ for (int i = 0; i < dof_kernel_size; i++) {
+
+ int int_ofs = i - dof_kernel_from;
+ vec2 tap_uv = uv_interp + blur.dof_dir * float(int_ofs) * amount * blur.dof_radius;
+
+ float tap_k = dof_kernel[i];
+
+ float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r;
+ tap_depth = tap_depth * 2.0 - 1.0;
+
+ if (bool(blur.flags&FLAG_USE_ORTHOGONAL_PROJECTION)) {
+
+ tap_depth = ((tap_depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0;
+ } else {
+ tap_depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - tap_depth * (blur.camera_z_far - blur.camera_z_near));
+ }
+
+ float tap_amount = mix(smoothstep(blur.dof_begin, blur.dof_end, tap_depth), 1.0, int_ofs == 0);
+ tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect
+
+ vec4 tap_color = texture(source_color, tap_uv, 0.0) * tap_k;
+
+ k_accum += tap_k * tap_amount;
+ color_accum += tap_color * tap_amount;
+ }
+
+ if (k_accum > 0.0) {
+ color_accum /= k_accum;
+ }
+
+ frag_color = color_accum; ///k_accum;
+
+#endif
+
+#ifdef MODE_DOF_NEAR_BLUR
+
+ vec4 color_accum = vec4(0.0);
+
+ float max_accum = 0.0;
+
+ for (int i = 0; i < dof_kernel_size; i++) {
+
+ int int_ofs = i - dof_kernel_from;
+ vec2 tap_uv = uv_interp + blur.dof_dir * float(int_ofs) * blur.dof_radius;
+ float ofs_influence = max(0.0, 1.0 - float(abs(int_ofs)) / float(dof_kernel_from));
+
+ float tap_k = dof_kernel[i];
+
+ vec4 tap_color = texture(source_color, tap_uv, 0.0);
+
+ float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r;
+ tap_depth = tap_depth * 2.0 - 1.0;
+ if (bool(blur.flags&FLAG_USE_ORTHOGONAL_PROJECTION)) {
+
+ tap_depth = ((tap_depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0;
+ } else {
+ tap_depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - tap_depth * (blur.camera_z_far - blur.camera_z_near));
+ }
+ float tap_amount = 1.0 - smoothstep(blur.dof_end, blur.dof_begin, tap_depth);
+ tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect
+
+ if (bool(blur.flags&FLAG_DOF_NEAR_FIRST_TAP)) {
+ tap_color.a = 1.0 - smoothstep(blur.dof_end, blur.dof_begin, tap_depth);
+ }
+
+ max_accum = max(max_accum, tap_amount * ofs_influence);
+
+ color_accum += tap_color * tap_k;
+ }
+
+ color_accum.a = max(color_accum.a, sqrt(max_accum));
+
+#ifdef DOF_NEAR_BLUR_MERGE
+ {
+ vec4 original = texture(source_dof_original, uv_interp, 0.0);
+ color_accum = mix(original, color_accum, color_accum.a);
+ }
+#endif
+
+ if (bool(blur.flags&FLAG_DOF_NEAR_FIRST_TAP)) {
+ frag_color = color_accum;
+ }
+#endif
+
+#ifdef MODE_SIMPLE_COPY
+ vec4 color = texture(source_color, uv_interp, 0.0);
+ frag_color = color;
+#endif
+
+#ifdef MODE_SSAO_MERGE
+ vec4 color = texture(source_color, uv_interp, 0.0);
+ float ssao = texture(source_ssao, uv_interp, 0.0).r;
+ frag_color = vec4(mix(color.rgb, color.rgb * mix(blur.ssao_color.rgb, vec3(1.0), ssao), color.a), 1.0);
+#endif
+}
diff --git a/servers/visual/rasterizer_rd/shaders/blur_inc.glsl b/servers/visual/rasterizer_rd/shaders/blur_inc.glsl
new file mode 100644
index 0000000000..ea932130aa
--- /dev/null
+++ b/servers/visual/rasterizer_rd/shaders/blur_inc.glsl
@@ -0,0 +1,35 @@
+#define FLAG_HORIZONTAL (1<<0)
+#define FLAG_USE_BLUR_SECTION (1<<1)
+#define FLAG_USE_ORTHOGONAL_PROJECTION (1<<2)
+#define FLAG_DOF_NEAR_FIRST_TAP (1<<3)
+#define FLAG_GLOW_FIRST_PASS (1<<4)
+
+layout(push_constant, binding = 1, std430) uniform Blur {
+ vec4 section;
+ vec2 pixel_size;
+ uint flags;
+ uint pad;
+ //glow
+ float glow_strength;
+ float glow_bloom;
+ float glow_hdr_threshold;
+ float glow_hdr_scale;
+ float glow_exposure;
+ float glow_white;
+ float glow_luminance_cap;
+ float glow_auto_exposure_grey;
+ //dof
+ float dof_begin;
+ float dof_end;
+ float dof_radius;
+ float dof_pad;
+
+ vec2 dof_dir;
+ float camera_z_far;
+ float camera_z_near;
+
+ vec4 ssao_color;
+
+
+
+} blur;
diff --git a/servers/visual/rasterizer/shaders/canvas.glsl b/servers/visual/rasterizer_rd/shaders/canvas.glsl
index 00889f7345..63d2251465 100644
--- a/servers/visual/rasterizer/shaders/canvas.glsl
+++ b/servers/visual/rasterizer_rd/shaders/canvas.glsl
@@ -354,14 +354,8 @@ void main() {
#endif
-#if !defined(COLOR_USED)
- //default behavior, texture by color
-
color *= texture(sampler2D(color_texture,texture_sampler), uv);
-#endif
-
-
uint light_count = (draw_data.flags>>FLAGS_LIGHT_COUNT_SHIFT)&0xF; //max 16 lights
@@ -402,7 +396,7 @@ void main() {
#if defined(SCREEN_UV_USED)
- vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
+ vec2 screen_uv = gl_FragCoord.xy * canvas_data.screen_pixel_size;
#else
vec2 screen_uv = vec2(0.0);
#endif
diff --git a/servers/visual/rasterizer/shaders/canvas_occlusion.glsl b/servers/visual/rasterizer_rd/shaders/canvas_occlusion.glsl
index 01e87411d3..01e87411d3 100644
--- a/servers/visual/rasterizer/shaders/canvas_occlusion.glsl
+++ b/servers/visual/rasterizer_rd/shaders/canvas_occlusion.glsl
diff --git a/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl b/servers/visual/rasterizer_rd/shaders/canvas_uniforms_inc.glsl
index c8972a34bc..400c13ba68 100644
--- a/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl
+++ b/servers/visual/rasterizer_rd/shaders/canvas_uniforms_inc.glsl
@@ -1,5 +1,5 @@
-/* SET0: Draw Primitive */
+
#define M_PI 3.14159265359
@@ -25,6 +25,14 @@
#define FLAGS_DEFAULT_NORMAL_MAP_USED (1 << 26)
#define FLAGS_DEFAULT_SPECULAR_MAP_USED (1 << 27)
+// In vulkan, sets should always be ordered using the following logic:
+// Lower Sets: Sets that change format and layout less often
+// Higher sets: Sets that change format and layout very often
+// This is because changing a set for another with a different layout or format,
+// invalidates all the upper ones.
+
+/* SET0: Draw Primitive */
+
layout(push_constant, binding = 0, std430) uniform DrawData {
vec2 world_x;
vec2 world_y;
@@ -132,6 +140,6 @@ layout(set = 2, binding = 6) uniform sampler shadow_sampler;
#ifdef SCREEN_TEXTURE_USED
-layout(set = 3, binding = 1) uniform texture2D screen_texture;
+layout(set = 3, binding = 0) uniform texture2D screen_texture;
#endif
diff --git a/servers/visual/rendering_device.h b/servers/visual/rendering_device.h
index c9e2b9f820..fed2b0e79d 100644
--- a/servers/visual/rendering_device.h
+++ b/servers/visual/rendering_device.h
@@ -294,8 +294,9 @@ public:
TEXTURE_USAGE_STORAGE_ATOMIC_BIT = (1 << 4),
TEXTURE_USAGE_CPU_READ_BIT = (1 << 5),
TEXTURE_USAGE_CAN_UPDATE_BIT = (1 << 6),
- TEXTURE_USAGE_CAN_RETRIEVE_BIT = (1 << 7),
- TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT = (1 << 8),
+ TEXTURE_USAGE_CAN_COPY_FROM_BIT = (1 << 7),
+ TEXTURE_USAGE_CAN_COPY_TO_BIT = (1 << 8),
+ TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT = (1 << 9),
};
enum TextureSwizzle {
@@ -328,13 +329,12 @@ public:
depth = 1;
array_layers = 1;
mipmaps = 1;
- type = TEXTURE_TYPE_1D;
+ type = TEXTURE_TYPE_2D;
samples = TEXTURE_SAMPLES_1;
usage_bits = 0;
}
};
-
struct TextureView {
DataFormat format_override;
TextureSwizzle swizzle_r;
@@ -353,15 +353,16 @@ public:
virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<PoolVector<uint8_t> > &p_data = Vector<PoolVector<uint8_t> >()) = 0;
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture) = 0;
- virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture,int p_layer,int p_mipmap) = 0;
+ virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap) = 0;
virtual Error texture_update(RID p_texture, uint32_t p_layer, const PoolVector<uint8_t> &p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the begining of the frame, unless sync with draw is used, which is used to mix updates with draw calls
virtual PoolVector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer) = 0; // CPU textures will return immediately, while GPU textures will most likely force a flush
virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const = 0;
- virtual bool texture_is_shared(RID p_texture) =0;
+ virtual bool texture_is_shared(RID p_texture) = 0;
virtual bool texture_is_valid(RID p_texture) = 0;
+ virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, bool p_sync_with_draw = false) = 0;
/*********************/
/**** FRAMEBUFFER ****/
/*********************/
@@ -371,9 +372,9 @@ public:
TextureSamples samples;
uint32_t usage_flags;
AttachmentFormat() {
- format=DATA_FORMAT_R8G8B8A8_UNORM;
- samples=TEXTURE_SAMPLES_1;
- usage_flags=0;
+ format = DATA_FORMAT_R8G8B8A8_UNORM;
+ samples = TEXTURE_SAMPLES_1;
+ usage_flags = 0;
}
};
@@ -381,7 +382,7 @@ public:
// This ID is warranted to be unique for the same formats, does not need to be freed
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format) = 0;
- virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format) =0;
+ virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format) = 0;
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID) = 0;
@@ -563,7 +564,7 @@ public:
virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set) = 0;
virtual bool uniform_set_is_valid(RID p_uniform_set) = 0;
- virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size,const void *p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the begining of the frame, unless sync with draw is used, which is used to mix updates with draw calls
+ virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the begining of the frame, unless sync with draw is used, which is used to mix updates with draw calls
/*************************/
/**** RENDER PIPELINE ****/
@@ -824,7 +825,7 @@ public:
};
virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0;
- virtual bool render_pipeline_is_valid(RID p_pipeline) =0;
+ virtual bool render_pipeline_is_valid(RID p_pipeline) = 0;
/****************/
/**** SCREEN ****/
@@ -874,7 +875,6 @@ public:
virtual void draw_list_end() = 0;
-
/***************/
/**** FREE! ****/
/***************/
@@ -912,13 +912,13 @@ public:
LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES,
LIMIT_MAX_VERTEX_INPUT_BINDINGS,
LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE,
- LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT ,
+ LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
};
- virtual int limit_get(Limit p_limit) =0;
+ virtual int limit_get(Limit p_limit) = 0;
//methods below not exposed, used by RenderingDeviceRD
- virtual void prepare_screen_for_drawing() =0;
+ virtual void prepare_screen_for_drawing() = 0;
virtual void finalize_frame() = 0;
virtual void advance_frame() = 0;
diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h
index d87d40739f..c120a90314 100644
--- a/servers/visual/visual_server_canvas.h
+++ b/servers/visual/visual_server_canvas.h
@@ -31,7 +31,7 @@
#ifndef VISUALSERVERCANVAS_H
#define VISUALSERVERCANVAS_H
-#include "rasterizer/rasterizer.h"
+#include "rasterizer.h"
#include "visual_server_viewport.h"
class VisualServerCanvas {
diff --git a/servers/visual/visual_server_globals.h b/servers/visual/visual_server_globals.h
index 5bc76afe4c..5a9d365eca 100644
--- a/servers/visual/visual_server_globals.h
+++ b/servers/visual/visual_server_globals.h
@@ -31,7 +31,7 @@
#ifndef VISUAL_SERVER_GLOBALS_H
#define VISUAL_SERVER_GLOBALS_H
-#include "rasterizer/rasterizer.h"
+#include "rasterizer.h"
class VisualServerCanvas;
class VisualServerViewport;
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 08d4b7dc52..2122587304 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -32,7 +32,7 @@
#define VISUAL_SERVER_RASTER_H
#include "core/math/octree.h"
-#include "servers/visual/rasterizer/rasterizer.h"
+#include "servers/visual/rasterizer.h"
#include "servers/visual_server.h"
#include "visual_server_canvas.h"
#include "visual_server_globals.h"
diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h
index a4c3499359..d04cbf343a 100644
--- a/servers/visual/visual_server_scene.h
+++ b/servers/visual/visual_server_scene.h
@@ -31,7 +31,7 @@
#ifndef VISUALSERVERSCENE_H
#define VISUALSERVERSCENE_H
-#include "servers/visual/rasterizer/rasterizer.h"
+#include "servers/visual/rasterizer.h"
#include "core/math/geometry.h"
#include "core/math/octree.h"
diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h
index 4af22a4ad8..f701e3612a 100644
--- a/servers/visual/visual_server_viewport.h
+++ b/servers/visual/visual_server_viewport.h
@@ -33,7 +33,7 @@
#include "core/rid_owner.h"
#include "core/self_list.h"
-#include "rasterizer/rasterizer.h"
+#include "rasterizer.h"
#include "servers/arvr/arvr_interface.h"
#include "servers/visual_server.h"