From 851d58b34f11f73403729d595116a1b189093821 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 29 Jan 2019 19:57:35 +1100 Subject: DRW: support clipping for all lamp types --- source/blender/draw/intern/draw_builtin_shader.c | 9 ++++-- source/blender/draw/intern/draw_common.c | 32 ++++++++++++++-------- source/blender/draw/intern/draw_common.h | 8 +++--- source/blender/draw/modes/object_mode.c | 20 +++++++------- .../draw/modes/shaders/common_world_clip_lib.glsl | 2 +- .../gpu/shaders/gpu_shader_3D_groundline_geom.glsl | 9 ++++++ .../shaders/gpu_shader_3D_groundpoint_vert.glsl | 7 ++++- .../shaders/gpu_shader_3D_passthrough_vert.glsl | 10 ++++++- .../gpu_shader_instance_distance_line_vert.glsl | 7 ++++- ..._shader_instance_edges_variying_color_geom.glsl | 8 ++++++ ..._shader_instance_edges_variying_color_vert.glsl | 7 ++++- 11 files changed, 86 insertions(+), 33 deletions(-) (limited to 'source') diff --git a/source/blender/draw/intern/draw_builtin_shader.c b/source/blender/draw/intern/draw_builtin_shader.c index 0b3fc45f5e7..2c3d656da2c 100644 --- a/source/blender/draw/intern/draw_builtin_shader.c +++ b/source/blender/draw/intern/draw_builtin_shader.c @@ -50,7 +50,11 @@ extern char datatoc_common_world_clip_lib_glsl[]; GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA, \ GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA, \ GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR, \ - GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED) + GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED, \ + GPU_SHADER_3D_GROUNDLINE, \ + GPU_SHADER_3D_GROUNDPOINT, \ + GPU_SHADER_DISTANCE_LINES, \ + GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR) /* cache of built-in shaders (each is created on first use) */ static struct { @@ -70,9 +74,10 @@ static GPUShader *drw_shader_get_builtin_shader_clipped(eGPUBuiltinShader shader &shader_code.geom, &shader_code.defs); + /* In rare cases geometry shaders calculate clipping themselves. */ return DRW_shader_create_from_arrays({ .vert = (const char *[]){world_clip_lib, shader_code.vert, NULL}, - .geom = (const char *[]){shader_code.geom, NULL}, + .geom = (const char *[]){shader_code.geom ? world_clip_lib : NULL, shader_code.geom, NULL}, .frag = (const char *[]){shader_code.frag, NULL}, .defs = (const char *[]){world_clip_def, shader_code.defs, NULL}}); } diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index 28bd39e9090..676c401cf44 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -358,24 +358,28 @@ DRWShadingGroup *shgroup_dynpoints_uniform_color( return grp; } -DRWShadingGroup *shgroup_groundlines_uniform_color(DRWPass *pass, const float color[4]) +DRWShadingGroup *shgroup_groundlines_uniform_color(DRWPass *pass, const float color[4], eDRW_ShaderSlot shader_slot) { - GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDLINE); + GPUShader *sh = DRW_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDLINE, shader_slot); DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass); DRW_shgroup_uniform_vec4(grp, "color", color, 1); - + if (shader_slot == DRW_SHADER_SLOT_CLIPPED) { + DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d); + } return grp; } -DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass, const float color[4]) +DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass, const float color[4], eDRW_ShaderSlot shader_slot) { - GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDPOINT); + GPUShader *sh = DRW_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDPOINT, shader_slot); DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass); DRW_shgroup_uniform_vec4(grp, "color", color, 1); DRW_shgroup_state_enable(grp, DRW_STATE_POINT); - + if (shader_slot == DRW_SHADER_SLOT_CLIPPED) { + DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d); + } return grp; } @@ -561,9 +565,9 @@ DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct GPUBatch *geom, e return grp; } -DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct GPUBatch *geom) +DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot) { - GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_DISTANCE_LINES); + GPUShader *sh_inst = DRW_shader_get_builtin_shader(GPU_SHADER_DISTANCE_LINES, shader_slot); static float point_size = 4.0f; DRW_shgroup_instance_format(g_formats.instance_distance_lines, { @@ -575,13 +579,15 @@ DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct GPUBatch DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_distance_lines); DRW_shgroup_uniform_float(grp, "size", &point_size, 1); - + if (shader_slot == DRW_SHADER_SLOT_CLIPPED) { + DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d); + } return grp; } -DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct GPUBatch *geom) +DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot) { - GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR); + GPUShader *sh_inst = DRW_shader_get_builtin_shader(GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR, shader_slot); static const int True = true; static const int False = false; @@ -594,7 +600,9 @@ DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct GPUBatch *geom) DRW_shgroup_uniform_bool(grp, "drawFront", &False, 1); DRW_shgroup_uniform_bool(grp, "drawBack", &False, 1); DRW_shgroup_uniform_bool(grp, "drawSilhouette", &True, 1); - + if (shader_slot == DRW_SHADER_SLOT_CLIPPED) { + DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d); + } return grp; } diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index 39a895632bd..dffe4f2ebc9 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -143,8 +143,8 @@ void DRW_shgroup_world_clip_planes_from_rv3d(struct DRWShadingGroup *shgrp, cons struct DRWShadingGroup *shgroup_dynlines_flat_color(struct DRWPass *pass); struct DRWShadingGroup *shgroup_dynlines_dashed_uniform_color(struct DRWPass *pass, const float color[4]); struct DRWShadingGroup *shgroup_dynpoints_uniform_color(struct DRWPass *pass, const float color[4], const float *size, eDRW_ShaderSlot shader_slot); -struct DRWShadingGroup *shgroup_groundlines_uniform_color(struct DRWPass *pass, const float color[4]); -struct DRWShadingGroup *shgroup_groundpoints_uniform_color(struct DRWPass *pass, const float color[4]); +struct DRWShadingGroup *shgroup_groundlines_uniform_color(struct DRWPass *pass, const float color[4], eDRW_ShaderSlot shader_slot); +struct DRWShadingGroup *shgroup_groundpoints_uniform_color(struct DRWPass *pass, const float color[4], eDRW_ShaderSlot shader_slot); struct DRWShadingGroup *shgroup_instance_screenspace(struct DRWPass *pass, struct GPUBatch *geom, const float *size, eDRW_ShaderSlot shader_slot); struct DRWShadingGroup *shgroup_instance_solid(struct DRWPass *pass, struct GPUBatch *geom); struct DRWShadingGroup *shgroup_instance_wire(struct DRWPass *pass, struct GPUBatch *geom); @@ -155,8 +155,8 @@ struct DRWShadingGroup *shgroup_instance(struct DRWPass *pass, struct GPUBatch * struct DRWShadingGroup *shgroup_instance_alpha(struct DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot); struct DRWShadingGroup *shgroup_instance_outline(struct DRWPass *pass, struct GPUBatch *geom, int *baseid); struct DRWShadingGroup *shgroup_camera_instance(struct DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot); -struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, struct GPUBatch *geom); -struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct GPUBatch *geom); +struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot); +struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot); struct DRWShadingGroup *shgroup_instance_mball_handles(struct DRWPass *pass); struct DRWShadingGroup *shgroup_instance_bone_axes(struct DRWPass *pass); struct DRWShadingGroup *shgroup_instance_bone_envelope_distance(struct DRWPass *pass); diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index ed047b93f9f..a64d7f288ca 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -1252,12 +1252,12 @@ static void OBJECT_cache_init(void *vedata) sgl->camera_focus = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot); geom = DRW_cache_single_line_get(); - sgl->camera_clip = shgroup_distance_lines_instance(sgl->non_meshes, geom); - sgl->camera_mist = shgroup_distance_lines_instance(sgl->non_meshes, geom); + sgl->camera_clip = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_slot); + sgl->camera_mist = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_slot); geom = DRW_cache_single_line_endpoints_get(); - sgl->camera_clip_points = shgroup_distance_lines_instance(sgl->non_meshes, geom); - sgl->camera_mist_points = shgroup_distance_lines_instance(sgl->non_meshes, geom); + sgl->camera_clip_points = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_slot); + sgl->camera_mist_points = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_slot); geom = DRW_cache_quad_get(); sgl->camera_stereo_plane = shgroup_instance_alpha(sgl->non_meshes, geom, draw_ctx->shader_slot); @@ -1310,7 +1310,7 @@ static void OBJECT_cache_init(void *vedata) /* start with buflimit because we don't want stipples */ geom = DRW_cache_single_line_get(); - sgl->lamp_buflimit = shgroup_distance_lines_instance(sgl->non_meshes, geom); + sgl->lamp_buflimit = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_slot); sgl->lamp_center = shgroup_dynpoints_uniform_color(sgl->non_meshes, gb->colorLampNoAlpha, &gb->sizeLampCenter, draw_ctx->shader_slot); @@ -1322,8 +1322,8 @@ static void OBJECT_cache_init(void *vedata) geom = DRW_cache_lamp_sunrays_get(); sgl->lamp_sunrays = shgroup_instance_screenspace(sgl->non_meshes, geom, &gb->sizeLampCircle, draw_ctx->shader_slot); - sgl->lamp_groundline = shgroup_groundlines_uniform_color(sgl->non_meshes, gb->colorLamp); - sgl->lamp_groundpoint = shgroup_groundpoints_uniform_color(sgl->non_meshes, gb->colorLamp); + sgl->lamp_groundline = shgroup_groundlines_uniform_color(sgl->non_meshes, gb->colorLamp, draw_ctx->shader_slot); + sgl->lamp_groundpoint = shgroup_groundpoints_uniform_color(sgl->non_meshes, gb->colorLamp, draw_ctx->shader_slot); geom = DRW_cache_screenspace_circle_get(); sgl->lamp_area_sphere = shgroup_instance_screen_aligned(sgl->non_meshes, geom, draw_ctx->shader_slot); @@ -1338,13 +1338,13 @@ static void OBJECT_cache_init(void *vedata) sgl->lamp_hemi = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot); geom = DRW_cache_single_line_get(); - sgl->lamp_distance = shgroup_distance_lines_instance(sgl->non_meshes, geom); + sgl->lamp_distance = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_slot); geom = DRW_cache_single_line_endpoints_get(); - sgl->lamp_buflimit_points = shgroup_distance_lines_instance(sgl->non_meshes, geom); + sgl->lamp_buflimit_points = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_slot); geom = DRW_cache_lamp_spot_get(); - sgl->lamp_spot_cone = shgroup_spot_instance(sgl->non_meshes, geom); + sgl->lamp_spot_cone = shgroup_spot_instance(sgl->non_meshes, geom, draw_ctx->shader_slot); geom = DRW_cache_circle_get(); sgl->lamp_spot_blend = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot); diff --git a/source/blender/draw/modes/shaders/common_world_clip_lib.glsl b/source/blender/draw/modes/shaders/common_world_clip_lib.glsl index b889780751e..6964b2a0c39 100644 --- a/source/blender/draw/modes/shaders/common_world_clip_lib.glsl +++ b/source/blender/draw/modes/shaders/common_world_clip_lib.glsl @@ -1,5 +1,5 @@ #ifdef USE_WORLD_CLIP_PLANES -#ifdef GPU_VERTEX_SHADER +#if defined(GPU_VERTEX_SHADER) || defined(GPU_GEOMETRY_SHADER) uniform vec4 WorldClipPlanes[6]; void world_clip_planes_calc_clip_distance(vec3 wpos) { diff --git a/source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl b/source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl index f16fa21b342..29bdd03f7e3 100644 --- a/source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl +++ b/source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl @@ -8,9 +8,18 @@ layout(line_strip, max_vertices = 2) out; void main() { vec3 vert = gl_in[0].gl_Position.xyz; + gl_Position = ViewProjectionMatrix * vec4(vert.xyz, 1.0); +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_set_clip_distance(gl_in[0].gl_ClipDistance); +#endif EmitVertex(); + gl_Position = ViewProjectionMatrix * vec4(vert.xy, 0.0, 1.0); +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance(vec3(vert.xy, 0.0)); +#endif EmitVertex(); + EndPrimitive(); } diff --git a/source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl index 55f410eb25d..b08d87cdfa6 100644 --- a/source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl @@ -6,6 +6,11 @@ in vec3 pos; void main() { - gl_Position = ViewProjectionMatrix * vec4(pos.xy, 0.0, 1.0); + vec4 pos_4d = vec4(pos.xy, 0.0, 1.0); + gl_Position = ViewProjectionMatrix * pos_4d; gl_PointSize = 2.0; + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance(pos_4d.xyz); +#endif } diff --git a/source/blender/gpu/shaders/gpu_shader_3D_passthrough_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_passthrough_vert.glsl index 60793bf56b6..4196dbbad02 100644 --- a/source/blender/gpu/shaders/gpu_shader_3D_passthrough_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_3D_passthrough_vert.glsl @@ -1,8 +1,16 @@ +#ifdef USE_WORLD_CLIP_PLANES +uniform mat4 ModelMatrix; +#endif /* Does Nothing */ in vec3 pos; void main() { - gl_Position = vec4(pos, 1.0); + vec4 pos_4d = vec4(pos, 1.0); + gl_Position = pos_4d; + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance((ModelMatrix * pos_4d).xyz); +#endif } diff --git a/source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl index 432b6cac049..2097b900666 100644 --- a/source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl @@ -18,8 +18,13 @@ void main() { float len = end - start; vec3 sta = vec3(0.0, 0.0, -start); + vec4 pos_4d = vec4(pos * -len + sta, 1.0); - gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pos * -len + sta, 1.0); + gl_Position = ViewProjectionMatrix * InstanceModelMatrix * pos_4d; gl_PointSize = size; finalColor = vec4(color, 1.0); + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance((InstanceModelMatrix * pos_4d).xyz); +#endif } diff --git a/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl index e26f419b8cd..c19598ea8ab 100644 --- a/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl +++ b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl @@ -28,10 +28,18 @@ flat out vec4 finalColor; void emitLine(vec4 color) { gl_Position = ProjectionMatrix * MV_pos[0]; +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_set_clip_distance(gl_in[0].gl_ClipDistance); +#endif EmitVertex(); + gl_Position = ProjectionMatrix * MV_pos[1]; +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_set_clip_distance(gl_in[1].gl_ClipDistance); +#endif finalColor = color; EmitVertex(); + EndPrimitive(); } diff --git a/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl index 9de50246a40..3877c63d00a 100644 --- a/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl @@ -37,7 +37,8 @@ void main() mat4 ModelViewMatrix = ViewMatrix * InstanceModelMatrix; - MV_pos = ModelViewMatrix * vec4(pos, 1.0); + vec4 pos_4d = vec4(pos, 1.0); + MV_pos = ModelViewMatrix * pos_4d; mat3 NormalMatrix = transpose(inverse(mat3(ModelViewMatrix))); @@ -60,4 +61,8 @@ void main() edgeClass = -1.0; // back-facing edge fCol = color; + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance((InstanceModelMatrix * vec4(pos, 1.0)).xyz); +#endif } -- cgit v1.2.3