diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2018-06-27 13:55:49 +0300 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2018-06-27 13:59:01 +0300 |
commit | 20b8e1d8f1ebc4091f59e9bca32264717849a39b (patch) | |
tree | 09cabce715e9cdd0b09308a826e6b1d3d32f203a /source/blender/draw | |
parent | cf2dcd57c0a6211de22abbf2c40a6eed80d77416 (diff) |
Workbench: Added a quality slider for the viewport
Currently only attached to the Anti Aliasing of the solid mode of the
viewport. But eventually we could add other options here. Quality
setting can be found in the System tab of the userpref.
The slider goes from No Antialiasing (0.0 - 0.1) to FXAA (0.1 - 0.25) to
TAA8 (0.25 - 0.6) to TAA16 (0.6 - 0.8) to TAA32 (0.8 - 1.0)
Diffstat (limited to 'source/blender/draw')
6 files changed, 152 insertions, 58 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl index 38f55015877..7e638abcd15 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl @@ -17,14 +17,14 @@ layout(std140) uniform samples_block { vec4 ssao_samples[500]; }; -#define ssao_samples_num ssao_params.x -#define jitter_tilling ssao_params.yz -#define dfdy_sign ssao_params.w - -#define ssao_distance ssao_settings.x -#define ssao_factor_cavity ssao_settings.y -#define ssao_factor_edge ssao_settings.z -#define ssao_attenuation ssao_settings.a +#define ssao_samples_num ssao_params.x +#define jitter_tilling ssao_params.yz +#define ssao_iteration ssao_params.w + +#define ssao_distance ssao_settings.x +#define ssao_factor_cavity ssao_settings.y +#define ssao_factor_edge ssao_settings.z +#define ssao_attenuation ssao_settings.a vec3 get_view_space_from_depth(in vec2 uvcoords, in float depth) { diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl index da0198ab2e7..a5a5b9e49ba 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl @@ -24,19 +24,24 @@ void ssao_factors( /* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */ offset *= 0.5; + int num_samples = int(ssao_samples_num); /* Note. Putting noise usage here to put some ALU after texture fetch. */ vec2 rotX = noise.rg; vec2 rotY = vec2(-rotX.y, rotX.x); - for (int x = 0; x < num_samples && x < 500; x++) { + for (int x = 0; x < num_samples; x++) { + int sample_index = x; + if (sample_index > 500) { + continue; + } /* ssao_samples[x].xy is sample direction (normalized). * ssao_samples[x].z is sample distance from disk center. */ /* Rotate with random direction to get jittered result. */ - vec2 dir_jittered = vec2(dot(ssao_samples[x].xy, rotX), dot(ssao_samples[x].xy, rotY)); - dir_jittered.xy *= ssao_samples[x].z + noise.b; + vec2 dir_jittered = vec2(dot(ssao_samples[sample_index].xy, rotX), dot(ssao_samples[sample_index].xy, rotY)); + dir_jittered.xy *= ssao_samples[sample_index].z + noise.b; vec2 uvcoords = screenco.xy + dir_jittered * offset; diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index a72f3a673b5..cab26ae015d 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -71,7 +71,6 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) const int ssao_samples = scene->display.matcap_ssao_samples; float invproj[4][4]; - float dfdyfacs[2]; const bool is_persp = DRW_viewport_is_persp_get(); /* view vectors for the corners of the view frustum. * Can be used to recreate the world space position easily */ @@ -83,12 +82,10 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) int i; const float *size = DRW_viewport_size_get(); - DRW_state_dfdy_factors_get(dfdyfacs); - wpd->ssao_params[0] = ssao_samples; wpd->ssao_params[1] = size[0] / 64.0; wpd->ssao_params[2] = size[1] / 64.0; - wpd->ssao_params[3] = dfdyfacs[1]; /* dfdy sign for offscreen */ + wpd->ssao_params[3] = 0; /* distance, factor, factor, attenuation */ copy_v4_fl4(wpd->ssao_settings, scene->display.matcap_ssao_distance, wpd->shading.cavity_valley_factor, wpd->shading.cavity_ridge_factor, scene->display.matcap_ssao_attenuation); diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index 96ed345ed45..17470dada39 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -268,7 +268,6 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) { WORKBENCH_FramebufferList *fbl = vedata->fbl; WORKBENCH_StorageList *stl = vedata->stl; - WORKBENCH_TextureList *txl = vedata->txl; WORKBENCH_PassList *psl = vedata->psl; DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); @@ -382,7 +381,8 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) const DRWContextState *draw_ctx = DRW_context_state_get(); Scene *scene = draw_ctx->scene; /* AO Samples Tex */ - const int ssao_samples = scene->display.matcap_ssao_samples; + const int ssao_samples_single_iteration = scene->display.matcap_ssao_samples; + const int ssao_samples = MIN2(ssao_samples_single_iteration, 500); if (e_data.sampling_ubo && (e_data.cached_sample_num != ssao_samples)) { DRW_UBO_FREE_SAFE(e_data.sampling_ubo); DRW_TEXTURE_FREE_SAFE(e_data.jitter_tx); @@ -405,6 +405,19 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) } { + if (TAA_ENABLED(wpd)) { + psl->effect_aa_pass = workbench_taa_create_pass(vedata, &e_data.composite_buffer_tx); + } + else if (FXAA_ENABLED(wpd)) { + psl->effect_aa_pass = workbench_fxaa_create_pass(&e_data.effect_buffer_tx); + stl->effects->jitter_index = 0; + } + else { + psl->effect_aa_pass = NULL; + } + } + + { int state = DRW_STATE_WRITE_COLOR; psl->cavity_pass = DRW_pass_create("Cavity", state); DRWShadingGroup *grp = DRW_shgroup_create(e_data.cavity_sh, psl->cavity_pass); @@ -421,19 +434,6 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) DRW_shgroup_uniform_block(grp, "samples_block", e_data.sampling_ubo); DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL); } - - { - if (TAA_ENABLED(wpd)) { - psl->effect_aa_pass = workbench_taa_create_pass(txl, stl->effects, fbl, &e_data.composite_buffer_tx); - } - else if (FXAA_ENABLED(wpd)) { - psl->effect_aa_pass = workbench_fxaa_create_pass(&e_data.effect_buffer_tx); - stl->effects->jitter_index = 0; - } - else { - psl->effect_aa_pass = NULL; - } - } } void workbench_deferred_engine_free(void) @@ -845,7 +845,7 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) if (taa_enabled) { - workbench_taa_draw_scene_start(effect_info); + workbench_taa_draw_scene_start(vedata); } /* clear in background */ diff --git a/source/blender/draw/engines/workbench/workbench_effect_taa.c b/source/blender/draw/engines/workbench/workbench_effect_taa.c index deebac05096..34db49b7009 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_taa.c +++ b/source/blender/draw/engines/workbench/workbench_effect_taa.c @@ -1,28 +1,90 @@ #include "workbench_private.h" +#include "BLI_jitter_2d.h" static struct { struct GPUShader *effect_taa_sh; - + float jitter_8[8][2]; + float jitter_16[16][2]; + float jitter_32[32][2]; } e_data = {NULL}; extern char datatoc_workbench_effect_taa_frag_glsl[]; -/* - * Sub-sample positions for TAA8 - * first sample needs to be at 0.0f, 0.0f - * as that sample depicts the z-buffer - */ -static const float SAMPLE_LOCS_8[8][2] = { - { 0.125f-0.125f, 0.375f-0.375f}, - {-0.625f-0.125f, -0.625f-0.375f}, - { 0.875f-0.125f, 0.875f-0.375f}, - {-0.875f-0.125f, 0.125f-0.375f}, - { 0.625f-0.125f, -0.125f-0.375f}, - {-0.375f-0.125f, 0.625f-0.375f}, - { 0.375f-0.125f, -0.875f-0.375f}, - {-0.125f-0.125f, -0.375f-0.375f}, -}; + +static void workbench_taa_jitter_init_order(float (*table)[2], int num) +{ + BLI_jitter_init(table, num); + + /* find closest element to center */ + int closest_index = 0; + float closest_squared_distance = 1.0f; + + for (int index = 0 ; index < num; index++) { + const float squared_dist = SQUARE(table[index][0]) + SQUARE(table[index][1]); + if (squared_dist < closest_squared_distance) { + closest_squared_distance = squared_dist; + closest_index = index; + } + } + + /* move jitter table so that closest sample is in center */ + for (int index = 0 ; index < num; index++) { + sub_v2_v2(table[index], table[closest_index]); + } + + /* swap center sample to the start of the table */ + if (closest_index != 0) { + swap_v2_v2(table[0], table[closest_index]); + } + + /* sort list based on furtest distance with previous */ + for (int i = 0 ; i < num - 2; i ++) + { + float f_squared_dist = 0.0; + int f_index = i; + for(int j = i + 1; j < num; j ++) + { + const float squared_dist = SQUARE(table[i][0] - table[j][0]) + SQUARE(table[i][1] - table[j][1]); + if (squared_dist > f_squared_dist) + { + f_squared_dist = squared_dist; + f_index = j; + } + } + swap_v2_v2(table[i+1], table[f_index]); + } +} + + +static void workbench_taa_jitter_init(void) +{ + workbench_taa_jitter_init_order(e_data.jitter_8, 8); + workbench_taa_jitter_init_order(e_data.jitter_16, 16); + workbench_taa_jitter_init_order(e_data.jitter_32, 32); +} + +int workbench_taa_calculate_num_iterations(WORKBENCH_Data *vedata) +{ + WORKBENCH_StorageList *stl = vedata->stl; + WORKBENCH_PrivateData *wpd = stl->g_data; + int result = 1; + if (TAA_ENABLED(wpd)) + { + if (IN_RANGE_INCL(wpd->user_preferences->gpu_viewport_quality, GPU_VIEWPORT_QUALITY_TAA8, GPU_VIEWPORT_QUALITY_TAA16)) + { + result = 8; + } + else if (IN_RANGE_INCL(wpd->user_preferences->gpu_viewport_quality, GPU_VIEWPORT_QUALITY_TAA16, GPU_VIEWPORT_QUALITY_TAA32)) + { + result = 16; + } + else { + result = 32; + } + } + return result; +} void workbench_taa_engine_init(WORKBENCH_Data *vedata) { @@ -33,6 +95,7 @@ void workbench_taa_engine_init(WORKBENCH_Data *vedata) if (e_data.effect_taa_sh == NULL) { e_data.effect_taa_sh = DRW_shader_create_fullscreen(datatoc_workbench_effect_taa_frag_glsl, NULL); + workbench_taa_jitter_init(); } /* reset complete drawing when navigating. */ @@ -68,8 +131,13 @@ void workbench_taa_engine_free(void) } -DRWPass *workbench_taa_create_pass(WORKBENCH_TextureList *txl, WORKBENCH_EffectInfo *effect_info, WORKBENCH_FramebufferList *fbl, GPUTexture **color_buffer_tx) +DRWPass *workbench_taa_create_pass(WORKBENCH_Data *vedata, GPUTexture **color_buffer_tx) { + WORKBENCH_StorageList *stl = vedata->stl; + WORKBENCH_TextureList *txl = vedata->txl; + WORKBENCH_EffectInfo *effect_info = stl->effects; + WORKBENCH_FramebufferList *fbl = vedata->fbl; + WORKBENCH_PrivateData *wpd = stl->g_data; /* * jitter_index is not updated yet. This will be done in during draw phase. * so for now it is inversed. @@ -120,20 +188,45 @@ DRWPass *workbench_taa_create_pass(WORKBENCH_TextureList *txl, WORKBENCH_EffectI effect_info->final_color_tx = txl->history_buffer2_tx; effect_info->final_color_fb = fbl->effect_taa_uneven_fb; } + + /* + * Set the offset for the cavity shader so every iteration different + * samples will be selected + */ + wpd->ssao_params[3] = previous_jitter_index; + return pass; } -void workbench_taa_draw_scene_start(WORKBENCH_EffectInfo *effect_info) +void workbench_taa_draw_scene_start(WORKBENCH_Data *vedata) { + WORKBENCH_StorageList *stl = vedata->stl; + WORKBENCH_EffectInfo *effect_info = stl->effects; const float *viewport_size = DRW_viewport_size_get(); - const int samples = 8; + int num_samples = 8; + float (*samples)[2] = e_data.jitter_8; float mix_factor; + num_samples = workbench_taa_calculate_num_iterations(vedata); + switch(num_samples) + { + case 8: + samples = e_data.jitter_8; + break; + case 16: + samples = e_data.jitter_16; + break; + case 32: + default: + samples = e_data.jitter_32; + break; + } + mix_factor = 1.0f / (effect_info->jitter_index + 1); - const int bitmask = samples - 1; + const int bitmask = num_samples - 1; const int jitter_index = effect_info->jitter_index; - const float *transform_offset = SAMPLE_LOCS_8[jitter_index]; + const float *transform_offset = samples[jitter_index]; effect_info->jitter_index = (jitter_index + 1) & bitmask; /* construct new matrices from transform delta */ diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index 404ec50fd97..5f938b8f0b2 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -52,10 +52,8 @@ #define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW) #define IS_NAVIGATING(wpd) (DRW_context_state_get()->rv3d->rflag & RV3D_NAVIGATING) -#define FXAA_ENABLED(wpd) ((!DRW_state_is_opengl_render()) && ((wpd->user_preferences->gpu_viewport_antialias == USER_AA_FXAA) || (ELEM(wpd->user_preferences->gpu_viewport_antialias, USER_AA_TAA8) && IS_NAVIGATING(wpd)))) -#define TAA8_ENABLED(wpd) (ELEM(wpd->user_preferences->gpu_viewport_antialias, USER_AA_TAA8) && (!DRW_state_is_opengl_render()) && (!IS_NAVIGATING(wpd))) -#define TAA_ENABLED(wpd) (TAA8_ENABLED(wpd)) - +#define FXAA_ENABLED(wpd) ((!DRW_state_is_opengl_render()) && (IN_RANGE(wpd->user_preferences->gpu_viewport_quality, GPU_VIEWPORT_QUALITY_FXAA, GPU_VIEWPORT_QUALITY_TAA8) || ((wpd->user_preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8) && IS_NAVIGATING(wpd)))) +#define TAA_ENABLED(wpd) (wpd->user_preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8 && !IS_NAVIGATING(wpd)) #define SPECULAR_HIGHLIGHT_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) && (!STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd))) #define OBJECT_ID_PASS_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE) #define NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) (MATCAP_ENABLED(wpd) || STUDIOLIGHT_ENABLED(wpd) || SHADOW_ENABLED(wpd) || SPECULAR_HIGHLIGHT_ENABLED(wpd)) @@ -269,11 +267,12 @@ void workbench_fxaa_draw_pass(WORKBENCH_PrivateData *wpd, GPUFrameBuffer *fb, GP /* workbench_effect_taa.c */ void workbench_taa_engine_init(WORKBENCH_Data *vedata); void workbench_taa_engine_free(void); -DRWPass *workbench_taa_create_pass(WORKBENCH_TextureList *txl, WORKBENCH_EffectInfo *effect_info, WORKBENCH_FramebufferList *fbl, GPUTexture **color_buffer_tx); +DRWPass *workbench_taa_create_pass(WORKBENCH_Data *vedata, GPUTexture **color_buffer_tx); void workbench_taa_draw_pass(WORKBENCH_EffectInfo *effect_info, /*WORKBENCH_PrivateData *wpd, , GPUFrameBuffer *fb, GPUTexture *tx, */DRWPass *effect_aa_pass); -void workbench_taa_draw_scene_start(WORKBENCH_EffectInfo *effect_info); +void workbench_taa_draw_scene_start(WORKBENCH_Data *vedata); void workbench_taa_draw_scene_end(WORKBENCH_Data *vedata); void workbench_taa_view_updated(WORKBENCH_Data *vedata); +int workbench_taa_calculate_num_iterations(WORKBENCH_Data *vedata); /* workbench_materials.c */ int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd, Image *ima); |