Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2018-10-31 20:31:14 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-10-31 20:32:54 +0300
commitcde64619cab3674dd4aa2d064406a71efbe2c4d7 (patch)
tree3b9c5df8cf4f2471aa1da33d2428665288d55c47 /source/blender
parentc6466ed0d2fc86d3a0c92acd07a154249921eaa6 (diff)
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.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/scene.c2
-rw-r--r--source/blender/blenloader/intern/versioning_280.c8
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h2
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c59
-rw-r--r--source/blender/makesdna/DNA_scene_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_scene.c17
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h1
-rw-r--r--source/blender/render/intern/source/initrender.c19
8 files changed, 97 insertions, 15 deletions
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 8fdf207ad68..60b542cd254 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -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 |
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index a726b32166b..21debc13a22 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -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;
+ }
+ }
+ }
}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index fbabf86074e..e732bc8d40d 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -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;
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 86c20ee54da..a2c44cbcd38 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -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)
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 9045fb4353d..ebdce500d31 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -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 */
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 8e7075ca91a..79f4312f589 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -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)
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index cc2bd01718a..614a1735f44 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -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);
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 828d626f9a7..1420b8feef7 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -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(&params.viewplane), BLI_rctf_size_y(&params.viewplane));
+
+ params.viewplane.xmin -= overscan;
+ params.viewplane.xmax += overscan;
+ params.viewplane.ymin -= overscan;
+ params.viewplane.ymax += overscan;
+ BKE_camera_params_compute_matrix(&params);
+ 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);