diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index b264b457396..3dfb262414b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6675,10 +6675,6 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) rv3d->render_engine = NULL; rv3d->sms = NULL; rv3d->smooth_timer = NULL; - - /* TODO: support clipping in 2.8x, - * Tools use clipping which is confusing when it isn't displayed, T59580. */ - rv3d->rflag &= ~RV3D_CLIPPING; } } } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl index 7c5b528c40d..e821581298d 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl @@ -1,10 +1,16 @@ uniform mat4 ModelViewProjectionMatrix; +uniform mat4 ModelMatrix; uniform mat4 ModelMatrixInverse; uniform mat4 ProjectionMatrix; uniform mat4 ViewProjectionMatrix; uniform mat4 ViewMatrixInverse; uniform mat3 NormalMatrix; +#ifdef USE_WORLD_CLIP_PLANES +uniform vec4 WorldClipPlanes[6]; +uniform int WorldClipPlanesLen; +#endif + #ifndef HAIR_SHADER in vec3 pos; in vec3 nor; @@ -68,4 +74,14 @@ void main() normal_viewport = normalize(normal_viewport); # endif #endif + +#ifdef USE_WORLD_CLIP_PLANES + { + vec3 worldPosition = (ModelMatrix * vec4(pos, 1.0)).xyz; + for (int i = 0; i < WorldClipPlanesLen; i++) { + gl_ClipDistance[i] = dot(WorldClipPlanes[i].xyz, worldPosition) + WorldClipPlanes[i].w; + } + } +#endif + } diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index 937378dabb4..427ae4063f9 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -88,6 +88,18 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) wd->curvature_ridge = 0.5f / max_ff(SQUARE(wpd->shading.curvature_ridge_factor), 1e-4f); wd->curvature_valley = 0.7f / max_ff(SQUARE(wpd->shading.curvature_valley_factor), 1e-4f); + { + RegionView3D *rv3d = draw_ctx->rv3d; + if (rv3d->rflag & RV3D_CLIPPING) { + memcpy(wpd->world_clip_planes, rv3d->clip, sizeof(float[6][4])); + wpd->world_clip_planes_len = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6; + DRW_state_clip_planes_count_set(6); + } + else { + wpd->world_clip_planes_len = 0; + } + } + wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), &wpd->world_data); /* Cavity settings */ @@ -172,6 +184,13 @@ void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, floa DRW_uniformbuffer_update(wpd->world_ubo, wd); } +void workbench_private_draw_finish(WORKBENCH_PrivateData *wpd) +{ + if (wpd->world_clip_planes_len) { + DRW_state_clip_planes_reset(); + } +} + void workbench_private_data_free(WORKBENCH_PrivateData *wpd) { BLI_ghash_free(wpd->material_hash, NULL, MEM_freeN); diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index 3f537f6c6d0..5868ad90206 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -1081,6 +1081,7 @@ void workbench_deferred_draw_finish(WORKBENCH_Data *vedata) WORKBENCH_StorageList *stl = vedata->stl; WORKBENCH_PrivateData *wpd = stl->g_data; + workbench_private_draw_finish(wpd); workbench_private_data_free(wpd); workbench_volume_smoke_textures_free(wpd); } diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index 94cbb20ef5f..0ccc95d6b94 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -647,6 +647,7 @@ void workbench_forward_draw_finish(WORKBENCH_Data *vedata) WORKBENCH_StorageList *stl = vedata->stl; WORKBENCH_PrivateData *wpd = stl->g_data; + workbench_private_draw_finish(wpd); workbench_private_data_free(wpd); workbench_volume_smoke_textures_free(wpd); } diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c index 679f11620b4..ce71189f344 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -110,6 +110,9 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_text if (is_hair) { BLI_dynstr_appendf(ds, "#define HAIR_SHADER\n"); } + if (wpd->world_clip_planes_len) { + BLI_dynstr_appendf(ds, "#define USE_WORLD_CLIP_PLANES\n"); + } str = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); @@ -168,6 +171,7 @@ int workbench_material_get_prepass_shader_index( SET_FLAG_FROM_TEST(index, NORMAL_VIEWPORT_PASS_ENABLED(wpd), 1 << 3); SET_FLAG_FROM_TEST(index, MATCAP_ENABLED(wpd), 1 << 4); SET_FLAG_FROM_TEST(index, use_textures, 1 << 5); + SET_FLAG_FROM_TEST(index, wpd->world_clip_planes_len != 0, 1 << 6); return index; } @@ -236,6 +240,12 @@ void workbench_material_shgroup_uniform( } DRW_shgroup_uniform_float(grp, "materialRoughness", &material->roughness, 1); } + + if (wpd->world_clip_planes_len) { + DRW_shgroup_uniform_vec4(grp, "WorldClipPlanes", wpd->world_clip_planes[0], wpd->world_clip_planes_len); + DRW_shgroup_uniform_int(grp, "WorldClipPlanesLen", &wpd->world_clip_planes_len, 1); + DRW_shgroup_state_enable(grp, DRW_STATE_CLIP_PLANES); + } } void workbench_material_copy(WORKBENCH_MaterialData *dest_material, const WORKBENCH_MaterialData *source_material) diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index e7712ff8f32..e38c7ae424d 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -41,7 +41,7 @@ #define WORKBENCH_ENGINE "BLENDER_WORKBENCH" #define M_GOLDEN_RATION_CONJUGATE 0.618033988749895 #define MAX_COMPOSITE_SHADERS (1 << 6) -#define MAX_PREPASS_SHADERS (1 << 6) +#define MAX_PREPASS_SHADERS (1 << 7) #define MAX_ACCUM_SHADERS (1 << 4) #define MAX_CAVITY_SHADERS (1 << 3) @@ -200,6 +200,9 @@ typedef struct WORKBENCH_PrivateData { bool shadow_changed; bool is_playback; + float world_clip_planes[6][4]; + int world_clip_planes_len; + /* Volumes */ bool volumes_do; ListBase smoke_domains; @@ -318,6 +321,7 @@ bool studiolight_camera_in_object_shadow(WORKBENCH_PrivateData *wpd, Object *ob, /* workbench_data.c */ void workbench_effect_info_init(WORKBENCH_EffectInfo *effect_info); void workbench_private_data_init(WORKBENCH_PrivateData *wpd); +void workbench_private_draw_finish(WORKBENCH_PrivateData *wpd); void workbench_private_data_free(WORKBENCH_PrivateData *wpd); void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float r_light_direction[3]);