Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finish implementing Canvas Background mode #68805

Merged
merged 1 commit into from
Nov 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions servers/rendering/renderer_rd/effects/copy_effects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,16 +510,18 @@ void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuff

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

copy_to_fb.push_constant.use_section = true;
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_USE_SECTION;
copy_to_fb.push_constant.section[0] = p_uv_rect.position.x;
copy_to_fb.push_constant.section[1] = p_uv_rect.position.y;
copy_to_fb.push_constant.section[2] = p_uv_rect.size.x;
copy_to_fb.push_constant.section[3] = p_uv_rect.size.y;

if (p_flip_y) {
copy_to_fb.push_constant.flip_y = true;
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y;
}

copy_to_fb.push_constant.luminance_multiplier = 1.0;

// setup our uniforms
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);

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

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) {
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) {
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
ERR_FAIL_NULL(uniform_set_cache);
MaterialStorage *material_storage = MaterialStorage::get_singleton();
ERR_FAIL_NULL(material_storage);

memset(&copy_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));
copy_to_fb.push_constant.luminance_multiplier = 1.0;

if (p_flip_y) {
copy_to_fb.push_constant.flip_y = true;
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y;
}
if (p_force_luminance) {
copy_to_fb.push_constant.force_luminance = true;
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FORCE_LUMINANCE;
}
if (p_alpha_to_zero) {
copy_to_fb.push_constant.alpha_to_zero = true;
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ZERO;
}
if (p_srgb) {
copy_to_fb.push_constant.srgb = true;
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_SRGB;
}
if (p_alpha_to_one) {
copy_to_fb.push_constant.alpha_to_one = true;
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ONE;
}
if (p_linear) {
// Used for copying to a linear buffer. In the mobile renderer we divide the contents of the linear buffer
// to allow for a wider effective range.
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_LINEAR;
copy_to_fb.push_constant.luminance_multiplier = prefer_raster_effects ? 2.0 : 1.0;
}

// setup our uniforms
Expand Down
21 changes: 13 additions & 8 deletions servers/rendering/renderer_rd/effects/copy_effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,21 @@ class CopyEffects {
COPY_TO_FB_MAX,
};

enum CopyToFBFlags {
COPY_TO_FB_FLAG_FLIP_Y = (1 << 0),
COPY_TO_FB_FLAG_USE_SECTION = (1 << 1),
COPY_TO_FB_FLAG_FORCE_LUMINANCE = (1 << 2),
COPY_TO_FB_FLAG_ALPHA_TO_ZERO = (1 << 3),
COPY_TO_FB_FLAG_SRGB = (1 << 4),
COPY_TO_FB_FLAG_ALPHA_TO_ONE = (1 << 5),
COPY_TO_FB_FLAG_LINEAR = (1 << 6),
};

struct CopyToFbPushConstant {
float section[4];
float pixel_size[2];
uint32_t flip_y;
uint32_t use_section;

uint32_t force_luminance;
uint32_t alpha_to_zero;
uint32_t srgb;
uint32_t alpha_to_one;
float luminance_multiplier;
uint32_t flags;

float set_color[4];
};
Expand Down Expand Up @@ -322,7 +327,7 @@ class CopyEffects {
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_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);
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);
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);
void copy_raster(RID p_source_texture, RID p_dest_framebuffer);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1765,6 +1765,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
draw_sky = true;
} break;
case RS::ENV_BG_CANVAS: {
if (rb.is_valid()) {
RID texture = RendererRD::TextureStorage::get_singleton()->render_target_get_rd_texture(rb->get_render_target());
copy_effects->copy_to_fb_rect(texture, color_only_framebuffer, Rect2i(), false, false, false, false, RID(), false, false, true);
}
keep_color = true;
} break;
case RS::ENV_BG_KEEP: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
draw_sky = true;
} break;
case RS::ENV_BG_CANVAS: {
if (rb.is_valid()) {
RID dest_framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_ONE_PASS);
RID texture = RendererRD::TextureStorage::get_singleton()->render_target_get_rd_texture(rb->get_render_target());
copy_effects->copy_to_fb_rect(texture, dest_framebuffer, Rect2i(), false, false, false, false, RID(), false, false, true);
}
keep_color = true;
} break;
case RS::ENV_BG_KEEP: {
Expand Down
55 changes: 34 additions & 21 deletions servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
#endif // has_VK_KHR_multiview
#endif //MULTIVIEW

#define FLAG_FLIP_Y (1 << 0)
#define FLAG_USE_SECTION (1 << 1)
#define FLAG_FORCE_LUMINANCE (1 << 2)
#define FLAG_ALPHA_TO_ZERO (1 << 3)
#define FLAG_SRGB (1 << 4)
#define FLAG_ALPHA_TO_ONE (1 << 5)
#define FLAG_LINEAR (1 << 6)

#ifdef MULTIVIEW
layout(location = 0) out vec3 uv_interp;
#else
Expand All @@ -22,13 +30,8 @@ layout(location = 0) out vec2 uv_interp;
layout(push_constant, std430) uniform Params {
vec4 section;
vec2 pixel_size;
bool flip_y;
bool use_section;

bool force_luminance;
bool alpha_to_zero;
bool srgb;
bool alpha_to_one;
float luminance_multiplier;
uint flags;

vec4 color;
}
Expand All @@ -41,13 +44,13 @@ void main() {
uv_interp.z = ViewIndex;
#endif
vec2 vpos = uv_interp.xy;
if (params.use_section) {
if (bool(params.flags & FLAG_USE_SECTION)) {
vpos = params.section.xy + vpos * params.section.zw;
}

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

if (params.flip_y) {
if (bool(params.flags & FLAG_FLIP_Y)) {
uv_interp.y = 1.0 - uv_interp.y;
}
}
Expand All @@ -67,16 +70,19 @@ void main() {
#endif // has_VK_KHR_multiview
#endif //MULTIVIEW

#define FLAG_FLIP_Y (1 << 0)
#define FLAG_USE_SECTION (1 << 1)
#define FLAG_FORCE_LUMINANCE (1 << 2)
#define FLAG_ALPHA_TO_ZERO (1 << 3)
#define FLAG_SRGB (1 << 4)
#define FLAG_ALPHA_TO_ONE (1 << 5)
#define FLAG_LINEAR (1 << 6)

layout(push_constant, std430) uniform Params {
vec4 section;
vec2 pixel_size;
bool flip_y;
bool use_section;

bool force_luminance;
bool alpha_to_zero;
bool srgb;
bool alpha_to_one;
float luminance_multiplier;
uint flags;

vec4 color;
}
Expand Down Expand Up @@ -110,6 +116,10 @@ vec3 linear_to_srgb(vec3 color) {
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)));
}

vec3 srgb_to_linear(vec3 color) {
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)));
}

void main() {
#ifdef MODE_SET_COLOR
frag_color = params.color;
Expand Down Expand Up @@ -165,19 +175,22 @@ void main() {
#endif /* MODE_TWO_SOURCES */
#endif /* MULTIVIEW */

if (params.force_luminance) {
if (bool(params.flags & FLAG_FORCE_LUMINANCE)) {
color.rgb = vec3(max(max(color.r, color.g), color.b));
}
if (params.alpha_to_zero) {
if (bool(params.flags & FLAG_ALPHA_TO_ZERO)) {
color.rgb *= color.a;
}
if (params.srgb) {
if (bool(params.flags & FLAG_SRGB)) {
color.rgb = linear_to_srgb(color.rgb);
}
if (params.alpha_to_one) {
if (bool(params.flags & FLAG_ALPHA_TO_ONE)) {
color.a = 1.0;
}
if (bool(params.flags & FLAG_LINEAR)) {
color.rgb = srgb_to_linear(color.rgb);
}

frag_color = color;
frag_color = color / params.luminance_multiplier;
#endif // MODE_SET_COLOR
}
2 changes: 1 addition & 1 deletion servers/rendering/renderer_scene_cull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3319,7 +3319,7 @@ void RendererSceneCull::render_empty_scene(const Ref<RenderSceneBuffers> &p_rend
RendererSceneRender::CameraData camera_data;
camera_data.set_camera(Transform3D(), Projection(), true, false);

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);
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);
#endif
}

Expand Down
3 changes: 3 additions & 0 deletions servers/rendering/renderer_viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,9 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
if (!can_draw_3d) {
RSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas);
} else {
// There may be an outstanding clear request if a clear was requested, but no 2D elements were drawn.
// Clear now otherwise we copy over garbage from the render target.
RSG::texture_storage->render_target_do_clear_request(p_viewport->render_target);
_draw_3d(p_viewport);
}
}
Expand Down