Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/engines/eevee/eevee_render.c
| Show First 20 Lines • Show All 219 Lines • ▼ Show 20 Lines | GPU_framebuffer_read_color(vedata->stl->effects->final_fb, | ||||
| 0, | 0, | ||||
| rp->rect); | rp->rect); | ||||
| } | } | ||||
| static void eevee_render_result_subsurface(RenderLayer *rl, | static void eevee_render_result_subsurface(RenderLayer *rl, | ||||
| const char *viewname, | const char *viewname, | ||||
| const rcti *rect, | const rcti *rect, | ||||
| EEVEE_Data *vedata, | EEVEE_Data *vedata, | ||||
| EEVEE_ViewLayerData *UNUSED(sldata), | EEVEE_ViewLayerData *sldata, | ||||
| int render_samples) | int render_samples) | ||||
| { | { | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| ViewLayer *view_layer = draw_ctx->view_layer; | ViewLayer *view_layer = draw_ctx->view_layer; | ||||
| if (vedata->fbl->sss_accum_fb == NULL) { | if (vedata->fbl->sss_accum_fb == NULL) { | ||||
| /* SSS is not enabled. */ | /* SSS is not enabled. */ | ||||
| return; | return; | ||||
| } | } | ||||
| if ((view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) != 0) { | if ((view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) != 0) { | ||||
| RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_COLOR, viewname); | RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_COLOR, viewname); | ||||
| EEVEE_renderpass_postprocess( | |||||
| GPU_framebuffer_bind(vedata->fbl->sss_accum_fb); | sldata, vedata, SCE_PASS_SUBSURFACE_COLOR, vedata->fbl->renderpass_fb, render_samples); | ||||
| GPU_framebuffer_read_color(vedata->fbl->sss_accum_fb, | GPU_framebuffer_read_color(vedata->fbl->renderpass_fb, | ||||
| vedata->stl->g_data->overscan_pixels + rect->xmin, | vedata->stl->g_data->overscan_pixels + rect->xmin, | ||||
| vedata->stl->g_data->overscan_pixels + rect->ymin, | vedata->stl->g_data->overscan_pixels + rect->ymin, | ||||
| BLI_rcti_size_x(rect), | BLI_rcti_size_x(rect), | ||||
| BLI_rcti_size_y(rect), | BLI_rcti_size_y(rect), | ||||
| 3, | 3, | ||||
| 1, | 0, | ||||
| rp->rect); | rp->rect); | ||||
| /* This is the accumulated color. Divide by the number of samples. */ | |||||
| for (int i = 0; i < rp->rectx * rp->recty * 3; i++) { | |||||
| rp->rect[i] /= (float)render_samples; | |||||
| } | |||||
| } | } | ||||
| if ((view_layer->passflag & SCE_PASS_SUBSURFACE_DIRECT) != 0) { | if ((view_layer->passflag & SCE_PASS_SUBSURFACE_DIRECT) != 0) { | ||||
| RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_DIRECT, viewname); | RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_DIRECT, viewname); | ||||
| EEVEE_renderpass_postprocess( | |||||
| GPU_framebuffer_bind(vedata->fbl->sss_accum_fb); | sldata, vedata, SCE_PASS_SUBSURFACE_DIRECT, vedata->fbl->renderpass_fb, render_samples); | ||||
| GPU_framebuffer_read_color(vedata->fbl->sss_accum_fb, | GPU_framebuffer_read_color(vedata->fbl->renderpass_fb, | ||||
| vedata->stl->g_data->overscan_pixels + rect->xmin, | vedata->stl->g_data->overscan_pixels + rect->xmin, | ||||
| vedata->stl->g_data->overscan_pixels + rect->ymin, | vedata->stl->g_data->overscan_pixels + rect->ymin, | ||||
| BLI_rcti_size_x(rect), | BLI_rcti_size_x(rect), | ||||
| BLI_rcti_size_y(rect), | BLI_rcti_size_y(rect), | ||||
| 3, | 3, | ||||
| 0, | 0, | ||||
| rp->rect); | rp->rect); | ||||
| /* This is the accumulated color. Divide by the number of samples. */ | |||||
| for (int i = 0; i < rp->rectx * rp->recty * 3; i++) { | |||||
| rp->rect[i] /= (float)render_samples; | |||||
| } | |||||
| } | } | ||||
| if ((view_layer->passflag & SCE_PASS_SUBSURFACE_INDIRECT) != 0) { | if ((view_layer->passflag & SCE_PASS_SUBSURFACE_INDIRECT) != 0) { | ||||
| /* Do nothing as all the lighting is in the direct pass. | /* Do nothing as all the lighting is in the direct pass. | ||||
| * TODO : Separate Direct from indirect lighting. */ | * TODO : Separate Direct from indirect lighting. */ | ||||
| } | } | ||||
| } | } | ||||
| static void eevee_render_result_normal(RenderLayer *rl, | static void eevee_render_result_normal(RenderLayer *rl, | ||||
| const char *viewname, | const char *viewname, | ||||
| const rcti *rect, | const rcti *rect, | ||||
| EEVEE_Data *vedata, | EEVEE_Data *vedata, | ||||
| EEVEE_ViewLayerData *UNUSED(sldata)) | EEVEE_ViewLayerData *sldata) | ||||
| { | { | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| ViewLayer *view_layer = draw_ctx->view_layer; | ViewLayer *view_layer = draw_ctx->view_layer; | ||||
| EEVEE_StorageList *stl = vedata->stl; | EEVEE_StorageList *stl = vedata->stl; | ||||
| EEVEE_PrivateData *g_data = stl->g_data; | EEVEE_PrivateData *g_data = stl->g_data; | ||||
| /* Only read the center texel. */ | /* Only read the center texel. */ | ||||
| if (stl->effects->taa_current_sample > 1) { | if (stl->effects->taa_current_sample > 1) { | ||||
| return; | return; | ||||
| } | } | ||||
| if ((view_layer->passflag & SCE_PASS_NORMAL) != 0) { | if ((view_layer->passflag & SCE_PASS_NORMAL) != 0) { | ||||
| RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_NORMAL, viewname); | RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_NORMAL, viewname); | ||||
| EEVEE_renderpass_postprocess(sldata, vedata, SCE_PASS_NORMAL, vedata->fbl->renderpass_fb, 1); | |||||
| GPU_framebuffer_bind(vedata->fbl->main_fb); | GPU_framebuffer_read_color(vedata->fbl->renderpass_fb, | ||||
| GPU_framebuffer_read_color(vedata->fbl->main_fb, | |||||
| g_data->overscan_pixels + rect->xmin, | g_data->overscan_pixels + rect->xmin, | ||||
| g_data->overscan_pixels + rect->ymin, | g_data->overscan_pixels + rect->ymin, | ||||
| BLI_rcti_size_x(rect), | BLI_rcti_size_x(rect), | ||||
| BLI_rcti_size_y(rect), | BLI_rcti_size_y(rect), | ||||
| 3, | 3, | ||||
| 1, | 0, | ||||
| rp->rect); | rp->rect); | ||||
| float viewinv[4][4]; | |||||
| DRW_view_viewmat_get(NULL, viewinv, true); | |||||
| /* Convert Eevee encoded normals to Blender normals. */ | |||||
| for (int i = 0; i < rp->rectx * rp->recty * 3; i += 3) { | |||||
| if (rp->rect[i] == 0.0f && rp->rect[i + 1] == 0.0f) { | |||||
| /* If normal is not correct then do not produce NANs. */ | |||||
| continue; | |||||
| } | |||||
| float fenc[2]; | |||||
| fenc[0] = rp->rect[i + 0] * 4.0f - 2.0f; | |||||
| fenc[1] = rp->rect[i + 1] * 4.0f - 2.0f; | |||||
| float f = dot_v2v2(fenc, fenc); | |||||
| float g = sqrtf(1.0f - f / 4.0f); | |||||
| rp->rect[i + 0] = fenc[0] * g; | |||||
| rp->rect[i + 1] = fenc[1] * g; | |||||
| rp->rect[i + 2] = 1.0f - f / 2.0f; | |||||
| mul_mat3_m4_v3(viewinv, &rp->rect[i]); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| static void eevee_render_result_z(RenderLayer *rl, | static void eevee_render_result_z(RenderLayer *rl, | ||||
| const char *viewname, | const char *viewname, | ||||
| const rcti *rect, | const rcti *rect, | ||||
| EEVEE_Data *vedata, | EEVEE_Data *vedata, | ||||
| EEVEE_ViewLayerData *sldata) | EEVEE_ViewLayerData *sldata) | ||||
| { | { | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| ViewLayer *view_layer = draw_ctx->view_layer; | ViewLayer *view_layer = draw_ctx->view_layer; | ||||
| EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; | |||||
| EEVEE_StorageList *stl = vedata->stl; | EEVEE_StorageList *stl = vedata->stl; | ||||
| EEVEE_PrivateData *g_data = stl->g_data; | EEVEE_PrivateData *g_data = stl->g_data; | ||||
| /* Only read the center texel. */ | /* Only read the center texel. */ | ||||
| if (stl->effects->taa_current_sample > 1) { | if (stl->effects->taa_current_sample > 1) { | ||||
| return; | return; | ||||
| } | } | ||||
| if ((view_layer->passflag & SCE_PASS_Z) != 0) { | if ((view_layer->passflag & SCE_PASS_Z) != 0) { | ||||
| RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname); | RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname); | ||||
| EEVEE_renderpass_postprocess(sldata, vedata, SCE_PASS_Z, vedata->fbl->renderpass_fb, 1); | |||||
| GPU_framebuffer_bind(vedata->fbl->main_fb); | GPU_framebuffer_read_color(vedata->fbl->renderpass_fb, | ||||
| GPU_framebuffer_read_depth(vedata->fbl->main_fb, | |||||
| g_data->overscan_pixels + rect->xmin, | g_data->overscan_pixels + rect->xmin, | ||||
| g_data->overscan_pixels + rect->ymin, | g_data->overscan_pixels + rect->ymin, | ||||
| BLI_rcti_size_x(rect), | BLI_rcti_size_x(rect), | ||||
| BLI_rcti_size_y(rect), | BLI_rcti_size_y(rect), | ||||
| 1, | |||||
| 0, | |||||
| rp->rect); | rp->rect); | ||||
| bool is_persp = DRW_view_is_persp_get(NULL); | |||||
| float winmat[4][4]; | |||||
| DRW_view_winmat_get(NULL, winmat, false); | |||||
| /* Convert ogl depth [0..1] to view Z [near..far] */ | |||||
| for (int i = 0; i < rp->rectx * rp->recty; i++) { | |||||
| if (rp->rect[i] == 1.0f) { | |||||
| rp->rect[i] = 1e10f; /* Background */ | |||||
| } | |||||
| else { | |||||
| if (is_persp) { | |||||
| rp->rect[i] = rp->rect[i] * 2.0f - 1.0f; | |||||
| rp->rect[i] = winmat[3][2] / (rp->rect[i] + winmat[2][2]); | |||||
| } | |||||
| else { | |||||
| rp->rect[i] = -common_data->view_vecs[0][2] + | |||||
| rp->rect[i] * -common_data->view_vecs[1][2]; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| static void eevee_render_result_mist(RenderLayer *rl, | static void eevee_render_result_mist(RenderLayer *rl, | ||||
| const char *viewname, | const char *viewname, | ||||
| const rcti *rect, | const rcti *rect, | ||||
| EEVEE_Data *vedata, | EEVEE_Data *vedata, | ||||
| EEVEE_ViewLayerData *UNUSED(sldata), | EEVEE_ViewLayerData *sldata, | ||||
| int render_samples) | int render_samples) | ||||
| { | { | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| ViewLayer *view_layer = draw_ctx->view_layer; | ViewLayer *view_layer = draw_ctx->view_layer; | ||||
| if ((view_layer->passflag & SCE_PASS_MIST) != 0) { | if ((view_layer->passflag & SCE_PASS_MIST) != 0) { | ||||
| RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_MIST, viewname); | RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_MIST, viewname); | ||||
| EEVEE_renderpass_postprocess( | |||||
| GPU_framebuffer_bind(vedata->fbl->mist_accum_fb); | sldata, vedata, SCE_PASS_MIST, vedata->fbl->renderpass_fb, render_samples); | ||||
| GPU_framebuffer_read_color(vedata->fbl->mist_accum_fb, | GPU_framebuffer_read_color(vedata->fbl->renderpass_fb, | ||||
| vedata->stl->g_data->overscan_pixels + rect->xmin, | vedata->stl->g_data->overscan_pixels + rect->xmin, | ||||
| vedata->stl->g_data->overscan_pixels + rect->ymin, | vedata->stl->g_data->overscan_pixels + rect->ymin, | ||||
| BLI_rcti_size_x(rect), | BLI_rcti_size_x(rect), | ||||
| BLI_rcti_size_y(rect), | BLI_rcti_size_y(rect), | ||||
| 1, | 1, | ||||
| 0, | 0, | ||||
| rp->rect); | rp->rect); | ||||
| /* This is the accumulated color. Divide by the number of samples. */ | |||||
| for (int i = 0; i < rp->rectx * rp->recty; i++) { | |||||
| rp->rect[i] /= (float)render_samples; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| static void eevee_render_result_occlusion(RenderLayer *rl, | static void eevee_render_result_occlusion(RenderLayer *rl, | ||||
| const char *viewname, | const char *viewname, | ||||
| const rcti *rect, | const rcti *rect, | ||||
| EEVEE_Data *vedata, | EEVEE_Data *vedata, | ||||
| EEVEE_ViewLayerData *UNUSED(sldata), | EEVEE_ViewLayerData *sldata, | ||||
| int render_samples) | int render_samples) | ||||
| { | { | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| ViewLayer *view_layer = draw_ctx->view_layer; | ViewLayer *view_layer = draw_ctx->view_layer; | ||||
| if (vedata->fbl->ao_accum_fb == NULL) { | if (vedata->fbl->ao_accum_fb == NULL) { | ||||
| /* AO is not enabled. */ | /* AO is not enabled. */ | ||||
| return; | return; | ||||
| } | } | ||||
| if ((view_layer->passflag & SCE_PASS_AO) != 0) { | if ((view_layer->passflag & SCE_PASS_AO) != 0) { | ||||
| RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_AO, viewname); | RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_AO, viewname); | ||||
| EEVEE_renderpass_postprocess( | |||||
| GPU_framebuffer_bind(vedata->fbl->ao_accum_fb); | sldata, vedata, SCE_PASS_AO, vedata->fbl->renderpass_fb, render_samples); | ||||
| GPU_framebuffer_read_color(vedata->fbl->ao_accum_fb, | GPU_framebuffer_read_color(vedata->fbl->renderpass_fb, | ||||
| vedata->stl->g_data->overscan_pixels + rect->xmin, | vedata->stl->g_data->overscan_pixels + rect->xmin, | ||||
| vedata->stl->g_data->overscan_pixels + rect->ymin, | vedata->stl->g_data->overscan_pixels + rect->ymin, | ||||
| BLI_rcti_size_x(rect), | BLI_rcti_size_x(rect), | ||||
| BLI_rcti_size_y(rect), | BLI_rcti_size_y(rect), | ||||
| 3, | 3, | ||||
| 0, | 0, | ||||
| rp->rect); | rp->rect); | ||||
| /* This is the accumulated color. Divide by the number of samples. */ | |||||
| for (int i = 0; i < rp->rectx * rp->recty * 3; i += 3) { | |||||
| rp->rect[i] = rp->rect[i + 1] = rp->rect[i + 2] = min_ff( | |||||
| 1.0f, rp->rect[i] / (float)render_samples); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| static void eevee_render_draw_background(EEVEE_Data *vedata) | static void eevee_render_draw_background(EEVEE_Data *vedata) | ||||
| { | { | ||||
| EEVEE_FramebufferList *fbl = vedata->fbl; | EEVEE_FramebufferList *fbl = vedata->fbl; | ||||
| EEVEE_StorageList *stl = vedata->stl; | EEVEE_StorageList *stl = vedata->stl; | ||||
| EEVEE_PassList *psl = vedata->psl; | EEVEE_PassList *psl = vedata->psl; | ||||
| ▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl, const rcti *rect) | ||||
| GPU_framebuffer_bind(fbl->main_fb); | GPU_framebuffer_bind(fbl->main_fb); | ||||
| DRW_hair_update(); | DRW_hair_update(); | ||||
| if ((view_layer->passflag & (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT | | if ((view_layer->passflag & (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT | | ||||
| SCE_PASS_SUBSURFACE_INDIRECT)) != 0) { | SCE_PASS_SUBSURFACE_INDIRECT)) != 0) { | ||||
| EEVEE_subsurface_output_init(sldata, vedata); | EEVEE_subsurface_output_init(sldata, vedata); | ||||
| } | } | ||||
| /* check if we are requesting other render passes than the combined one. | |||||
| */ | |||||
| if ((view_layer->passflag & EEVEE_RENDERPASSES_WITH_POST_PROCESSING) != 0) { | |||||
| EEVEE_renderpass_init(vedata); | |||||
| } | |||||
| if ((view_layer->passflag & SCE_PASS_MIST) != 0) { | if ((view_layer->passflag & SCE_PASS_MIST) != 0) { | ||||
| EEVEE_mist_output_init(sldata, vedata); | EEVEE_mist_output_init(sldata, vedata); | ||||
| } | } | ||||
| if ((view_layer->passflag & SCE_PASS_AO) != 0) { | if ((view_layer->passflag & SCE_PASS_AO) != 0) { | ||||
| EEVEE_occlusion_output_init(sldata, vedata); | EEVEE_occlusion_output_init(sldata, vedata); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 150 Lines • Show Last 20 Lines | |||||