Differential D10414 Diff 33970 source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
| Show First 20 Lines • Show All 258 Lines • ▼ Show 20 Lines | else { | ||||
| DRW_TEXTURE_FREE_SAFE(txl->history_buffer_tx); | DRW_TEXTURE_FREE_SAFE(txl->history_buffer_tx); | ||||
| DRW_TEXTURE_FREE_SAFE(txl->depth_buffer_tx); | DRW_TEXTURE_FREE_SAFE(txl->depth_buffer_tx); | ||||
| DRW_TEXTURE_FREE_SAFE(txl->depth_buffer_in_front_tx); | DRW_TEXTURE_FREE_SAFE(txl->depth_buffer_in_front_tx); | ||||
| DRW_TEXTURE_FREE_SAFE(txl->smaa_search_tx); | DRW_TEXTURE_FREE_SAFE(txl->smaa_search_tx); | ||||
| DRW_TEXTURE_FREE_SAFE(txl->smaa_area_tx); | DRW_TEXTURE_FREE_SAFE(txl->smaa_area_tx); | ||||
| } | } | ||||
| } | } | ||||
| static float filter_blackman_harris(float x, const float width) | |||||
| { | |||||
| if (x > width * 0.5f) { | |||||
| return 0.0f; | |||||
| } | |||||
| x = 2.0f * M_PI * clamp_f((x / width + 0.5f), 0.0f, 1.0f); | |||||
| return 0.35875f - 0.48829f * cosf(x) + 0.14128f * cosf(2.0f * x) - 0.01168f * cosf(3.0f * x); | |||||
| } | |||||
| /* Compute weights for the 3x3 neighborhood using a 1.5px filter. */ | |||||
| static void workbench_antialiasing_weights_get(const float offset[2], | |||||
| float r_weights[9], | |||||
| float *r_weight_sum) | |||||
| { | |||||
| /* NOTE: If filter width is bigger than 2.0f, then we need to sample more neighborhood. */ | |||||
| const float filter_width = 2.0f; | |||||
| *r_weight_sum = 0.0f; | |||||
| int i = 0; | |||||
| for (int x = -1; x <= 1; x++) { | |||||
| for (int y = -1; y <= 1; y++, i++) { | |||||
| float sample_co[2] = {x, y}; | |||||
| add_v2_v2(sample_co, offset); | |||||
| float r = len_v2(sample_co); | |||||
| /* fclem: is radial distance ok here? */ | |||||
| float weight = filter_blackman_harris(r, filter_width); | |||||
| *r_weight_sum += weight; | |||||
| r_weights[i] = weight; | |||||
| } | |||||
| } | |||||
| } | |||||
| void workbench_antialiasing_cache_init(WORKBENCH_Data *vedata) | void workbench_antialiasing_cache_init(WORKBENCH_Data *vedata) | ||||
| { | { | ||||
| WORKBENCH_TextureList *txl = vedata->txl; | WORKBENCH_TextureList *txl = vedata->txl; | ||||
| WORKBENCH_PrivateData *wpd = vedata->stl->wpd; | WORKBENCH_PrivateData *wpd = vedata->stl->wpd; | ||||
| WORKBENCH_PassList *psl = vedata->psl; | WORKBENCH_PassList *psl = vedata->psl; | ||||
| DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); | DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); | ||||
| DRWShadingGroup *grp = NULL; | DRWShadingGroup *grp = NULL; | ||||
| if (wpd->taa_sample_len == 0) { | if (wpd->taa_sample_len == 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| { | { | ||||
| DRW_PASS_CREATE(psl->aa_accum_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL); | DRW_PASS_CREATE(psl->aa_accum_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL); | ||||
| DRW_PASS_INSTANCE_CREATE(psl->aa_accum_replace_ps, psl->aa_accum_ps, DRW_STATE_WRITE_COLOR); | |||||
| GPUShader *shader = workbench_shader_antialiasing_accumulation_get(); | GPUShader *shader = workbench_shader_antialiasing_accumulation_get(); | ||||
| grp = DRW_shgroup_create(shader, psl->aa_accum_ps); | grp = DRW_shgroup_create(shader, psl->aa_accum_ps); | ||||
| DRW_shgroup_uniform_texture(grp, "colorBuffer", dtxl->color); | DRW_shgroup_uniform_texture_ex(grp, "colorBuffer", dtxl->color, GPU_SAMPLER_DEFAULT); | ||||
| DRW_shgroup_uniform_float(grp, "samplesWeights", wpd->taa_weights, 9); | |||||
| DRW_shgroup_call_procedural_triangles(grp, NULL, 1); | DRW_shgroup_call_procedural_triangles(grp, NULL, 1); | ||||
| } | } | ||||
| const float *size = DRW_viewport_size_get(); | const float *size = DRW_viewport_size_get(); | ||||
| const float *sizeinv = DRW_viewport_invert_size_get(); | const float *sizeinv = DRW_viewport_invert_size_get(); | ||||
| const float metrics[4] = {sizeinv[0], sizeinv[1], size[0], size[1]}; | const float metrics[4] = {sizeinv[0], sizeinv[1], size[0], size[1]}; | ||||
| { | { | ||||
| Show All 27 Lines | const float metrics[4] = {sizeinv[0], sizeinv[1], size[0], size[1]}; | ||||
| DRW_PASS_CREATE(psl->aa_resolve_ps, DRW_STATE_WRITE_COLOR); | DRW_PASS_CREATE(psl->aa_resolve_ps, DRW_STATE_WRITE_COLOR); | ||||
| GPUShader *sh = workbench_shader_antialiasing_get(2); | GPUShader *sh = workbench_shader_antialiasing_get(2); | ||||
| grp = DRW_shgroup_create(sh, psl->aa_resolve_ps); | grp = DRW_shgroup_create(sh, psl->aa_resolve_ps); | ||||
| DRW_shgroup_uniform_texture(grp, "blendTex", wpd->smaa_weight_tx); | DRW_shgroup_uniform_texture(grp, "blendTex", wpd->smaa_weight_tx); | ||||
| DRW_shgroup_uniform_texture(grp, "colorTex", txl->history_buffer_tx); | DRW_shgroup_uniform_texture(grp, "colorTex", txl->history_buffer_tx); | ||||
| DRW_shgroup_uniform_vec4_copy(grp, "viewportMetrics", metrics); | DRW_shgroup_uniform_vec4_copy(grp, "viewportMetrics", metrics); | ||||
| DRW_shgroup_uniform_float(grp, "mixFactor", &wpd->smaa_mix_factor, 1); | DRW_shgroup_uniform_float(grp, "mixFactor", &wpd->smaa_mix_factor, 1); | ||||
| DRW_shgroup_uniform_float(grp, "taaSampleCountInv", &wpd->taa_sample_inv, 1); | DRW_shgroup_uniform_float(grp, "taaAccumulatedWeight", &wpd->taa_weight_accum, 1); | ||||
| DRW_shgroup_call_procedural_triangles(grp, NULL, 1); | DRW_shgroup_call_procedural_triangles(grp, NULL, 1); | ||||
| } | } | ||||
| } | } | ||||
| /* Return true if render is not cached. */ | /* Return true if render is not cached. */ | ||||
| bool workbench_antialiasing_setup(WORKBENCH_Data *vedata) | bool workbench_antialiasing_setup(WORKBENCH_Data *vedata) | ||||
| { | { | ||||
| Show All 27 Lines | switch (wpd->taa_sample_len) { | ||||
| case 16: | case 16: | ||||
| transform_offset = e_data.jitter_16[min_ii(wpd->taa_sample, 16)]; | transform_offset = e_data.jitter_16[min_ii(wpd->taa_sample, 16)]; | ||||
| break; | break; | ||||
| case 32: | case 32: | ||||
| transform_offset = e_data.jitter_32[min_ii(wpd->taa_sample, 32)]; | transform_offset = e_data.jitter_32[min_ii(wpd->taa_sample, 32)]; | ||||
| break; | break; | ||||
| } | } | ||||
| workbench_antialiasing_weights_get(transform_offset, wpd->taa_weights, &wpd->taa_weights_sum); | |||||
| /* construct new matrices from transform delta */ | /* construct new matrices from transform delta */ | ||||
| float winmat[4][4], viewmat[4][4], persmat[4][4]; | float winmat[4][4], viewmat[4][4], persmat[4][4]; | ||||
| DRW_view_winmat_get(default_view, winmat, false); | DRW_view_winmat_get(default_view, winmat, false); | ||||
| DRW_view_viewmat_get(default_view, viewmat, false); | DRW_view_viewmat_get(default_view, viewmat, false); | ||||
| DRW_view_persmat_get(default_view, persmat, false); | DRW_view_persmat_get(default_view, persmat, false); | ||||
| window_translate_m4(winmat, | window_translate_m4(winmat, | ||||
| persmat, | persmat, | ||||
| Show All 34 Lines | void workbench_antialiasing_draw_pass(WORKBENCH_Data *vedata) | ||||
| * We always do SMAA on top of TAA accumulation, unless the number of samples of TAA is already | * We always do SMAA on top of TAA accumulation, unless the number of samples of TAA is already | ||||
| * high. This ensure a smoother transition. | * high. This ensure a smoother transition. | ||||
| * If TAA accumulation is finished, we only blit the result. | * If TAA accumulation is finished, we only blit the result. | ||||
| */ | */ | ||||
| const bool last_sample = wpd->taa_sample + 1 == wpd->taa_sample_len; | const bool last_sample = wpd->taa_sample + 1 == wpd->taa_sample_len; | ||||
| const bool taa_finished = wpd->taa_sample >= wpd->taa_sample_len; | const bool taa_finished = wpd->taa_sample >= wpd->taa_sample_len; | ||||
| if (wpd->taa_sample == 0) { | if (wpd->taa_sample == 0) { | ||||
| wpd->taa_weight_accum = wpd->taa_weights_sum; | |||||
| wpd->valid_history = true; | wpd->valid_history = true; | ||||
| GPU_texture_copy(txl->history_buffer_tx, dtxl->color); | |||||
| GPU_framebuffer_bind(fbl->antialiasing_fb); | |||||
| DRW_draw_pass(psl->aa_accum_replace_ps); | |||||
| /* In playback mode, we are sure the next redraw will not use the same viewmatrix. | /* In playback mode, we are sure the next redraw will not use the same viewmatrix. | ||||
| * In this case no need to save the depth buffer. */ | * In this case no need to save the depth buffer. */ | ||||
| if (!wpd->is_playback) { | if (!wpd->is_playback) { | ||||
| GPU_texture_copy(txl->depth_buffer_tx, dtxl->depth); | GPU_texture_copy(txl->depth_buffer_tx, dtxl->depth); | ||||
| } | } | ||||
| if (workbench_in_front_history_needed(vedata)) { | if (workbench_in_front_history_needed(vedata)) { | ||||
| GPU_texture_copy(txl->depth_buffer_in_front_tx, dtxl->depth_in_front); | GPU_texture_copy(txl->depth_buffer_in_front_tx, dtxl->depth_in_front); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (!taa_finished) { | if (!taa_finished) { | ||||
| /* Accumulate result to the TAA buffer. */ | /* Accumulate result to the TAA buffer. */ | ||||
| GPU_framebuffer_bind(fbl->antialiasing_fb); | GPU_framebuffer_bind(fbl->antialiasing_fb); | ||||
| DRW_draw_pass(psl->aa_accum_ps); | DRW_draw_pass(psl->aa_accum_ps); | ||||
| wpd->taa_weight_accum += wpd->taa_weights_sum; | |||||
| } | } | ||||
| /* Copy back the saved depth buffer for correct overlays. */ | /* Copy back the saved depth buffer for correct overlays. */ | ||||
| GPU_texture_copy(dtxl->depth, txl->depth_buffer_tx); | GPU_texture_copy(dtxl->depth, txl->depth_buffer_tx); | ||||
| if (workbench_in_front_history_needed(vedata)) { | if (workbench_in_front_history_needed(vedata)) { | ||||
| GPU_texture_copy(dtxl->depth_in_front, txl->depth_buffer_in_front_tx); | GPU_texture_copy(dtxl->depth_in_front, txl->depth_buffer_in_front_tx); | ||||
| } | } | ||||
| } | } | ||||
| if (!DRW_state_is_image_render() || last_sample) { | if (!DRW_state_is_image_render() || last_sample) { | ||||
| /* After a certain point SMAA is no longer necessary. */ | /* After a certain point SMAA is no longer necessary. */ | ||||
| wpd->smaa_mix_factor = 1.0f - clamp_f(wpd->taa_sample / 4.0f, 0.0f, 1.0f); | wpd->smaa_mix_factor = 1.0f - clamp_f(wpd->taa_sample / 4.0f, 0.0f, 1.0f); | ||||
| wpd->taa_sample_inv = 1.0f / min_ii(wpd->taa_sample + 1, wpd->taa_sample_len); | |||||
| printf("wpd->taa_weight_accum %f\n", wpd->taa_weight_accum); | |||||
jbakker: remove debug line. | |||||
| if (wpd->smaa_mix_factor > 0.0f) { | if (wpd->smaa_mix_factor > 0.0f) { | ||||
| GPU_framebuffer_bind(fbl->smaa_edge_fb); | GPU_framebuffer_bind(fbl->smaa_edge_fb); | ||||
| DRW_draw_pass(psl->aa_edge_ps); | DRW_draw_pass(psl->aa_edge_ps); | ||||
| GPU_framebuffer_bind(fbl->smaa_weight_fb); | GPU_framebuffer_bind(fbl->smaa_weight_fb); | ||||
| DRW_draw_pass(psl->aa_weight_ps); | DRW_draw_pass(psl->aa_weight_ps); | ||||
| } | } | ||||
| Show All 13 Lines | |||||
remove debug line.