You've already forked godot
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:
@@ -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))) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user