Skip to content

Commit 21ac6d7

Browse files
committed
Finish implementing Canvas Background mode
1 parent 49cc12b commit 21ac6d7

File tree

7 files changed

+77
-38
lines changed

7 files changed

+77
-38
lines changed

servers/rendering/renderer_rd/effects/copy_effects.cpp

+17-8
Original file line numberDiff line numberDiff line change
@@ -510,16 +510,18 @@ void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuff
510510

511511
memset(&copy_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));
512512

513-
copy_to_fb.push_constant.use_section = true;
513+
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_USE_SECTION;
514514
copy_to_fb.push_constant.section[0] = p_uv_rect.position.x;
515515
copy_to_fb.push_constant.section[1] = p_uv_rect.position.y;
516516
copy_to_fb.push_constant.section[2] = p_uv_rect.size.x;
517517
copy_to_fb.push_constant.section[3] = p_uv_rect.size.y;
518518

519519
if (p_flip_y) {
520-
copy_to_fb.push_constant.flip_y = true;
520+
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y;
521521
}
522522

523+
copy_to_fb.push_constant.luminance_multiplier = 1.0;
524+
523525
// setup our uniforms
524526
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
525527

@@ -537,28 +539,35 @@ void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuff
537539
RD::get_singleton()->draw_list_draw(draw_list, true);
538540
}
539541

540-
void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview, bool p_alpha_to_one) {
542+
void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview, bool p_alpha_to_one, bool p_linear) {
541543
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
542544
ERR_FAIL_NULL(uniform_set_cache);
543545
MaterialStorage *material_storage = MaterialStorage::get_singleton();
544546
ERR_FAIL_NULL(material_storage);
545547

546548
memset(&copy_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));
549+
copy_to_fb.push_constant.luminance_multiplier = 1.0;
547550

548551
if (p_flip_y) {
549-
copy_to_fb.push_constant.flip_y = true;
552+
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y;
550553
}
551554
if (p_force_luminance) {
552-
copy_to_fb.push_constant.force_luminance = true;
555+
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FORCE_LUMINANCE;
553556
}
554557
if (p_alpha_to_zero) {
555-
copy_to_fb.push_constant.alpha_to_zero = true;
558+
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ZERO;
556559
}
557560
if (p_srgb) {
558-
copy_to_fb.push_constant.srgb = true;
561+
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_SRGB;
559562
}
560563
if (p_alpha_to_one) {
561-
copy_to_fb.push_constant.alpha_to_one = true;
564+
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ONE;
565+
}
566+
if (p_linear) {
567+
// Used for copying to a linear buffer. In the mobile renderer we divide the contents of the linear buffer
568+
// to allow for a wider effective range.
569+
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_LINEAR;
570+
copy_to_fb.push_constant.luminance_multiplier = prefer_raster_effects ? 2.0 : 1.0;
562571
}
563572

564573
// setup our uniforms

servers/rendering/renderer_rd/effects/copy_effects.h

+13-8
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,21 @@ class CopyEffects {
181181
COPY_TO_FB_MAX,
182182
};
183183

184+
enum CopyToFBFlags {
185+
COPY_TO_FB_FLAG_FLIP_Y = (1 << 0),
186+
COPY_TO_FB_FLAG_USE_SECTION = (1 << 1),
187+
COPY_TO_FB_FLAG_FORCE_LUMINANCE = (1 << 2),
188+
COPY_TO_FB_FLAG_ALPHA_TO_ZERO = (1 << 3),
189+
COPY_TO_FB_FLAG_SRGB = (1 << 4),
190+
COPY_TO_FB_FLAG_ALPHA_TO_ONE = (1 << 5),
191+
COPY_TO_FB_FLAG_LINEAR = (1 << 6),
192+
};
193+
184194
struct CopyToFbPushConstant {
185195
float section[4];
186196
float pixel_size[2];
187-
uint32_t flip_y;
188-
uint32_t use_section;
189-
190-
uint32_t force_luminance;
191-
uint32_t alpha_to_zero;
192-
uint32_t srgb;
193-
uint32_t alpha_to_one;
197+
float luminance_multiplier;
198+
uint32_t flags;
194199

195200
float set_color[4];
196201
};
@@ -322,7 +327,7 @@ class CopyEffects {
322327
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);
323328
void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false);
324329
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);
325-
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, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false, bool alpha_to_one = false);
330+
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, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false, bool alpha_to_one = false, bool p_linear = false);
326331
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);
327332
void copy_raster(RID p_source_texture, RID p_dest_framebuffer);
328333

servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -1765,6 +1765,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
17651765
draw_sky = true;
17661766
} break;
17671767
case RS::ENV_BG_CANVAS: {
1768+
if (rb.is_valid()) {
1769+
RID texture = RendererRD::TextureStorage::get_singleton()->render_target_get_rd_texture(rb->get_render_target());
1770+
copy_effects->copy_to_fb_rect(texture, color_only_framebuffer, Rect2i(), false, false, false, false, RID(), false, false, true);
1771+
}
17681772
keep_color = true;
17691773
} break;
17701774
case RS::ENV_BG_KEEP: {

servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
796796
draw_sky = true;
797797
} break;
798798
case RS::ENV_BG_CANVAS: {
799+
if (rb.is_valid()) {
800+
RID dest_framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_ONE_PASS);
801+
RID texture = RendererRD::TextureStorage::get_singleton()->render_target_get_rd_texture(rb->get_render_target());
802+
copy_effects->copy_to_fb_rect(texture, dest_framebuffer, Rect2i(), false, false, false, false, RID(), false, false, true);
803+
}
799804
keep_color = true;
800805
} break;
801806
case RS::ENV_BG_KEEP: {

servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl

+34-21
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@
1313
#endif // has_VK_KHR_multiview
1414
#endif //MULTIVIEW
1515

16+
#define FLAG_FLIP_Y (1 << 0)
17+
#define FLAG_USE_SECTION (1 << 1)
18+
#define FLAG_FORCE_LUMINANCE (1 << 2)
19+
#define FLAG_ALPHA_TO_ZERO (1 << 3)
20+
#define FLAG_SRGB (1 << 4)
21+
#define FLAG_ALPHA_TO_ONE (1 << 5)
22+
#define FLAG_LINEAR (1 << 6)
23+
1624
#ifdef MULTIVIEW
1725
layout(location = 0) out vec3 uv_interp;
1826
#else
@@ -22,13 +30,8 @@ layout(location = 0) out vec2 uv_interp;
2230
layout(push_constant, std430) uniform Params {
2331
vec4 section;
2432
vec2 pixel_size;
25-
bool flip_y;
26-
bool use_section;
27-
28-
bool force_luminance;
29-
bool alpha_to_zero;
30-
bool srgb;
31-
bool alpha_to_one;
33+
float luminance_multiplier;
34+
uint flags;
3235

3336
vec4 color;
3437
}
@@ -41,13 +44,13 @@ void main() {
4144
uv_interp.z = ViewIndex;
4245
#endif
4346
vec2 vpos = uv_interp.xy;
44-
if (params.use_section) {
47+
if (bool(params.flags & FLAG_USE_SECTION)) {
4548
vpos = params.section.xy + vpos * params.section.zw;
4649
}
4750

4851
gl_Position = vec4(vpos * 2.0 - 1.0, 0.0, 1.0);
4952

50-
if (params.flip_y) {
53+
if (bool(params.flags & FLAG_FLIP_Y)) {
5154
uv_interp.y = 1.0 - uv_interp.y;
5255
}
5356
}
@@ -67,16 +70,19 @@ void main() {
6770
#endif // has_VK_KHR_multiview
6871
#endif //MULTIVIEW
6972

73+
#define FLAG_FLIP_Y (1 << 0)
74+
#define FLAG_USE_SECTION (1 << 1)
75+
#define FLAG_FORCE_LUMINANCE (1 << 2)
76+
#define FLAG_ALPHA_TO_ZERO (1 << 3)
77+
#define FLAG_SRGB (1 << 4)
78+
#define FLAG_ALPHA_TO_ONE (1 << 5)
79+
#define FLAG_LINEAR (1 << 6)
80+
7081
layout(push_constant, std430) uniform Params {
7182
vec4 section;
7283
vec2 pixel_size;
73-
bool flip_y;
74-
bool use_section;
75-
76-
bool force_luminance;
77-
bool alpha_to_zero;
78-
bool srgb;
79-
bool alpha_to_one;
84+
float luminance_multiplier;
85+
uint flags;
8086

8187
vec4 color;
8288
}
@@ -110,6 +116,10 @@ vec3 linear_to_srgb(vec3 color) {
110116
return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f)));
111117
}
112118

119+
vec3 srgb_to_linear(vec3 color) {
120+
return mix(pow((color.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), color.rgb * (1.0 / 12.92), lessThan(color.rgb, vec3(0.04045)));
121+
}
122+
113123
void main() {
114124
#ifdef MODE_SET_COLOR
115125
frag_color = params.color;
@@ -165,19 +175,22 @@ void main() {
165175
#endif /* MODE_TWO_SOURCES */
166176
#endif /* MULTIVIEW */
167177

168-
if (params.force_luminance) {
178+
if (bool(params.flags & FLAG_FORCE_LUMINANCE)) {
169179
color.rgb = vec3(max(max(color.r, color.g), color.b));
170180
}
171-
if (params.alpha_to_zero) {
181+
if (bool(params.flags & FLAG_ALPHA_TO_ZERO)) {
172182
color.rgb *= color.a;
173183
}
174-
if (params.srgb) {
184+
if (bool(params.flags & FLAG_SRGB)) {
175185
color.rgb = linear_to_srgb(color.rgb);
176186
}
177-
if (params.alpha_to_one) {
187+
if (bool(params.flags & FLAG_ALPHA_TO_ONE)) {
178188
color.a = 1.0;
179189
}
190+
if (bool(params.flags & FLAG_LINEAR)) {
191+
color.rgb = srgb_to_linear(color.rgb);
192+
}
180193

181-
frag_color = color;
194+
frag_color = color / params.luminance_multiplier;
182195
#endif // MODE_SET_COLOR
183196
}

servers/rendering/renderer_scene_cull.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -3319,7 +3319,7 @@ void RendererSceneCull::render_empty_scene(const Ref<RenderSceneBuffers> &p_rend
33193319
RendererSceneRender::CameraData camera_data;
33203320
camera_data.set_camera(Transform3D(), Projection(), true, false);
33213321

3322-
scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
3322+
scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), environment, RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
33233323
#endif
33243324
}
33253325

servers/rendering/renderer_viewport.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,9 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
550550
if (!can_draw_3d) {
551551
RSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas);
552552
} else {
553+
// There may be an outstanding clear request if a clear was requested, but no 2D elements were drawn.
554+
// Clear now otherwise we copy over garbage from the render target.
555+
RSG::texture_storage->render_target_do_clear_request(p_viewport->render_target);
553556
_draw_3d(p_viewport);
554557
}
555558
}

0 commit comments

Comments
 (0)