Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/engines/workbench/workbench_deferred.c
| Show First 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | static struct { | ||||
| struct GPUShader *shadow_pass_manifold_sh; | struct GPUShader *shadow_pass_manifold_sh; | ||||
| struct GPUShader *shadow_caps_sh; | struct GPUShader *shadow_caps_sh; | ||||
| struct GPUShader *shadow_caps_manifold_sh; | struct GPUShader *shadow_caps_manifold_sh; | ||||
| struct GPUShader *oit_resolve_sh; | struct GPUShader *oit_resolve_sh; | ||||
| /* TODO(fclem) move everything below to wpd and custom viewlayer data. */ | /* TODO(fclem) move everything below to wpd and custom viewlayer data. */ | ||||
| struct GPUTexture *oit_accum_tx; /* ref only, not alloced */ | struct GPUTexture *oit_accum_tx; /* ref only, not alloced */ | ||||
| struct GPUTexture *oit_revealage_tx; /* ref only, not alloced */ | struct GPUTexture *oit_revealage_tx; /* ref only, not alloced */ | ||||
| struct GPUTexture *ghost_depth_tx; /* ref only, not alloced */ | |||||
| struct GPUTexture *object_id_tx; /* ref only, not alloced */ | struct GPUTexture *object_id_tx; /* ref only, not alloced */ | ||||
| struct GPUTexture *color_buffer_tx; /* ref only, not alloced */ | struct GPUTexture *color_buffer_tx; /* ref only, not alloced */ | ||||
| struct GPUTexture *cavity_buffer_tx; /* ref only, not alloced */ | struct GPUTexture *cavity_buffer_tx; /* ref only, not alloced */ | ||||
| struct GPUTexture *normal_buffer_tx; /* ref only, not alloced */ | struct GPUTexture *normal_buffer_tx; /* ref only, not alloced */ | ||||
| struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */ | struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */ | ||||
| SceneDisplay display; /* world light direction for shadows */ | SceneDisplay display; /* world light direction for shadows */ | ||||
| ▲ Show 20 Lines • Show All 491 Lines • ▼ Show 20 Lines | /* Prepass */ | ||||
| psl->ghost_prepass_pass = DRW_pass_create("Prepass Ghost", | psl->ghost_prepass_pass = DRW_pass_create("Prepass Ghost", | ||||
| (do_cull) ? state | DRW_STATE_CULL_BACK : state); | (do_cull) ? state | DRW_STATE_CULL_BACK : state); | ||||
| psl->ghost_prepass_hair_pass = DRW_pass_create("Prepass Ghost", state); | psl->ghost_prepass_hair_pass = DRW_pass_create("Prepass Ghost", state); | ||||
| psl->ghost_resolve_pass = DRW_pass_create("Resolve Ghost Depth", | psl->ghost_resolve_pass = DRW_pass_create("Resolve Ghost Depth", | ||||
| DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS); | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS); | ||||
| grp = DRW_shgroup_create(e_data.ghost_resolve_sh, psl->ghost_resolve_pass); | grp = DRW_shgroup_create(e_data.ghost_resolve_sh, psl->ghost_resolve_pass); | ||||
| DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.ghost_depth_tx); | DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth_in_front); | ||||
| DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL); | DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL); | ||||
| } | } | ||||
| { | { | ||||
| workbench_aa_create_pass(vedata, &e_data.color_buffer_tx); | workbench_aa_create_pass(vedata, &e_data.color_buffer_tx); | ||||
| } | } | ||||
| { | { | ||||
| Show All 22 Lines | if (CURVATURE_ENABLED(wpd)) { | ||||
| DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx); | DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx); | ||||
| DRW_shgroup_uniform_vec2(grp, "curvature_settings", &wpd->world_data.curvature_ridge, 1); | DRW_shgroup_uniform_vec2(grp, "curvature_settings", &wpd->world_data.curvature_ridge, 1); | ||||
| } | } | ||||
| DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL); | DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL); | ||||
| } | } | ||||
| } | } | ||||
| static void workbench_setup_ghost_framebuffer(WORKBENCH_FramebufferList *fbl) | |||||
| { | |||||
| const float *viewport_size = DRW_viewport_size_get(); | |||||
| const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; | |||||
| e_data.ghost_depth_tx = DRW_texture_pool_query_2d( | |||||
| size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_workbench_solid); | |||||
| GPU_framebuffer_ensure_config(&fbl->ghost_prepass_fb, | |||||
| { | |||||
| GPU_ATTACHMENT_TEXTURE(e_data.ghost_depth_tx), | |||||
| GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx), | |||||
| GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx), | |||||
| GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx), | |||||
| }); | |||||
| } | |||||
| void workbench_deferred_engine_free(void) | void workbench_deferred_engine_free(void) | ||||
| { | { | ||||
| for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) { | for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) { | ||||
| WORKBENCH_DEFERRED_Shaders *sh_data = &e_data.sh_data[sh_data_index]; | WORKBENCH_DEFERRED_Shaders *sh_data = &e_data.sh_data[sh_data_index]; | ||||
| for (int index = 0; index < MAX_PREPASS_SHADERS; index++) { | for (int index = 0; index < MAX_PREPASS_SHADERS; index++) { | ||||
| DRW_SHADER_FREE_SAFE(sh_data->prepass_sh_cache[index]); | DRW_SHADER_FREE_SAFE(sh_data->prepass_sh_cache[index]); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 563 Lines • ▼ Show 20 Lines | #endif | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void workbench_deferred_cache_finish(WORKBENCH_Data *UNUSED(vedata)) | void workbench_deferred_cache_finish(WORKBENCH_Data *vedata) | ||||
| { | { | ||||
| WORKBENCH_PassList *psl = vedata->psl; | |||||
| WORKBENCH_FramebufferList *fbl = vedata->fbl; | |||||
| if (GHOST_ENABLED(psl)) { | |||||
| /* HACK we allocate the infront depth here to avoid the overhead when if is not needed. */ | |||||
| DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); | |||||
| DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); | |||||
| DRW_texture_ensure_fullscreen_2d(&dtxl->depth_in_front, GPU_DEPTH24_STENCIL8, 0); | |||||
| GPU_framebuffer_ensure_config( | |||||
| &dfbl->default_fb, | |||||
| {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)}); | |||||
| GPU_framebuffer_ensure_config( | |||||
| &dfbl->in_front_fb, | |||||
| {GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front), GPU_ATTACHMENT_TEXTURE(dtxl->color)}); | |||||
| GPU_framebuffer_ensure_config(&fbl->ghost_prepass_fb, | |||||
| { | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front), | |||||
| GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx), | |||||
| GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx), | |||||
| GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx), | |||||
| }); | |||||
| } | |||||
| } | } | ||||
| void workbench_deferred_draw_background(WORKBENCH_Data *vedata) | void workbench_deferred_draw_background(WORKBENCH_Data *vedata) | ||||
| { | { | ||||
| WORKBENCH_StorageList *stl = vedata->stl; | WORKBENCH_StorageList *stl = vedata->stl; | ||||
| WORKBENCH_FramebufferList *fbl = vedata->fbl; | WORKBENCH_FramebufferList *fbl = vedata->fbl; | ||||
| WORKBENCH_PrivateData *wpd = stl->g_data; | WORKBENCH_PrivateData *wpd = stl->g_data; | ||||
| const float clear_depth = 1.0f; | const float clear_depth = 1.0f; | ||||
| Show All 17 Lines | |||||
| void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) | void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) | ||||
| { | { | ||||
| WORKBENCH_PassList *psl = vedata->psl; | WORKBENCH_PassList *psl = vedata->psl; | ||||
| WORKBENCH_StorageList *stl = vedata->stl; | WORKBENCH_StorageList *stl = vedata->stl; | ||||
| WORKBENCH_FramebufferList *fbl = vedata->fbl; | WORKBENCH_FramebufferList *fbl = vedata->fbl; | ||||
| WORKBENCH_PrivateData *wpd = stl->g_data; | WORKBENCH_PrivateData *wpd = stl->g_data; | ||||
| DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); | DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); | ||||
| DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); | |||||
| if (workbench_is_taa_enabled(wpd)) { | if (workbench_is_taa_enabled(wpd)) { | ||||
| workbench_taa_draw_scene_start(vedata); | workbench_taa_draw_scene_start(vedata); | ||||
| } | } | ||||
| /* clear in background */ | /* clear in background */ | ||||
| GPU_framebuffer_bind(fbl->prepass_fb); | GPU_framebuffer_bind(fbl->prepass_fb); | ||||
| DRW_draw_pass(psl->prepass_pass); | DRW_draw_pass(psl->prepass_pass); | ||||
| DRW_draw_pass(psl->prepass_hair_pass); | DRW_draw_pass(psl->prepass_hair_pass); | ||||
| if (GHOST_ENABLED(psl)) { | if (fbl->ghost_prepass_fb) { | ||||
| /* meh, late init to not request a depth buffer we won't use. */ | |||||
| workbench_setup_ghost_framebuffer(fbl); | |||||
| GPU_framebuffer_bind(fbl->ghost_prepass_fb); | GPU_framebuffer_bind(fbl->ghost_prepass_fb); | ||||
| GPU_framebuffer_clear_depth(fbl->ghost_prepass_fb, 1.0f); | GPU_framebuffer_clear_depth(fbl->ghost_prepass_fb, 1.0f); | ||||
| } | |||||
| else if (dtxl->depth_in_front) { | |||||
| /* TODO(fclem) This clear should be done in a global place. */ | |||||
| GPU_framebuffer_bind(dfbl->in_front_fb); | |||||
| GPU_framebuffer_clear_depth(dfbl->in_front_fb, 1.0f); | |||||
| } | |||||
| if (GHOST_ENABLED(psl)) { | |||||
| DRW_draw_pass(psl->ghost_prepass_pass); | DRW_draw_pass(psl->ghost_prepass_pass); | ||||
| DRW_draw_pass(psl->ghost_prepass_hair_pass); | DRW_draw_pass(psl->ghost_prepass_hair_pass); | ||||
| GPU_framebuffer_bind(dfbl->depth_only_fb); | GPU_framebuffer_bind(dfbl->depth_only_fb); | ||||
| DRW_draw_pass(psl->ghost_resolve_pass); | DRW_draw_pass(psl->ghost_resolve_pass); | ||||
| } | } | ||||
| if (CAVITY_ENABLED(wpd)) { | if (CAVITY_ENABLED(wpd)) { | ||||
| Show All 34 Lines | #endif | ||||
| else { | else { | ||||
| GPU_framebuffer_bind(fbl->composite_fb); | GPU_framebuffer_bind(fbl->composite_fb); | ||||
| DRW_draw_pass(psl->composite_pass); | DRW_draw_pass(psl->composite_pass); | ||||
| } | } | ||||
| /* In order to not draw on top of ghost objects, we clear the stencil | /* In order to not draw on top of ghost objects, we clear the stencil | ||||
| * to 0xFF and the ghost object to 0x00 and only draw overlays on top if | * to 0xFF and the ghost object to 0x00 and only draw overlays on top if | ||||
| * stencil is not 0. */ | * stencil is not 0. */ | ||||
| /* TODO(fclem) Remove this hack. */ | |||||
| GPU_framebuffer_bind(dfbl->depth_only_fb); | GPU_framebuffer_bind(dfbl->depth_only_fb); | ||||
| GPU_framebuffer_clear_stencil(dfbl->depth_only_fb, 0xFF); | GPU_framebuffer_clear_stencil(dfbl->depth_only_fb, 0xFF); | ||||
| /* TODO(fclem): only enable when needed (when there is overlays). */ | /* TODO(fclem): only enable when needed (when there is overlays). */ | ||||
| if (GHOST_ENABLED(psl)) { | if (GHOST_ENABLED(psl)) { | ||||
| DRWState state = DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS; | DRWState state = DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS; | ||||
| DRW_pass_state_set(psl->ghost_prepass_pass, state); | DRW_pass_state_set(psl->ghost_prepass_pass, state); | ||||
| DRW_pass_state_set(psl->ghost_prepass_hair_pass, state); | DRW_pass_state_set(psl->ghost_prepass_hair_pass, state); | ||||
| DRW_draw_pass(psl->ghost_prepass_pass); | DRW_draw_pass(psl->ghost_prepass_pass); | ||||
| DRW_draw_pass(psl->ghost_prepass_hair_pass); | DRW_draw_pass(psl->ghost_prepass_hair_pass); | ||||
| } | } | ||||
| GPU_framebuffer_bind(fbl->composite_fb); | GPU_framebuffer_bind(fbl->composite_fb); | ||||
| DRW_draw_pass(psl->background_pass); | DRW_draw_pass(psl->background_pass); | ||||
| if (OIT_ENABLED(wpd) && !DRW_pass_is_empty(psl->transparent_accum_pass)) { | if (OIT_ENABLED(wpd) && !DRW_pass_is_empty(psl->transparent_accum_pass)) { | ||||
| DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); | |||||
| /* meh, late init to not request buffers we won't use. */ | /* meh, late init to not request buffers we won't use. */ | ||||
| workbench_init_oit_framebuffer(fbl, dtxl); | workbench_init_oit_framebuffer(fbl, dtxl); | ||||
| const float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; | const float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; | ||||
| GPU_framebuffer_bind(fbl->transparent_accum_fb); | GPU_framebuffer_bind(fbl->transparent_accum_fb); | ||||
| GPU_framebuffer_clear_color(fbl->transparent_accum_fb, clear_color); | GPU_framebuffer_clear_color(fbl->transparent_accum_fb, clear_color); | ||||
| DRW_draw_pass(psl->transparent_accum_pass); | DRW_draw_pass(psl->transparent_accum_pass); | ||||
| Show All 22 Lines | |||||