3D View: Support vert & weight paint mask clipping
authorCampbell Barton <ideasman42@gmail.com>
Tue, 22 Jan 2019 11:20:19 +0000 (22:20 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 22 Jan 2019 11:22:20 +0000 (22:22 +1100)
source/blender/draw/modes/paint_vertex_mode.c
source/blender/draw/modes/paint_weight_mode.c
source/blender/draw/modes/shaders/paint_face_vert.glsl
source/blender/draw/modes/shaders/paint_texture_vert.glsl
source/blender/draw/modes/shaders/paint_vertex_vert.glsl
source/blender/draw/modes/shaders/paint_wire_vert.glsl

index 658631e..da0f032 100644 (file)
@@ -38,6 +38,8 @@
 
 #include "DEG_depsgraph_query.h"
 
+extern char datatoc_common_world_clip_lib_glsl[];
+
 extern char datatoc_paint_vertex_vert_glsl[];
 extern char datatoc_paint_vertex_frag_glsl[];
 extern char datatoc_paint_wire_vert_glsl[];
@@ -69,13 +71,17 @@ typedef struct PAINT_VERTEX_Data {
        PAINT_VERTEX_StorageList *stl;
 } PAINT_VERTEX_Data;
 
+typedef struct PAINT_VERTEX_Shaders {
+       struct GPUShader *vcolor_face;
+       struct GPUShader *wire_overlay;
+       struct GPUShader *face_overlay;
+       struct GPUShader *vert_overlay;
+} PAINT_VERTEX_Shaders;
+
 /* *********** STATIC *********** */
 
 static struct {
-       struct GPUShader *vcolor_face_shader;
-       struct GPUShader *wire_overlay_shader;
-       struct GPUShader *face_overlay_shader;
-       struct GPUShader *vert_overlay_shader;
+       PAINT_VERTEX_Shaders sh_data[2];
 } e_data = {NULL}; /* Engine data */
 
 typedef struct PAINT_VERTEX_PrivateData {
@@ -87,26 +93,47 @@ typedef struct PAINT_VERTEX_PrivateData {
 
 /* *********** FUNCTIONS *********** */
 
+static int PAINT_VERTEX_sh_data_index_from_rv3d(const RegionView3D *rv3d)
+{
+       if (rv3d->rflag & RV3D_CLIPPING) {
+               return 1;
+       }
+       return 0;
+}
+
 static void PAINT_VERTEX_engine_init(void *UNUSED(vedata))
 {
-       if (!e_data.vcolor_face_shader) {
-               e_data.vcolor_face_shader = DRW_shader_create(
-                       datatoc_paint_vertex_vert_glsl, NULL,
-                       datatoc_paint_vertex_frag_glsl, NULL);
-
-               e_data.wire_overlay_shader = DRW_shader_create_with_lib(
-                       datatoc_paint_wire_vert_glsl, NULL,
-                       datatoc_paint_wire_frag_glsl,
-                       datatoc_common_globals_lib_glsl, "#define VERTEX_MODE\n");
-
-               e_data.face_overlay_shader = DRW_shader_create(
-                       datatoc_paint_face_vert_glsl, NULL,
-                       datatoc_gpu_shader_uniform_color_frag_glsl, NULL);
-
-               e_data.vert_overlay_shader = DRW_shader_create_with_lib(
-                       datatoc_paint_wire_vert_glsl, NULL,
-                       datatoc_paint_vert_frag_glsl,
-                       datatoc_common_globals_lib_glsl, NULL);
+       const DRWContextState *draw_ctx = DRW_context_state_get();
+       PAINT_VERTEX_Shaders *sh_data = &e_data.sh_data[PAINT_VERTEX_sh_data_index_from_rv3d(draw_ctx->rv3d)];
+       const bool is_clip = (draw_ctx->rv3d->rflag & RV3D_CLIPPING) != 0;
+
+       if (is_clip) {
+               DRW_state_clip_planes_set_from_rv3d(draw_ctx->rv3d);
+       }
+
+       if (!sh_data->vcolor_face) {
+               const char *world_clip_lib_or_empty = is_clip ? datatoc_common_world_clip_lib_glsl : "";
+               const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : "";
+
+               sh_data->vcolor_face = DRW_shader_create_from_arrays({
+                       .vert = (const char *[]){world_clip_lib_or_empty, datatoc_paint_vertex_vert_glsl, NULL},
+                       .frag = (const char *[]){datatoc_paint_vertex_frag_glsl, NULL},
+                       .defs = (const char *[]){world_clip_def_or_empty, NULL}});
+
+               sh_data->wire_overlay = DRW_shader_create_from_arrays({
+                       .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_wire_vert_glsl, NULL},
+                       .frag = (const char *[]){datatoc_paint_wire_frag_glsl, NULL},
+                       .defs = (const char *[]){world_clip_def_or_empty, "#define VERTEX_MODE\n", NULL}});
+
+               sh_data->face_overlay = DRW_shader_create_from_arrays({
+                       .vert = (const char *[]){world_clip_lib_or_empty, datatoc_paint_face_vert_glsl, NULL},
+                       .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
+                       .defs = (const char *[]){world_clip_def_or_empty, NULL}});
+
+               sh_data->vert_overlay = DRW_shader_create_from_arrays({
+                       .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_wire_vert_glsl, NULL},
+                       .frag = (const char *[]){datatoc_paint_vert_frag_glsl, NULL},
+                       .defs = (const char *[]){world_clip_def_or_empty, NULL}});
        }
 }
 
@@ -116,6 +143,8 @@ static void PAINT_VERTEX_cache_init(void *vedata)
        PAINT_VERTEX_StorageList *stl = ((PAINT_VERTEX_Data *)vedata)->stl;
        const DRWContextState *draw_ctx = DRW_context_state_get();
        const View3D *v3d = draw_ctx->v3d;
+       const RegionView3D *rv3d = draw_ctx->rv3d;
+       PAINT_VERTEX_Shaders *sh_data = &e_data.sh_data[PAINT_VERTEX_sh_data_index_from_rv3d(rv3d)];
 
        if (!stl->g_data) {
                /* Alloc transient pointers */
@@ -128,8 +157,11 @@ static void PAINT_VERTEX_cache_init(void *vedata)
                        "Vert Color Pass",
                        DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_MULTIPLY);
 
-               stl->g_data->fvcolor_shgrp = DRW_shgroup_create(e_data.vcolor_face_shader, psl->vcolor_faces);
+               stl->g_data->fvcolor_shgrp = DRW_shgroup_create(sh_data->vcolor_face, psl->vcolor_faces);
                DRW_shgroup_uniform_float_copy(stl->g_data->fvcolor_shgrp, "white_factor", 1.0f - v3d->overlay.vertex_paint_mode_opacity);
+               if (rv3d->rflag & RV3D_CLIPPING) {
+                       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->fvcolor_shgrp, rv3d);
+               }
        }
 
        {
@@ -137,8 +169,11 @@ static void PAINT_VERTEX_cache_init(void *vedata)
                        "Wire Pass",
                        DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_OFFSET_NEGATIVE);
 
-               stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay);
+               stl->g_data->lwire_shgrp = DRW_shgroup_create(sh_data->wire_overlay, psl->wire_overlay);
                DRW_shgroup_uniform_block(stl->g_data->lwire_shgrp, "globalsBlock", G_draw.block_ubo);
+               if (rv3d->rflag & RV3D_CLIPPING) {
+                       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->lwire_shgrp, rv3d);
+               }
        }
 
        {
@@ -146,10 +181,12 @@ static void PAINT_VERTEX_cache_init(void *vedata)
                        "Face Mask Pass",
                        DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND);
 
-               stl->g_data->face_shgrp = DRW_shgroup_create(e_data.face_overlay_shader, psl->face_overlay);
-
+               stl->g_data->face_shgrp = DRW_shgroup_create(sh_data->face_overlay, psl->face_overlay);
                static float col[4] = {1.0f, 1.0f, 1.0f, 0.2f};
                DRW_shgroup_uniform_vec4(stl->g_data->face_shgrp, "color", col, 1);
+               if (rv3d->rflag & RV3D_CLIPPING) {
+                       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->face_shgrp, rv3d);
+               }
        }
 
        {
@@ -157,8 +194,11 @@ static void PAINT_VERTEX_cache_init(void *vedata)
                        "Vert Mask Pass",
                        DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_OFFSET_NEGATIVE);
 
-               stl->g_data->vert_shgrp = DRW_shgroup_create(e_data.vert_overlay_shader, psl->vert_overlay);
+               stl->g_data->vert_shgrp = DRW_shgroup_create(sh_data->vert_overlay, psl->vert_overlay);
                DRW_shgroup_uniform_block(stl->g_data->vert_shgrp, "globalsBlock", G_draw.block_ubo);
+               if (rv3d->rflag & RV3D_CLIPPING) {
+                       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->vert_shgrp, rv3d);
+               }
        }
 }
 
@@ -215,10 +255,13 @@ static void PAINT_VERTEX_draw_scene(void *vedata)
 
 static void PAINT_VERTEX_engine_free(void)
 {
-       DRW_SHADER_FREE_SAFE(e_data.vcolor_face_shader);
-       DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader);
-       DRW_SHADER_FREE_SAFE(e_data.vert_overlay_shader);
-       DRW_SHADER_FREE_SAFE(e_data.face_overlay_shader);
+       for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) {
+               PAINT_VERTEX_Shaders *sh_data = &e_data.sh_data[sh_data_index];
+               GPUShader **sh_data_as_array = (GPUShader **)sh_data;
+               for (int i = 0; i < (sizeof(PAINT_VERTEX_Shaders) / sizeof(GPUShader *)); i++) {
+                       DRW_SHADER_FREE_SAFE(sh_data_as_array[i]);
+               }
+       }
 }
 
 static const DrawEngineDataSize PAINT_VERTEX_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_VERTEX_Data);
index 87e832e..7ba4e70 100644 (file)
@@ -40,6 +40,8 @@
 
 #include "DEG_depsgraph_query.h"
 
+extern char datatoc_common_world_clip_lib_glsl[];
+
 extern char datatoc_paint_face_vert_glsl[];
 extern char datatoc_paint_weight_vert_glsl[];
 extern char datatoc_paint_weight_frag_glsl[];
@@ -71,13 +73,18 @@ typedef struct PAINT_WEIGHT_Data {
        PAINT_WEIGHT_StorageList *stl;
 } PAINT_WEIGHT_Data;
 
+typedef struct PAINT_WEIGHT_Shaders {
+       struct GPUShader *weight_face;
+       struct GPUShader *wire_overlay;
+       struct GPUShader *face_overlay;
+       struct GPUShader *vert_overlay;
+} PAINT_WEIGHT_Shaders;
+
 /* *********** STATIC *********** */
 
 static struct {
-       struct GPUShader *weight_face_shader;
-       struct GPUShader *wire_overlay_shader;
-       struct GPUShader *face_overlay_shader;
-       struct GPUShader *vert_overlay_shader;
+       PAINT_WEIGHT_Shaders sh_data[2];
+
        int actdef;
 } e_data = {NULL}; /* Engine data */
 
@@ -90,27 +97,47 @@ typedef struct PAINT_WEIGHT_PrivateData {
 
 /* *********** FUNCTIONS *********** */
 
+static int PAINT_WEIGHT_sh_data_index_from_rv3d(const RegionView3D *rv3d)
+{
+       if (rv3d->rflag & RV3D_CLIPPING) {
+               return 1;
+       }
+       return 0;
+}
+
 static void PAINT_WEIGHT_engine_init(void *UNUSED(vedata))
 {
-       if (!e_data.weight_face_shader) {
-               e_data.weight_face_shader = DRW_shader_create_with_lib(
-                       datatoc_paint_weight_vert_glsl, NULL,
-                       datatoc_paint_weight_frag_glsl,
-                       datatoc_common_globals_lib_glsl, NULL);
-
-               e_data.wire_overlay_shader = DRW_shader_create_with_lib(
-                       datatoc_paint_wire_vert_glsl, NULL,
-                       datatoc_paint_wire_frag_glsl,
-                       datatoc_common_globals_lib_glsl, "#define WEIGHT_MODE\n");
-
-               e_data.face_overlay_shader = DRW_shader_create(
-                       datatoc_paint_face_vert_glsl, NULL,
-                       datatoc_gpu_shader_uniform_color_frag_glsl, NULL);
-
-               e_data.vert_overlay_shader = DRW_shader_create_with_lib(
-                       datatoc_paint_wire_vert_glsl, NULL,
-                       datatoc_paint_vert_frag_glsl,
-                       datatoc_common_globals_lib_glsl, NULL);
+       const DRWContextState *draw_ctx = DRW_context_state_get();
+       PAINT_WEIGHT_Shaders *sh_data = &e_data.sh_data[PAINT_WEIGHT_sh_data_index_from_rv3d(draw_ctx->rv3d)];
+       const bool is_clip = (draw_ctx->rv3d->rflag & RV3D_CLIPPING) != 0;
+
+       if (is_clip) {
+               DRW_state_clip_planes_set_from_rv3d(draw_ctx->rv3d);
+       }
+
+       if (!sh_data->weight_face) {
+               const char *world_clip_lib_or_empty = is_clip ? datatoc_common_world_clip_lib_glsl : "";
+               const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : "";
+
+               sh_data->weight_face = DRW_shader_create_from_arrays({
+                       .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_weight_vert_glsl, NULL},
+                       .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_paint_weight_frag_glsl, NULL},
+                       .defs = (const char *[]){world_clip_def_or_empty, NULL}});
+
+               sh_data->wire_overlay = DRW_shader_create_from_arrays({
+                       .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_wire_vert_glsl, NULL},
+                       .frag = (const char *[]){datatoc_paint_wire_frag_glsl, NULL},
+                       .defs = (const char *[]){world_clip_def_or_empty, "#define WEIGHT_MODE\n", NULL}});
+
+               sh_data->face_overlay = DRW_shader_create_from_arrays({
+                       .vert = (const char *[]){world_clip_lib_or_empty, datatoc_paint_face_vert_glsl, NULL},
+                       .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
+                       .defs = (const char *[]){world_clip_def_or_empty, NULL}});
+
+               sh_data->vert_overlay = DRW_shader_create_from_arrays({
+                       .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_wire_vert_glsl, NULL},
+                       .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_paint_vert_frag_glsl, NULL},
+                       .defs = (const char *[]){world_clip_def_or_empty, NULL}});
        }
 }
 
@@ -120,6 +147,8 @@ static void PAINT_WEIGHT_cache_init(void *vedata)
        PAINT_WEIGHT_StorageList *stl = ((PAINT_WEIGHT_Data *)vedata)->stl;
        const DRWContextState *draw_ctx = DRW_context_state_get();
        const View3D *v3d = draw_ctx->v3d;
+       RegionView3D *rv3d = draw_ctx->rv3d;
+       PAINT_WEIGHT_Shaders *sh_data = &e_data.sh_data[PAINT_WEIGHT_sh_data_index_from_rv3d(rv3d)];
 
        if (!stl->g_data) {
                /* Alloc transient pointers */
@@ -132,13 +161,16 @@ static void PAINT_WEIGHT_cache_init(void *vedata)
                        "Weight Pass",
                        DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_MULTIPLY);
 
-               stl->g_data->fweights_shgrp = DRW_shgroup_create(e_data.weight_face_shader, psl->weight_faces);
+               stl->g_data->fweights_shgrp = DRW_shgroup_create(sh_data->weight_face, psl->weight_faces);
 
                DRW_shgroup_uniform_bool_copy(stl->g_data->fweights_shgrp, "drawContours", (v3d->overlay.wpaint_flag & V3D_OVERLAY_WPAINT_CONTOURS) != 0);
 
                DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "opacity", &v3d->overlay.weight_paint_mode_opacity, 1);
                DRW_shgroup_uniform_texture(stl->g_data->fweights_shgrp, "colorramp", G_draw.weight_ramp);
                DRW_shgroup_uniform_block(stl->g_data->fweights_shgrp, "globalsBlock", G_draw.block_ubo);
+               if (rv3d->rflag & RV3D_CLIPPING) {
+                       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->fweights_shgrp, rv3d);
+               }
        }
 
        {
@@ -146,8 +178,11 @@ static void PAINT_WEIGHT_cache_init(void *vedata)
                        "Wire Pass",
                        DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_OFFSET_NEGATIVE);
 
-               stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay);
+               stl->g_data->lwire_shgrp = DRW_shgroup_create(sh_data->wire_overlay, psl->wire_overlay);
                DRW_shgroup_uniform_block(stl->g_data->lwire_shgrp, "globalsBlock", G_draw.block_ubo);
+               if (rv3d->rflag & RV3D_CLIPPING) {
+                       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->lwire_shgrp, rv3d);
+               }
        }
 
        {
@@ -155,10 +190,13 @@ static void PAINT_WEIGHT_cache_init(void *vedata)
                        "Face Mask Pass",
                        DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND);
 
-               stl->g_data->face_shgrp = DRW_shgroup_create(e_data.face_overlay_shader, psl->face_overlay);
+               stl->g_data->face_shgrp = DRW_shgroup_create(sh_data->face_overlay, psl->face_overlay);
 
                static float col[4] = {1.0f, 1.0f, 1.0f, 0.2f};
                DRW_shgroup_uniform_vec4(stl->g_data->face_shgrp, "color", col, 1);
+               if (rv3d->rflag & RV3D_CLIPPING) {
+                       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->face_shgrp, rv3d);
+               }
        }
 
        {
@@ -166,8 +204,11 @@ static void PAINT_WEIGHT_cache_init(void *vedata)
                        "Vert Mask Pass",
                        DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_OFFSET_NEGATIVE);
 
-               stl->g_data->vert_shgrp = DRW_shgroup_create(e_data.vert_overlay_shader, psl->vert_overlay);
+               stl->g_data->vert_shgrp = DRW_shgroup_create(sh_data->vert_overlay, psl->vert_overlay);
                DRW_shgroup_uniform_block(stl->g_data->vert_shgrp, "globalsBlock", G_draw.block_ubo);
+               if (rv3d->rflag & RV3D_CLIPPING) {
+                       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->vert_shgrp, rv3d);
+               }
        }
 }
 
@@ -219,10 +260,13 @@ static void PAINT_WEIGHT_draw_scene(void *vedata)
 
 static void PAINT_WEIGHT_engine_free(void)
 {
-       DRW_SHADER_FREE_SAFE(e_data.weight_face_shader);
-       DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader);
-       DRW_SHADER_FREE_SAFE(e_data.vert_overlay_shader);
-       DRW_SHADER_FREE_SAFE(e_data.face_overlay_shader);
+       for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) {
+               PAINT_WEIGHT_Shaders *sh_data = &e_data.sh_data[sh_data_index];
+               GPUShader **sh_data_as_array = (GPUShader **)sh_data;
+               for (int i = 0; i < (sizeof(PAINT_WEIGHT_Shaders) / sizeof(GPUShader *)); i++) {
+                       DRW_SHADER_FREE_SAFE(sh_data_as_array[i]);
+               }
+       }
 }
 
 static const DrawEngineDataSize PAINT_WEIGHT_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_WEIGHT_Data);
index 437eeb2..a850a13 100644 (file)
@@ -1,5 +1,6 @@
 
 uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 ModelMatrix;
 
 in vec3 pos;
 in vec4 nor; /* select flag on the 4th component */
@@ -11,4 +12,9 @@ void main()
        if (nor.w > 0.0) {
                gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
        }
+       else {
+#ifdef USE_WORLD_CLIP_PLANES
+               world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+#endif
+       }
 }
index 8eae494..c53439f 100644 (file)
@@ -1,5 +1,6 @@
 
 uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 ModelMatrix;
 
 in vec2 u; /* active uv map */
 in vec3 pos;
@@ -11,4 +12,8 @@ void main()
        gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
 
        uv_interp = u;
+
+#ifdef USE_WORLD_CLIP_PLANES
+               world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+#endif
 }
index e52c17e..7d2a20a 100644 (file)
@@ -1,5 +1,6 @@
 
 uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 ModelMatrix;
 
 in vec3 pos;
 in vec3 c; /* active color */
@@ -18,4 +19,8 @@ void main()
        gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
 
        finalColor = srgb_to_linear_attrib(c);
+
+#ifdef USE_WORLD_CLIP_PLANES
+       world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+#endif
 }
index b5ef921..2b8838f 100644 (file)
@@ -1,5 +1,6 @@
 
 uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 ModelMatrix;
 
 in vec3 pos;
 in vec4 nor; /* flag stored in w */
@@ -28,4 +29,8 @@ void main()
 
        finalColor = (is_select) ? colSel : colorWire;
        finalColor.a = nor.w;
+
+#ifdef USE_WORLD_CLIP_PLANES
+       world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+#endif
 }