diff options
Diffstat (limited to 'source/blender/draw/engines/workbench')
17 files changed, 123 insertions, 84 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl index e6bc4c7bbc6..a4d81393dbc 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl @@ -26,6 +26,10 @@ void curvature_compute(vec2 uv, if ((object_up != object_down) || (object_right != object_left)) { return; } + /* Avoid shading background pixels. */ + if ((object_up == object_right) && (object_right == 0u)) { + return; + } float normal_up = workbench_normal_decode(texture(normalBuffer, uv + offset.zy)).g; float normal_down = workbench_normal_decode(texture(normalBuffer, uv - offset.zy)).g; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl index 0efcfb35929..51007a9f246 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl @@ -4,7 +4,6 @@ * Converted and adapted from HLSL to GLSL by Clément Foucault */ -uniform mat4 ProjectionMatrix; uniform vec2 invertedViewportSize; uniform vec2 nearFar; uniform vec3 dofParams; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl index 6f99739f259..e45f7a7b9e3 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl @@ -24,11 +24,17 @@ bool node_tex_tile_lookup(inout vec3 co, sampler2DArray ima, sampler1DArray map) vec4 workbench_sample_texture(sampler2D image, vec2 coord, bool nearest_sampling) { - vec2 tex_size = vec2(textureSize(image, 0).xy); /* TODO(fclem) We could do the same with sampler objects. * But this is a quick workaround instead of messing with the GPUTexture itself. */ - vec2 uv = nearest_sampling ? (floor(coord * tex_size) + 0.5) / tex_size : coord; - return texture(image, uv); + if (nearest_sampling) { + /* Use texelFetch for nearest_sampling to reduce glitches. See: T73726 */ + vec2 tex_size = vec2(textureSize(image, 0).xy); + ivec2 uv = ivec2(floor(coord * tex_size) + 0.5); + return texelFetch(image, uv, 0); + } + else { + return texture(image, coord); + } } vec4 workbench_sample_texture_array(sampler2DArray tile_array, @@ -36,7 +42,6 @@ vec4 workbench_sample_texture_array(sampler2DArray tile_array, vec2 coord, bool nearest_sampling) { - vec2 tex_size = vec2(textureSize(tile_array, 0).xy); vec3 uv = vec3(coord, 0); if (!node_tex_tile_lookup(uv, tile_array, tile_data)) @@ -44,8 +49,15 @@ vec4 workbench_sample_texture_array(sampler2DArray tile_array, /* TODO(fclem) We could do the same with sampler objects. * But this is a quick workaround instead of messing with the GPUTexture itself. */ - uv.xy = nearest_sampling ? (floor(uv.xy * tex_size) + 0.5) / tex_size : uv.xy; - return texture(tile_array, uv); + if (nearest_sampling) { + /* Use texelFetch for nearest_sampling to reduce glitches. See: T73726 */ + vec3 tex_size = vec3(textureSize(tile_array, 0)); + uv.xy = floor(uv.xy * tex_size.xy) + 0.5; + return texelFetch(tile_array, ivec3(uv), 0); + } + else { + return texture(tile_array, uv); + } } uniform sampler2DArray imageTileArray; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl index 58becb03290..b77e168889f 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl @@ -15,4 +15,4 @@ void main() /* Make this fragment occlude any fragment that will try to * render over it in the normal passes. */ gl_FragDepth = 0.0; -}
\ No newline at end of file +} diff --git a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl index 81f6e651be0..41ef516ee4d 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl @@ -128,4 +128,4 @@ float get_shadow(vec3 N) float shadow_mix = smoothstep(world_data.shadow_shift, world_data.shadow_focus, light_factor); shadow_mix *= forceShadowing ? 0.0 : world_data.shadow_mul; return shadow_mix + world_data.shadow_add; -}
\ No newline at end of file +} diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index fc047eadf55..7b08e97ac31 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -182,7 +182,7 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) WORKBENCH_ViewLayerData *vldata = workbench_view_layer_data_ensure_ex(draw_ctx->view_layer); wpd->is_playback = DRW_state_is_playback(); - wpd->is_navigating = rv3d && (rv3d->rflag & (RV3D_NAVIGATING | RV3D_PAINTING)); + wpd->is_navigating = DRW_state_is_navigating(); wpd->ctx_mode = CTX_data_mode_enum_ex( draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode); @@ -199,7 +199,6 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) } wpd->clip_state = clip_state; - wpd->cull_state = CULL_BACKFACE_ENABLED(wpd) ? DRW_STATE_CULL_BACK : 0; wpd->vldata = vldata; wpd->world_ubo = vldata->world_ubo; @@ -218,8 +217,7 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) if (!v3d || (v3d->shading.type == OB_RENDER && BKE_scene_uses_blender_workbench(scene))) { /* FIXME: This reproduce old behavior when workbench was separated in 2 engines. * But this is a workaround for a missing update tagging from operators. */ - if (scene->display.shading.type != wpd->shading.type || - (v3d && (XRAY_ENABLED(v3d) != XRAY_ENABLED(&scene->display))) || + if ((v3d && (XRAY_ENABLED(v3d) != XRAY_ENABLED(&scene->display))) || (scene->display.shading.flag != wpd->shading.flag)) { wpd->view_updated = true; } @@ -246,13 +244,14 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) else { /* FIXME: This reproduce old behavior when workbench was separated in 2 engines. * But this is a workaround for a missing update tagging from operators. */ - if (v3d->shading.type != wpd->shading.type || XRAY_ENABLED(v3d) != XRAY_ENABLED(wpd) || - v3d->shading.flag != wpd->shading.flag) { + if (XRAY_ENABLED(v3d) != XRAY_ENABLED(wpd) || v3d->shading.flag != wpd->shading.flag) { wpd->view_updated = true; } wpd->shading = v3d->shading; if (wpd->shading.type < OB_SOLID) { + wpd->shading.light = V3D_LIGHTING_FLAT; + wpd->shading.color_type = V3D_SHADING_OBJECT_COLOR; wpd->shading.xray_alpha = 0.0f; } else if (XRAY_ENABLED(v3d)) { @@ -266,6 +265,8 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) copy_v4_fl(wpd->background_color, 0.0f); } + wpd->cull_state = CULL_BACKFACE_ENABLED(wpd) ? DRW_STATE_CULL_BACK : 0; + if (wpd->shading.light == V3D_LIGHTING_MATCAP) { wpd->studio_light = BKE_studiolight_find(wpd->shading.matcap, STUDIOLIGHT_TYPE_MATCAP); } diff --git a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c index a0db09e9273..0e896c4b7bb 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c +++ b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c @@ -19,7 +19,7 @@ /** \file * \ingroup draw_engine * - * Anti-aliasing: + * Anti-Aliasing: * * We use SMAA (Smart Morphological Anti-Aliasing) as a fast antialiasing solution. * @@ -141,7 +141,6 @@ static bool workbench_in_front_history_needed(WORKBENCH_Data *vedata) WORKBENCH_StorageList *stl = vedata->stl; const DRWContextState *draw_ctx = DRW_context_state_get(); const View3D *v3d = draw_ctx->v3d; - const Object *obact = draw_ctx->obact; if (!v3d || (v3d->flag2 & V3D_HIDE_OVERLAYS)) { return false; @@ -151,11 +150,6 @@ static bool workbench_in_front_history_needed(WORKBENCH_Data *vedata) return false; } - if (!obact || draw_ctx->object_mode != OB_MODE_WEIGHT_PAINT || - v3d->overlay.weight_paint_mode_opacity == 0.0) { - return false; - } - return true; } @@ -168,18 +162,37 @@ void workbench_antialiasing_engine_init(WORKBENCH_Data *vedata) wpd->view = NULL; - /* reset complete drawing when navigating or during viewport playback. */ + /* Reset complete drawing when navigating or during viewport playback or when + * leaving one of those states. In case of multires modifier the navigation + * mesh differs from the viewport mesh, so we need to be sure to restart. */ if (wpd->taa_sample != 0) { if (wpd->is_navigating || wpd->is_playback) { wpd->taa_sample = 0; + wpd->reset_next_sample = true; + } + else if (wpd->reset_next_sample) { + wpd->taa_sample = 0; + wpd->reset_next_sample = false; } } + /* Reset the TAA when we have already draw a sample, but the sample count differs from previous + * time. This removes render artifacts when the viewport anti-aliasing in the user preferences is + * set to a lower value. */ + if (wpd->taa_sample_len != wpd->taa_sample_len_previous) { + wpd->taa_sample = 0; + wpd->taa_sample_len_previous = wpd->taa_sample_len; + } + if (wpd->view_updated) { wpd->taa_sample = 0; wpd->view_updated = false; } + if (wpd->taa_sample_len > 0 && wpd->valid_history == false) { + wpd->taa_sample = 0; + } + { float persmat[4][4]; DRW_view_persmat_get(NULL, persmat, false); @@ -253,13 +266,8 @@ void workbench_antialiasing_engine_init(WORKBENCH_Data *vedata) false, NULL); - GPU_texture_bind(txl->smaa_search_tx, 0); GPU_texture_filter_mode(txl->smaa_search_tx, true); - GPU_texture_unbind(txl->smaa_search_tx); - - GPU_texture_bind(txl->smaa_area_tx, 0); GPU_texture_filter_mode(txl->smaa_area_tx, true); - GPU_texture_unbind(txl->smaa_area_tx); } } else { @@ -406,13 +414,16 @@ void workbench_antialiasing_draw_pass(WORKBENCH_Data *vedata) { WORKBENCH_PrivateData *wpd = vedata->stl->wpd; WORKBENCH_FramebufferList *fbl = vedata->fbl; + WORKBENCH_TextureList *txl = vedata->txl; WORKBENCH_PassList *psl = vedata->psl; DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); if (wpd->taa_sample_len == 0) { /* AA disabled. */ /* Just set sample to 1 to avoid rendering indefinitely. */ wpd->taa_sample = 1; + wpd->valid_history = false; return; } @@ -425,12 +436,15 @@ void workbench_antialiasing_draw_pass(WORKBENCH_Data *vedata) const bool last_sample = wpd->taa_sample + 1 == wpd->taa_sample_len; const bool taa_finished = wpd->taa_sample >= wpd->taa_sample_len; if (wpd->taa_sample == 0) { + wpd->valid_history = true; + GPU_texture_copy(txl->history_buffer_tx, dtxl->color); /* 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. */ - eGPUFrameBufferBits bits = GPU_COLOR_BIT | (!wpd->is_playback ? GPU_DEPTH_BIT : 0); - GPU_framebuffer_blit(dfbl->default_fb, 0, fbl->antialiasing_fb, 0, bits); + if (!wpd->is_playback) { + GPU_texture_copy(txl->depth_buffer_tx, dtxl->depth); + } if (workbench_in_front_history_needed(vedata)) { - GPU_framebuffer_blit(dfbl->in_front_fb, 0, fbl->antialiasing_in_front_fb, 0, GPU_DEPTH_BIT); + GPU_texture_copy(txl->depth_buffer_in_front_tx, dtxl->depth_in_front); } } else { @@ -440,9 +454,9 @@ void workbench_antialiasing_draw_pass(WORKBENCH_Data *vedata) DRW_draw_pass(psl->aa_accum_ps); } /* Copy back the saved depth buffer for correct overlays. */ - GPU_framebuffer_blit(fbl->antialiasing_fb, 0, dfbl->default_fb, 0, GPU_DEPTH_BIT); + GPU_texture_copy(dtxl->depth, txl->depth_buffer_tx); if (workbench_in_front_history_needed(vedata)) { - GPU_framebuffer_blit(fbl->antialiasing_in_front_fb, 0, dfbl->in_front_fb, 0, GPU_DEPTH_BIT); + GPU_texture_copy(dtxl->depth_in_front, txl->depth_buffer_in_front_tx); } } diff --git a/source/blender/draw/engines/workbench/workbench_effect_cavity.c b/source/blender/draw/engines/workbench/workbench_effect_cavity.c index cdf8a93fc57..4a8db65c02e 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_cavity.c +++ b/source/blender/draw/engines/workbench/workbench_effect_cavity.c @@ -42,11 +42,11 @@ /* Using Hammersley distribution */ static float *create_disk_samples(int num_samples, int num_iterations) { + BLI_assert(num_samples * num_iterations <= CAVITY_MAX_SAMPLES); const int total_samples = num_samples * num_iterations; const float num_samples_inv = 1.0f / num_samples; /* vec4 to ensure memory alignment. */ float(*texels)[4] = MEM_callocN(sizeof(float[4]) * CAVITY_MAX_SAMPLES, __func__); - for (int i = 0; i < total_samples; i++) { float it_add = (i / num_samples) * 0.499f; float r = fmodf((i + 0.5f + it_add) * num_samples_inv, 1.0f); @@ -102,7 +102,7 @@ void workbench_cavity_data_update(WORKBENCH_PrivateData *wpd, WORKBENCH_UBO_Worl if (CAVITY_ENABLED(wpd)) { int cavity_sample_count_single_iteration = scene->display.matcap_ssao_samples; int cavity_sample_count_total = workbench_cavity_total_sample_count(wpd, scene); - int max_iter_count = cavity_sample_count_total / cavity_sample_count_single_iteration; + const int max_iter_count = cavity_sample_count_total / cavity_sample_count_single_iteration; int sample = wpd->taa_sample % max_iter_count; wd->cavity_sample_start = cavity_sample_count_single_iteration * sample; @@ -128,6 +128,7 @@ void workbench_cavity_samples_ubo_ensure(WORKBENCH_PrivateData *wpd) int cavity_sample_count_single_iteration = scene->display.matcap_ssao_samples; int cavity_sample_count = workbench_cavity_total_sample_count(wpd, scene); + const int max_iter_count = max_ii(1, cavity_sample_count / cavity_sample_count_single_iteration); if (wpd->vldata->cavity_sample_count != cavity_sample_count) { DRW_UBO_FREE_SAFE(wpd->vldata->cavity_sample_ubo); @@ -135,8 +136,7 @@ void workbench_cavity_samples_ubo_ensure(WORKBENCH_PrivateData *wpd) } if (wpd->vldata->cavity_sample_ubo == NULL) { - float *samples = create_disk_samples(cavity_sample_count_single_iteration, - max_ii(1, wpd->taa_sample_len)); + float *samples = create_disk_samples(cavity_sample_count_single_iteration, max_iter_count); wpd->vldata->cavity_jitter_tx = create_jitter_texture(cavity_sample_count); /* NOTE: Uniform buffer needs to always be filled to be valid. */ wpd->vldata->cavity_sample_ubo = DRW_uniformbuffer_create( diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c index c6c594dc04d..511dd563b46 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.c +++ b/source/blender/draw/engines/workbench/workbench_engine.c @@ -55,6 +55,7 @@ void workbench_engine_init(void *ved) if (!stl->wpd) { stl->wpd = MEM_callocN(sizeof(*stl->wpd), __func__); + stl->wpd->taa_sample_len_previous = -1; stl->wpd->view_updated = true; } @@ -112,13 +113,12 @@ static void workbench_cache_sculpt_populate(WORKBENCH_PrivateData *wpd, Object *ob, eV3DShadingColorType color_type) { - const bool use_vcol = ELEM(color_type, V3D_SHADING_VERTEX_COLOR); const bool use_single_drawcall = !ELEM(color_type, V3D_SHADING_MATERIAL_COLOR); BLI_assert(wpd->shading.color_type != V3D_SHADING_TEXTURE_COLOR); if (use_single_drawcall) { DRWShadingGroup *grp = workbench_material_setup(wpd, ob, 0, color_type, NULL); - DRW_shgroup_call_sculpt(grp, ob, false, false, use_vcol); + DRW_shgroup_call_sculpt(grp, ob, false, false); } else { const int materials_len = DRW_cache_object_material_count_get(ob); @@ -126,7 +126,7 @@ static void workbench_cache_sculpt_populate(WORKBENCH_PrivateData *wpd, for (int i = 0; i < materials_len; i++) { shgrps[i] = workbench_material_setup(wpd, ob, i + 1, color_type, NULL); } - DRW_shgroup_call_sculpt_with_materials(shgrps, ob, false); + DRW_shgroup_call_sculpt_with_materials(shgrps, materials_len, ob); } } @@ -153,6 +153,9 @@ static void workbench_cache_texpaint_populate(WORKBENCH_PrivateData *wpd, Object if (geoms) { const int materials_len = DRW_cache_object_material_count_get(ob); for (int i = 0; i < materials_len; i++) { + if (geoms[i] == NULL) { + continue; + } DRWShadingGroup *grp = workbench_image_setup(wpd, ob, i + 1, NULL, NULL, 0); DRW_shgroup_call(grp, geoms[i], ob); } @@ -184,6 +187,9 @@ static void workbench_cache_common_populate(WORKBENCH_PrivateData *wpd, if (geoms) { const int materials_len = DRW_cache_object_material_count_get(ob); for (int i = 0; i < materials_len; i++) { + if (geoms[i] == NULL) { + continue; + } DRWShadingGroup *grp = workbench_material_setup(wpd, ob, i + 1, color_type, r_transp); DRW_shgroup_call(grp, geoms[i], ob); } @@ -315,8 +321,8 @@ void workbench_cache_populate(void *ved, Object *ob) } if (!(ob->base_flag & BASE_FROM_DUPLI)) { - ModifierData *md = modifiers_findByType(ob, eModifierType_Fluid); - if (md && modifier_isEnabled(wpd->scene, md, eModifierMode_Realtime)) { + ModifierData *md = BKE_modifiers_findby_type(ob, eModifierType_Fluid); + if (md && BKE_modifier_is_enabled(wpd->scene, md, eModifierMode_Realtime)) { FluidModifierData *fmd = (FluidModifierData *)md; if (fmd->domain && fmd->domain->type == FLUID_DOMAIN_TYPE_GAS) { workbench_volume_cache_populate(vedata, wpd->scene, ob, md, V3D_SHADING_SINGLE_COLOR); diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c index a2abecb679f..b36a4a3a494 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -267,7 +267,6 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd, } if (tex == NULL) { - printf("Image not found\n"); tex = wpd->dummy_image_tx; } @@ -285,11 +284,11 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd, *grp_tex = grp = DRW_shgroup_create_sub(grp); if (tex_tile_data) { - DRW_shgroup_uniform_texture_persistent(grp, "imageTileArray", tex); - DRW_shgroup_uniform_texture_persistent(grp, "imageTileData", tex_tile_data); + DRW_shgroup_uniform_texture(grp, "imageTileArray", tex); + DRW_shgroup_uniform_texture(grp, "imageTileData", tex_tile_data); } else { - DRW_shgroup_uniform_texture_persistent(grp, "imageTexture", tex); + DRW_shgroup_uniform_texture(grp, "imageTexture", tex); } DRW_shgroup_uniform_bool_copy(grp, "imagePremult", (ima && ima->alpha_mode == IMA_ALPHA_PREMUL)); DRW_shgroup_uniform_bool_copy(grp, "imageNearest", (interp == SHD_INTERP_CLOSEST)); diff --git a/source/blender/draw/engines/workbench/workbench_opaque.c b/source/blender/draw/engines/workbench/workbench_opaque.c index 08511ca092c..27d5b71f35c 100644 --- a/source/blender/draw/engines/workbench/workbench_opaque.c +++ b/source/blender/draw/engines/workbench/workbench_opaque.c @@ -92,22 +92,24 @@ void workbench_opaque_cache_init(WORKBENCH_Data *data) wpd->prepass[opaque][infront][hair].common_shgrp = grp = DRW_shgroup_create(sh, pass); DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr); DRW_shgroup_uniform_int_copy(grp, "materialIndex", -1); + DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap); wpd->prepass[opaque][infront][hair].vcol_shgrp = grp = DRW_shgroup_create(sh, pass); - DRW_shgroup_uniform_block_persistent(grp, "material_block", wpd->material_ubo_curr); + DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr); DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. (uses vcol) */ + DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap); sh = workbench_shader_opaque_image_get(wpd, hair, false); wpd->prepass[opaque][infront][hair].image_shgrp = grp = DRW_shgroup_create(sh, pass); - DRW_shgroup_uniform_block_persistent(grp, "material_block", wpd->material_ubo_curr); + DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr); DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */ DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap); sh = workbench_shader_opaque_image_get(wpd, hair, true); wpd->prepass[opaque][infront][hair].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass); - DRW_shgroup_uniform_block_persistent(grp, "material_block", wpd->material_ubo_curr); + DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr); DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */ DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap); } @@ -121,9 +123,9 @@ void workbench_opaque_cache_init(WORKBENCH_Data *data) sh = workbench_shader_composite_get(wpd); grp = DRW_shgroup_create(sh, psl->composite_ps); - DRW_shgroup_uniform_block_persistent(grp, "world_block", wpd->world_ubo); - DRW_shgroup_uniform_texture_persistent(grp, "materialBuffer", wpd->material_buffer_tx); - DRW_shgroup_uniform_texture_persistent(grp, "normalBuffer", wpd->normal_buffer_tx); + DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo); + DRW_shgroup_uniform_texture(grp, "materialBuffer", wpd->material_buffer_tx); + DRW_shgroup_uniform_texture(grp, "normalBuffer", wpd->normal_buffer_tx); DRW_shgroup_uniform_bool_copy(grp, "forceShadowing", false); DRW_shgroup_stencil_mask(grp, 0x00); @@ -135,8 +137,8 @@ void workbench_opaque_cache_init(WORKBENCH_Data *data) struct GPUTexture *spec_tx = wpd->studio_light->matcap_specular.gputexture; const bool use_spec = workbench_is_specular_highlight_enabled(wpd); spec_tx = (use_spec && spec_tx) ? spec_tx : diff_tx; - DRW_shgroup_uniform_texture_persistent(grp, "matcapDiffuseImage", diff_tx); - DRW_shgroup_uniform_texture_persistent(grp, "matcapSpecularImage", spec_tx); + DRW_shgroup_uniform_texture(grp, "matcapDiffuseImage", diff_tx); + DRW_shgroup_uniform_texture(grp, "matcapSpecularImage", spec_tx); } DRW_shgroup_call_procedural_triangles(grp, NULL, 1); diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index 87b1c82ce94..967bdf9bae0 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -261,12 +261,16 @@ typedef struct WORKBENCH_PrivateData { /* Temporal Antialiasing */ /** Total number of samples to after which TAA stops accumulating samples. */ int taa_sample_len; + /** Total number of samples of the previous TAA. When changed TAA will be reset. */ + int taa_sample_len_previous; /** Current TAA sample index in [0..taa_sample_len[ range. */ int taa_sample; /** Inverse of taa_sample to divide the accumulation buffer. */ float taa_sample_inv; /** If the view has been updated and TAA needs to be reset. */ bool view_updated; + /** True if the history buffer contains relevant data and false if it could contain garbage. */ + bool valid_history; /** View */ struct DRWView *view; /** Last projection matrix to see if view is still valid. */ @@ -333,6 +337,7 @@ typedef struct WORKBENCH_PrivateData { bool dof_enabled; bool is_playback; bool is_navigating; + bool reset_next_sample; } WORKBENCH_PrivateData; /* Transient data */ typedef struct WORKBENCH_ObjectData { diff --git a/source/blender/draw/engines/workbench/workbench_render.c b/source/blender/draw/engines/workbench/workbench_render.c index 5a315e80a47..9e66bcb07f4 100644 --- a/source/blender/draw/engines/workbench/workbench_render.c +++ b/source/blender/draw/engines/workbench/workbench_render.c @@ -52,14 +52,12 @@ static void workbench_render_cache(void *vedata, static void workbench_render_matrices_init(RenderEngine *engine, Depsgraph *depsgraph) { /* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */ - Scene *scene = DEG_get_evaluated_scene(depsgraph); struct Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re)); - float frame = BKE_scene_frame_get(scene); /* Set the persective, view and window matrix. */ float winmat[4][4], viewmat[4][4], viewinv[4][4]; - RE_GetCameraWindow(engine->re, ob_camera_eval, frame, winmat); + RE_GetCameraWindow(engine->re, ob_camera_eval, winmat); RE_GetCameraModelMatrix(engine->re, ob_camera_eval, viewinv); invert_m4_m4(viewmat, viewinv); diff --git a/source/blender/draw/engines/workbench/workbench_shader.c b/source/blender/draw/engines/workbench/workbench_shader.c index 2e796056029..99366779b22 100644 --- a/source/blender/draw/engines/workbench/workbench_shader.c +++ b/source/blender/draw/engines/workbench/workbench_shader.c @@ -23,6 +23,7 @@ #include "DRW_render.h" #include "BLI_dynstr.h" +#include "BLI_string_utils.h" #include "workbench_engine.h" #include "workbench_private.h" @@ -359,32 +360,24 @@ void workbench_shader_depth_of_field_get(GPUShader **prepare_sh, GPUShader **resolve_sh) { if (e_data.dof_prepare_sh == NULL) { - e_data.dof_prepare_sh = DRW_shader_create_fullscreen(datatoc_workbench_effect_dof_frag_glsl, - "#define PREPARE\n"); - - e_data.dof_downsample_sh = DRW_shader_create_fullscreen(datatoc_workbench_effect_dof_frag_glsl, - "#define DOWNSAMPLE\n"); + char *frag = BLI_string_joinN(datatoc_common_view_lib_glsl, + datatoc_workbench_effect_dof_frag_glsl); + e_data.dof_prepare_sh = DRW_shader_create_fullscreen(frag, "#define PREPARE\n"); + e_data.dof_downsample_sh = DRW_shader_create_fullscreen(frag, "#define DOWNSAMPLE\n"); #if 0 /* TODO(fclem) finish COC min_max optimization */ - e_data.dof_flatten_v_sh = DRW_shader_create_fullscreen(datatoc_workbench_effect_dof_frag_glsl, + e_data.dof_flatten_v_sh = DRW_shader_create_fullscreen(frag, "#define FLATTEN_VERTICAL\n"); - - e_data.dof_flatten_h_sh = DRW_shader_create_fullscreen(datatoc_workbench_effect_dof_frag_glsl, + e_data.dof_flatten_h_sh = DRW_shader_create_fullscreen(frag, "#define FLATTEN_HORIZONTAL\n"); - - e_data.dof_dilate_v_sh = DRW_shader_create_fullscreen(datatoc_workbench_effect_dof_frag_glsl, + e_data.dof_dilate_v_sh = DRW_shader_create_fullscreen(frag, "#define DILATE_VERTICAL\n"); - - e_data.dof_dilate_h_sh = DRW_shader_create_fullscreen(datatoc_workbench_effect_dof_frag_glsl, + e_data.dof_dilate_h_sh = DRW_shader_create_fullscreen(frag, "#define DILATE_HORIZONTAL\n"); #endif - e_data.dof_blur1_sh = DRW_shader_create_fullscreen(datatoc_workbench_effect_dof_frag_glsl, - "#define BLUR1\n"); - - e_data.dof_blur2_sh = DRW_shader_create_fullscreen(datatoc_workbench_effect_dof_frag_glsl, - "#define BLUR2\n"); - - e_data.dof_resolve_sh = DRW_shader_create_fullscreen(datatoc_workbench_effect_dof_frag_glsl, - "#define RESOLVE\n"); + e_data.dof_blur1_sh = DRW_shader_create_fullscreen(frag, "#define BLUR1\n"); + e_data.dof_blur2_sh = DRW_shader_create_fullscreen(frag, "#define BLUR2\n"); + e_data.dof_resolve_sh = DRW_shader_create_fullscreen(frag, "#define RESOLVE\n"); + MEM_freeN(frag); } *prepare_sh = e_data.dof_prepare_sh; diff --git a/source/blender/draw/engines/workbench/workbench_shadow.c b/source/blender/draw/engines/workbench/workbench_shadow.c index efd0ad9134e..2cf5f3c4c13 100644 --- a/source/blender/draw/engines/workbench/workbench_shadow.c +++ b/source/blender/draw/engines/workbench/workbench_shadow.c @@ -333,6 +333,11 @@ void workbench_shadow_cache_populate(WORKBENCH_Data *data, Object *ob, const boo use_shadow_pass_technique = false; } + /* We cannot use Shadow Pass technique on non-manifold object (see T76168). */ + if (use_shadow_pass_technique && !is_manifold && (wpd->cull_state != 0)) { + use_shadow_pass_technique = false; + } + if (use_shadow_pass_technique) { grp = DRW_shgroup_create_sub(wpd->shadow_pass_grp[is_manifold]); DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1); diff --git a/source/blender/draw/engines/workbench/workbench_transparent.c b/source/blender/draw/engines/workbench/workbench_transparent.c index 39aa721a41c..5fd8229304a 100644 --- a/source/blender/draw/engines/workbench/workbench_transparent.c +++ b/source/blender/draw/engines/workbench/workbench_transparent.c @@ -67,7 +67,7 @@ void workbench_transparent_engine_init(WORKBENCH_Data *data) static void workbench_transparent_lighting_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp) { - DRW_shgroup_uniform_block_persistent(grp, "world_block", wpd->world_ubo); + DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo); DRW_shgroup_uniform_bool_copy(grp, "forceShadowing", false); if (STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) { @@ -78,8 +78,8 @@ static void workbench_transparent_lighting_uniforms(WORKBENCH_PrivateData *wpd, struct GPUTexture *spec_tx = wpd->studio_light->matcap_specular.gputexture; const bool use_spec = workbench_is_specular_highlight_enabled(wpd); spec_tx = (use_spec && spec_tx) ? spec_tx : diff_tx; - DRW_shgroup_uniform_texture_persistent(grp, "matcapDiffuseImage", diff_tx); - DRW_shgroup_uniform_texture_persistent(grp, "matcapSpecularImage", spec_tx); + DRW_shgroup_uniform_texture(grp, "matcapDiffuseImage", diff_tx); + DRW_shgroup_uniform_texture(grp, "matcapSpecularImage", spec_tx); } } @@ -116,20 +116,20 @@ void workbench_transparent_cache_init(WORKBENCH_Data *data) workbench_transparent_lighting_uniforms(wpd, grp); wpd->prepass[transp][infront][hair].vcol_shgrp = grp = DRW_shgroup_create(sh, pass); - DRW_shgroup_uniform_block_persistent(grp, "material_block", wpd->material_ubo_curr); + DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr); DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. (uses vcol) */ sh = workbench_shader_transparent_image_get(wpd, hair, false); wpd->prepass[transp][infront][hair].image_shgrp = grp = DRW_shgroup_create(sh, pass); - DRW_shgroup_uniform_block_persistent(grp, "material_block", wpd->material_ubo_curr); + DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr); DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */ workbench_transparent_lighting_uniforms(wpd, grp); sh = workbench_shader_transparent_image_get(wpd, hair, true); wpd->prepass[transp][infront][hair].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass); - DRW_shgroup_uniform_block_persistent(grp, "material_block", wpd->material_ubo_curr); + DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr); DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */ workbench_transparent_lighting_uniforms(wpd, grp); } diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c index 951712d6ba3..21cb567aaae 100644 --- a/source/blender/draw/engines/workbench/workbench_volume.c +++ b/source/blender/draw/engines/workbench/workbench_volume.c @@ -28,6 +28,7 @@ #include "DNA_volume_types.h" #include "BLI_dynstr.h" +#include "BLI_listbase.h" #include "BLI_rand.h" #include "BLI_string_utils.h" @@ -290,7 +291,7 @@ void workbench_volume_draw_finish(WORKBENCH_Data *vedata) * modifier we don't want them to take precious VRAM if the * modifier is not used for display. We should share them for * all viewport in a redraw at least. */ - for (LinkData *link = wpd->smoke_domains.first; link; link = link->next) { + LISTBASE_FOREACH (LinkData *, link, &wpd->smoke_domains) { FluidModifierData *mmd = (FluidModifierData *)link->data; GPU_free_smoke(mmd); } |