1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-22 15:06:45 +00:00

Optionally scale 3D render content

This commit is contained in:
Bastiaan Olij
2021-08-19 11:52:06 +10:00
parent 6e87d62873
commit 64626cc435
15 changed files with 184 additions and 34 deletions

View File

@@ -86,12 +86,13 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::clear() {
void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count) {
clear();
bool is_half_resolution = false; // Set this once we support this feature.
msaa = p_msaa;
Size2i target_size = RD::get_singleton()->texture_size(p_target_buffer);
width = p_width;
height = p_height;
bool is_scaled = (target_size.width != p_width) || (target_size.height != p_height);
view_count = p_view_count;
color = p_color_buffer;
@@ -124,7 +125,7 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b
passes.push_back(pass);
color_fbs[FB_CONFIG_THREE_SUBPASSES] = RD::get_singleton()->framebuffer_create_multipass(fb, passes, RenderingDevice::INVALID_ID, view_count);
if (!is_half_resolution) {
if (!is_scaled) {
// - add blit to 2D pass
fb.push_back(p_target_buffer); // 2 - target buffer
@@ -211,7 +212,7 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b
color_fbs[FB_CONFIG_ONE_PASS] = RD::get_singleton()->framebuffer_create_multipass(fb, one_pass_with_resolve, RenderingDevice::INVALID_ID, view_count);
}
if (!is_half_resolution) {
if (!is_scaled) {
// - add blit to 2D pass
fb.push_back(p_target_buffer); // 3 - target buffer
RD::FramebufferPass blit_pass;
@@ -497,7 +498,6 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
bool using_subpass_transparent = true;
bool using_subpass_post_process = true;
bool is_half_resolution = false; // Set this once we support this feature.
bool using_ssr = false; // I don't think we support this in our mobile renderer so probably should phase it out
bool using_sss = false; // I don't think we support this in our mobile renderer so probably should phase it out
@@ -518,7 +518,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
screen_size.x = render_buffer->width;
screen_size.y = render_buffer->height;
if (is_half_resolution) {
if (render_buffer->color_fbs[FB_CONFIG_FOUR_SUBPASSES].is_null()) {
// can't do blit subpass
using_subpass_post_process = false;
} else if (env && (env->glow_enabled || env->auto_exposure || camera_effects_uses_dof(p_render_data->camera_effects))) {

View File

@@ -2591,6 +2591,8 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
ERR_FAIL_COND_MSG(p_view_count == 0, "Must have at least 1 view");
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
// Should we add an overrule per viewport?
rb->width = p_width;
rb->height = p_height;
rb->render_target = p_render_target;
@@ -2637,8 +2639,8 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
tf.format = RD::DATA_FORMAT_R32_SFLOAT;
}
tf.width = p_width;
tf.height = p_height;
tf.width = rb->width;
tf.height = rb->height;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
tf.array_layers = rb->view_count; // create a layer for every view
@@ -2660,10 +2662,10 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
}
RID target_texture = storage->render_target_get_rd_texture(rb->render_target);
rb->data->configure(rb->texture, rb->depth_texture, target_texture, p_width, p_height, p_msaa, p_view_count);
rb->data->configure(rb->texture, rb->depth_texture, target_texture, rb->width, rb->height, p_msaa, p_view_count);
if (is_clustered_enabled()) {
rb->cluster_builder->setup(Size2i(p_width, p_height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture);
rb->cluster_builder->setup(Size2i(rb->width, rb->height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture);
}
}

View File

@@ -71,6 +71,44 @@ static Transform2D _canvas_get_transform(RendererViewport::Viewport *p_viewport,
return xf;
}
void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
if (p_viewport->render_buffers.is_valid()) {
if (p_viewport->size.width == 0 || p_viewport->size.height == 0) {
RSG::scene->free(p_viewport->render_buffers);
p_viewport->render_buffers = RID();
} else {
RS::ViewportScale3D scale_3d = p_viewport->scale_3d;
if (Engine::get_singleton()->is_editor_hint()) { // ignore this inside of the editor
scale_3d = RS::VIEWPORT_SCALE_3D_DISABLED;
}
int width = p_viewport->size.width;
int height = p_viewport->size.height;
switch (scale_3d) {
case RS::VIEWPORT_SCALE_3D_75_PERCENT: {
width = (width * 3) / 4;
height = (height * 3) / 4;
}; break;
case RS::VIEWPORT_SCALE_3D_50_PERCENT: {
width = width >> 1;
height = height >> 1;
}; break;
case RS::VIEWPORT_SCALE_3D_33_PERCENT: {
width = width / 3;
height = height / 3;
}; break;
case RS::VIEWPORT_SCALE_3D_25_PERCENT: {
width = width >> 2;
height = height >> 2;
}; break;
default:
break;
}
RSG::scene->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, width, height, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_debanding, p_viewport->get_view_count());
}
}
}
void RendererViewport::_draw_3d(Viewport *p_viewport) {
RENDER_TIMESTAMP(">Begin Rendering 3D Scene");
@@ -100,7 +138,7 @@ void RendererViewport::_draw_3d(Viewport *p_viewport) {
RENDER_TIMESTAMP("<End Rendering 3D Scene");
}
void RendererViewport::_draw_viewport(Viewport *p_viewport, uint32_t p_view_count) {
void RendererViewport::_draw_viewport(Viewport *p_viewport) {
if (p_viewport->measure_render_time) {
String rt_id = "vp_begin_" + itos(p_viewport->self.get_id());
RSG::storage->capture_timestamp(rt_id);
@@ -142,7 +180,8 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport, uint32_t p_view_coun
if ((scenario_draw_canvas_bg || can_draw_3d) && !p_viewport->render_buffers.is_valid()) {
//wants to draw 3D but there is no render buffer, create
p_viewport->render_buffers = RSG::scene->render_buffers_create();
RSG::scene->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_debanding, p_view_count);
_configure_3d_render_buffers(p_viewport);
}
RSG::storage->render_target_request_clear(p_viewport->render_target, bgcolor);
@@ -556,7 +595,7 @@ void RendererViewport::draw_viewports() {
RSG::scene->set_debug_draw_mode(vp->debug_draw);
// and draw viewport
_draw_viewport(vp, view_count);
_draw_viewport(vp);
// measure
@@ -580,7 +619,7 @@ void RendererViewport::draw_viewports() {
RSG::scene->set_debug_draw_mode(vp->debug_draw);
// render standard mono camera
_draw_viewport(vp, 1);
_draw_viewport(vp);
if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID && (!vp->viewport_render_direct_to_screen || !RSG::rasterizer->is_low_end())) {
//copy to screen if set as such
@@ -648,9 +687,19 @@ void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) {
}
viewport->use_xr = p_use_xr;
if (viewport->render_buffers.is_valid()) {
RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, viewport->use_debanding, viewport->get_view_count());
_configure_3d_render_buffers(viewport);
}
void RendererViewport::viewport_set_scale_3d(RID p_viewport, RenderingServer::ViewportScale3D p_scale_3d) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
if (viewport->scale_3d == p_scale_3d) {
return;
}
viewport->scale_3d = p_scale_3d;
_configure_3d_render_buffers(viewport);
}
uint32_t RendererViewport::Viewport::get_view_count() {
@@ -677,14 +726,7 @@ void RendererViewport::viewport_set_size(RID p_viewport, int p_width, int p_heig
viewport->size = Size2(p_width, p_height);
uint32_t view_count = viewport->get_view_count();
RSG::storage->render_target_set_size(viewport->render_target, p_width, p_height, view_count);
if (viewport->render_buffers.is_valid()) {
if (p_width == 0 || p_height == 0) {
RSG::scene->free(viewport->render_buffers);
viewport->render_buffers = RID();
} else {
RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, viewport->use_debanding, view_count);
}
}
_configure_3d_render_buffers(viewport);
viewport->occlusion_buffer_dirty = true;
}
@@ -915,9 +957,7 @@ void RendererViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa
return;
}
viewport->msaa = p_msaa;
if (viewport->render_buffers.is_valid()) {
RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa, viewport->screen_space_aa, viewport->use_debanding, viewport->get_view_count());
}
_configure_3d_render_buffers(viewport);
}
void RendererViewport::viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode) {
@@ -928,9 +968,7 @@ void RendererViewport::viewport_set_screen_space_aa(RID p_viewport, RS::Viewport
return;
}
viewport->screen_space_aa = p_mode;
if (viewport->render_buffers.is_valid()) {
RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, p_mode, viewport->use_debanding, viewport->get_view_count());
}
_configure_3d_render_buffers(viewport);
}
void RendererViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_debanding) {
@@ -941,9 +979,7 @@ void RendererViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_deb
return;
}
viewport->use_debanding = p_use_debanding;
if (viewport->render_buffers.is_valid()) {
RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, p_use_debanding, viewport->get_view_count());
}
_configure_3d_render_buffers(viewport);
}
void RendererViewport::viewport_set_use_occlusion_culling(RID p_viewport, bool p_use_occlusion_culling) {

View File

@@ -49,6 +49,8 @@ public:
bool use_xr; /* use xr interface to override camera positioning and projection matrices and control output */
RS::ViewportScale3D scale_3d = RenderingServer::VIEWPORT_SCALE_3D_DISABLED;
Size2i size;
RID camera;
RID scenario;
@@ -192,8 +194,9 @@ public:
int total_draw_calls_used = 0;
private:
void _configure_3d_render_buffers(Viewport *p_viewport);
void _draw_3d(Viewport *p_viewport);
void _draw_viewport(Viewport *p_viewport, uint32_t p_view_count = 1);
void _draw_viewport(Viewport *p_viewport);
int occlusion_rays_per_thread = 512;
@@ -204,6 +207,7 @@ public:
void viewport_initialize(RID p_rid);
void viewport_set_use_xr(RID p_viewport, bool p_use_xr);
void viewport_set_scale_3d(RID p_viewport, RenderingServer::ViewportScale3D p_scale_3d);
void viewport_set_size(RID p_viewport, int p_width, int p_height);

View File

@@ -495,6 +495,7 @@ public:
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_valid(RID p_texture) = 0;
virtual Size2i texture_size(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, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;

View File

@@ -526,6 +526,7 @@ public:
FUNCRIDSPLIT(viewport)
FUNC2(viewport_set_use_xr, RID, bool)
FUNC2(viewport_set_scale_3d, RID, ViewportScale3D)
FUNC3(viewport_set_size, RID, int, int)
FUNC2(viewport_set_active, RID, bool)