Eevee: Implement Overscan option
This option make the internal render size larger than the output size in order to minimize screenspace effects disapearing at the render edges. The overscan size added around the render is the maximum dimension multiplied by the overscan percentage.
This commit is contained in:
parent
c6466ed0d2
commit
cde64619ca
|
@ -956,13 +956,21 @@ class RENDER_PT_eevee_film(RenderButtonsPanel, Panel):
|
|||
layout.use_property_split = True
|
||||
|
||||
scene = context.scene
|
||||
props = scene.eevee
|
||||
rd = scene.render
|
||||
|
||||
split = layout.split()
|
||||
split.prop(props, "use_overscan")
|
||||
row = split.row()
|
||||
row.active = props.use_overscan
|
||||
row.prop(props, "overscan_size", text="")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(rd, "filter_size")
|
||||
col.prop(rd, "alpha_mode", text="Alpha")
|
||||
|
||||
|
||||
|
||||
class RENDER_PT_eevee_hair(RenderButtonsPanel, Panel):
|
||||
bl_label = "Hair"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
|
|
@ -919,6 +919,8 @@ void BKE_scene_init(Scene *sce)
|
|||
|
||||
sce->eevee.light_cache = NULL;
|
||||
|
||||
sce->eevee.overscan = 0.3f;
|
||||
|
||||
sce->eevee.flag =
|
||||
SCE_EEVEE_VOLUMETRIC_LIGHTS |
|
||||
SCE_EEVEE_GTAO_BENT_NORMALS |
|
||||
|
|
|
@ -2226,4 +2226,12 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
| OB_EMPTY_IMAGE_VISIBLE_ORTHOGRAPHIC);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "SceneEEVEE", "float", "overscan")) {
|
||||
for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
|
||||
scene->eevee.overscan = 3.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -797,6 +797,8 @@ typedef struct EEVEE_PrivateData {
|
|||
float viewmat[4][4], viewinv[4][4];
|
||||
float winmat[4][4], wininv[4][4];
|
||||
float studiolight_matrix[3][3];
|
||||
float overscan, overscan_pixels;
|
||||
float size_orig[2];
|
||||
|
||||
/* Mist Settings */
|
||||
float mist_start, mist_inv_dist, mist_falloff;
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include "DNA_node_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BKE_camera.h"
|
||||
|
||||
#include "BLI_rand.h"
|
||||
#include "BLI_rect.h"
|
||||
|
||||
|
@ -54,6 +56,7 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
|
|||
EEVEE_FramebufferList *fbl = vedata->fbl;
|
||||
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
|
||||
Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||
const float *size_orig = DRW_viewport_size_get();
|
||||
|
||||
/* Init default FB and render targets:
|
||||
* In render mode the default framebuffer is not generated
|
||||
|
@ -62,6 +65,28 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
|
|||
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
/* Alloc transient data. */
|
||||
if (!stl->g_data) {
|
||||
stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
|
||||
}
|
||||
EEVEE_PrivateData *g_data = stl->g_data;
|
||||
g_data->background_alpha = DRW_state_draw_background() ? 1.0f : 0.0f;
|
||||
g_data->valid_double_buffer = 0;
|
||||
copy_v2_v2(g_data->size_orig, size_orig);
|
||||
|
||||
if (scene->eevee.flag & SCE_EEVEE_OVERSCAN) {
|
||||
g_data->overscan = scene->eevee.overscan / 100.0f;
|
||||
g_data->overscan_pixels = roundf(max_ff(size_orig[0], size_orig[1]) * g_data->overscan);
|
||||
}
|
||||
else {
|
||||
g_data->overscan = 0.0f;
|
||||
g_data->overscan_pixels = 0.0f;
|
||||
}
|
||||
|
||||
/* XXX overiding viewport size. Simplify things but is not really 100% safe. */
|
||||
DRW_render_viewport_size_set((int[2]){size_orig[0] + g_data->overscan_pixels * 2.0f,
|
||||
size_orig[1] + g_data->overscan_pixels * 2.0f});
|
||||
|
||||
/* TODO 32 bit depth */
|
||||
DRW_texture_ensure_fullscreen_2D(&dtxl->depth, GPU_DEPTH24_STENCIL8, 0);
|
||||
DRW_texture_ensure_fullscreen_2D(&txl->color, GPU_RGBA32F, DRW_TEX_FILTER | DRW_TEX_MIPMAP);
|
||||
|
@ -79,14 +104,6 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
|
|||
GPU_ATTACHMENT_TEXTURE(txl->color)
|
||||
});
|
||||
|
||||
/* Alloc transient data. */
|
||||
if (!stl->g_data) {
|
||||
stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
|
||||
}
|
||||
EEVEE_PrivateData *g_data = stl->g_data;
|
||||
g_data->background_alpha = DRW_state_draw_background() ? 1.0f : 0.0f;
|
||||
g_data->valid_double_buffer = 0;
|
||||
|
||||
/* Alloc common ubo data. */
|
||||
if (sldata->common_ubo == NULL) {
|
||||
sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data), &sldata->common_data);
|
||||
|
@ -102,6 +119,8 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
|
|||
RE_GetCameraWindow(engine->re, ob_camera_eval, frame, g_data->winmat);
|
||||
RE_GetCameraModelMatrix(engine->re, ob_camera_eval, g_data->viewinv);
|
||||
|
||||
RE_GetCameraWindowWithOverscan(engine->re, g_data->winmat, g_data->overscan);
|
||||
|
||||
invert_m4_m4(g_data->viewmat, g_data->viewinv);
|
||||
mul_m4_m4m4(g_data->persmat, g_data->winmat, g_data->viewmat);
|
||||
invert_m4_m4(g_data->persinv, g_data->persmat);
|
||||
|
@ -189,7 +208,8 @@ static void eevee_render_result_combined(
|
|||
|
||||
GPU_framebuffer_bind(vedata->stl->effects->final_fb);
|
||||
GPU_framebuffer_read_color(vedata->stl->effects->final_fb,
|
||||
rect->xmin, rect->ymin,
|
||||
vedata->stl->g_data->overscan_pixels + rect->xmin,
|
||||
vedata->stl->g_data->overscan_pixels + rect->ymin,
|
||||
BLI_rcti_size_x(rect), BLI_rcti_size_y(rect),
|
||||
4, 0, rp->rect);
|
||||
|
||||
|
@ -217,7 +237,8 @@ static void eevee_render_result_subsurface(
|
|||
|
||||
GPU_framebuffer_bind(vedata->fbl->sss_accum_fb);
|
||||
GPU_framebuffer_read_color(vedata->fbl->sss_accum_fb,
|
||||
rect->xmin, rect->ymin,
|
||||
vedata->stl->g_data->overscan_pixels + rect->xmin,
|
||||
vedata->stl->g_data->overscan_pixels + rect->ymin,
|
||||
BLI_rcti_size_x(rect), BLI_rcti_size_y(rect),
|
||||
3, 1, rp->rect);
|
||||
|
||||
|
@ -232,7 +253,8 @@ static void eevee_render_result_subsurface(
|
|||
|
||||
GPU_framebuffer_bind(vedata->fbl->sss_accum_fb);
|
||||
GPU_framebuffer_read_color(vedata->fbl->sss_accum_fb,
|
||||
rect->xmin, rect->ymin,
|
||||
vedata->stl->g_data->overscan_pixels + rect->xmin,
|
||||
vedata->stl->g_data->overscan_pixels + rect->ymin,
|
||||
BLI_rcti_size_x(rect), BLI_rcti_size_y(rect),
|
||||
3, 0, rp->rect);
|
||||
|
||||
|
@ -266,7 +288,8 @@ static void eevee_render_result_normal(
|
|||
|
||||
GPU_framebuffer_bind(vedata->fbl->main_fb);
|
||||
GPU_framebuffer_read_color(vedata->fbl->main_fb,
|
||||
rect->xmin, rect->ymin,
|
||||
g_data->overscan_pixels + rect->xmin,
|
||||
g_data->overscan_pixels + rect->ymin,
|
||||
BLI_rcti_size_x(rect), BLI_rcti_size_y(rect),
|
||||
3, 1, rp->rect);
|
||||
|
||||
|
@ -312,7 +335,8 @@ static void eevee_render_result_z(
|
|||
|
||||
GPU_framebuffer_bind(vedata->fbl->main_fb);
|
||||
GPU_framebuffer_read_depth(vedata->fbl->main_fb,
|
||||
rect->xmin, rect->ymin,
|
||||
g_data->overscan_pixels + rect->xmin,
|
||||
g_data->overscan_pixels + rect->ymin,
|
||||
BLI_rcti_size_x(rect), BLI_rcti_size_y(rect),
|
||||
rp->rect);
|
||||
|
||||
|
@ -348,7 +372,8 @@ static void eevee_render_result_mist(
|
|||
|
||||
GPU_framebuffer_bind(vedata->fbl->mist_accum_fb);
|
||||
GPU_framebuffer_read_color(vedata->fbl->mist_accum_fb,
|
||||
rect->xmin, rect->ymin,
|
||||
vedata->stl->g_data->overscan_pixels + rect->xmin,
|
||||
vedata->stl->g_data->overscan_pixels + rect->ymin,
|
||||
BLI_rcti_size_x(rect), BLI_rcti_size_y(rect),
|
||||
1, 0, rp->rect);
|
||||
|
||||
|
@ -376,7 +401,8 @@ static void eevee_render_result_occlusion(
|
|||
|
||||
GPU_framebuffer_bind(vedata->fbl->ao_accum_fb);
|
||||
GPU_framebuffer_read_color(vedata->fbl->ao_accum_fb,
|
||||
rect->xmin, rect->ymin,
|
||||
vedata->stl->g_data->overscan_pixels + rect->xmin,
|
||||
vedata->stl->g_data->overscan_pixels + rect->ymin,
|
||||
BLI_rcti_size_x(rect), BLI_rcti_size_y(rect),
|
||||
3, 0, rp->rect);
|
||||
|
||||
|
@ -561,6 +587,9 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
|
|||
eevee_render_result_subsurface(rl, viewname, rect, vedata, sldata, render_samples);
|
||||
eevee_render_result_mist(rl, viewname, rect, vedata, sldata, render_samples);
|
||||
eevee_render_result_occlusion(rl, viewname, rect, vedata, sldata, render_samples);
|
||||
|
||||
/* Restore original viewport size. */
|
||||
DRW_render_viewport_size_set((int[2]){g_data->size_orig[0], g_data->size_orig[1]});
|
||||
}
|
||||
|
||||
void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
|
||||
|
|
|
@ -1485,6 +1485,9 @@ typedef struct SceneEEVEE {
|
|||
|
||||
struct LightCache *light_cache;
|
||||
char light_cache_info[64];
|
||||
|
||||
float overscan;
|
||||
float pad;
|
||||
} SceneEEVEE;
|
||||
|
||||
/* *************************************************************** */
|
||||
|
@ -2192,6 +2195,7 @@ enum {
|
|||
SCE_EEVEE_SHOW_CUBEMAPS = (1 << 18),
|
||||
SCE_EEVEE_GI_AUTOBAKE = (1 << 19),
|
||||
SCE_EEVEE_SHADOW_SOFT = (1 << 20),
|
||||
SCE_EEVEE_OVERSCAN = (1 << 21),
|
||||
};
|
||||
|
||||
/* SceneEEVEE->shadow_method */
|
||||
|
|
|
@ -6022,6 +6022,23 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
|
|||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_ui_text(prop, "Soft Shadows", "Randomize shadowmaps origin to create soft shadows");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
|
||||
|
||||
/* Overscan */
|
||||
prop = RNA_def_property(srna, "use_overscan", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_OVERSCAN);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_ui_text(prop, "Overscan", "Internally render past the image border to avoid "
|
||||
"screen-space effects disapearing");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
|
||||
|
||||
prop = RNA_def_property(srna, "overscan_size", PROP_FLOAT, PROP_PERCENTAGE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "overscan");
|
||||
RNA_def_property_float_default(prop, 3.0f);
|
||||
RNA_def_property_ui_text(prop, "Overscan Size", "Percentage of render size to add as overscan to the "
|
||||
"internal render buffers");
|
||||
RNA_def_property_range(prop, 0.0f, 50.0f);
|
||||
RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 2);
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
|
||||
}
|
||||
|
||||
void RNA_def_scene(BlenderRNA *brna)
|
||||
|
|
|
@ -335,6 +335,7 @@ struct RenderPass *RE_pass_find_by_type(volatile struct RenderLayer *rl, int pas
|
|||
#define RE_BAKE_AO 2
|
||||
|
||||
void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]);
|
||||
void RE_GetCameraWindowWithOverscan(struct Render *re, float mat[4][4], float overscan);
|
||||
void RE_GetCameraModelMatrix(struct Render *re, struct Object *camera, float r_mat[4][4]);
|
||||
struct Scene *RE_GetScene(struct Render *re);
|
||||
void RE_SetScene(struct Render *re, struct Scene *sce);
|
||||
|
|
|
@ -195,6 +195,25 @@ void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, flo
|
|||
copy_m4_m4(mat, re->winmat);
|
||||
}
|
||||
|
||||
/* Must be called after RE_GetCameraWindow(), does not change re->winmat. */
|
||||
void RE_GetCameraWindowWithOverscan(struct Render *re, float mat[4][4], float overscan)
|
||||
{
|
||||
CameraParams params;
|
||||
params.is_ortho = re->winmat[3][3] != 0.0f;
|
||||
params.clipsta = re->clipsta;
|
||||
params.clipend = re->clipend;
|
||||
params.viewplane = re->viewplane;
|
||||
|
||||
overscan *= max_ff(BLI_rctf_size_x(¶ms.viewplane), BLI_rctf_size_y(¶ms.viewplane));
|
||||
|
||||
params.viewplane.xmin -= overscan;
|
||||
params.viewplane.xmax += overscan;
|
||||
params.viewplane.ymin -= overscan;
|
||||
params.viewplane.ymax += overscan;
|
||||
BKE_camera_params_compute_matrix(¶ms);
|
||||
copy_m4_m4(mat, params.winmat);
|
||||
}
|
||||
|
||||
void RE_GetCameraModelMatrix(Render *re, struct Object *camera, float r_mat[4][4])
|
||||
{
|
||||
BKE_camera_multiview_model_matrix(&re->r, camera, re->viewname, r_mat);
|
||||
|
|
Loading…
Reference in New Issue