diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-06-03 16:13:33 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-06-03 16:26:37 +0300 |
commit | d0f7ab27a898757fe444ac778bf072c268042feb (patch) | |
tree | 14cb3b26759d65052e50b9bed3bd4e6ee281722f | |
parent | 778a19a13a1cd9a84563ca66653861b79651d2a5 (diff) |
Wireframe: Optimization for intel GPUs.
Intel GPU take more advantage of the geometry shader than other vendors.
Using a simple geom shader approach in this case is more performant.
4 files changed, 78 insertions, 2 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 2b6d261d43e..40fd8762821 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -279,6 +279,7 @@ data_to_c_simple(modes/shaders/edit_normals_geom.glsl SRC) data_to_c_simple(modes/shaders/overlay_face_orientation_frag.glsl SRC) data_to_c_simple(modes/shaders/overlay_face_orientation_vert.glsl SRC) data_to_c_simple(modes/shaders/overlay_face_wireframe_vert.glsl SRC) +data_to_c_simple(modes/shaders/overlay_face_wireframe_geom.glsl SRC) data_to_c_simple(modes/shaders/overlay_face_wireframe_frag.glsl SRC) data_to_c_simple(modes/shaders/object_empty_image_frag.glsl SRC) data_to_c_simple(modes/shaders/object_empty_image_vert.glsl SRC) diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c index 505472460a1..131a9bc10db 100644 --- a/source/blender/draw/modes/overlay_mode.c +++ b/source/blender/draw/modes/overlay_mode.c @@ -28,6 +28,7 @@ #include "BKE_object.h" #include "GPU_shader.h" +#include "GPU_extensions.h" #include "DRW_render.h" #include "draw_mode_engines.h" @@ -68,6 +69,7 @@ extern char datatoc_overlay_face_orientation_frag_glsl[]; extern char datatoc_overlay_face_orientation_vert_glsl[]; extern char datatoc_overlay_face_wireframe_vert_glsl[]; +extern char datatoc_overlay_face_wireframe_geom_glsl[]; extern char datatoc_overlay_face_wireframe_frag_glsl[]; extern struct GlobalsUboStorage ts; /* draw_common.c */ @@ -91,8 +93,13 @@ static void overlay_engine_init(void *vedata) } if (!e_data.face_wireframe_sh) { + char *wireframe_geom = NULL; + if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) { + wireframe_geom = datatoc_overlay_face_wireframe_geom_glsl; + } e_data.face_wireframe_sh = DRW_shader_create( - datatoc_overlay_face_wireframe_vert_glsl, NULL, + datatoc_overlay_face_wireframe_vert_glsl, + wireframe_geom, datatoc_overlay_face_wireframe_frag_glsl, NULL); } } diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl new file mode 100644 index 00000000000..1cea418419e --- /dev/null +++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl @@ -0,0 +1,42 @@ + +layout(triangles) in; +layout(triangle_strip, max_vertices = 3) out; + +in vec2 ssPos[]; +in float facingOut[]; + +flat out vec3 ssVec0; +flat out vec3 ssVec1; +flat out vec3 ssVec2; +out float facing; + +#define NO_EDGE vec3(10000.0); + +vec3 compute_vec(vec2 v0, vec2 v1) +{ + vec2 v = normalize(v1 - v0); + v = vec2(-v.y, v.x); + return vec3(v, -dot(v, v0)); +} + +void main(void) +{ + vec3 facings = vec3(facingOut[0], facingOut[1], facingOut[2]); + bvec3 do_edge = greaterThan(abs(facings), vec3(1.0)); + facings = fract(facings) - clamp(-sign(facings), 0.0, 1.0); + + ssVec0 = do_edge.x ? compute_vec(ssPos[0], ssPos[1]) : NO_EDGE; + ssVec1 = do_edge.y ? compute_vec(ssPos[1], ssPos[2]) : NO_EDGE; + ssVec2 = do_edge.z ? compute_vec(ssPos[2], ssPos[0]) : NO_EDGE; + + gl_Position = gl_in[0].gl_Position; + facing = facings.x; + EmitVertex(); + gl_Position = gl_in[1].gl_Position; + facing = facings.y; + EmitVertex(); + gl_Position = gl_in[2].gl_Position; + facing = facings.z; + EmitVertex(); + EndPrimitive(); +} diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl index 67f4a5c7668..2cd888e7537 100644 --- a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl +++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl @@ -1,3 +1,8 @@ + +#ifdef GPU_INTEL +#define USE_GEOM_SHADER +#endif + uniform mat4 ModelViewProjectionMatrix; uniform mat4 ModelViewMatrix; uniform mat4 ProjectionMatrix; @@ -9,10 +14,15 @@ uniform float nearDist; uniform samplerBuffer vertData; uniform isamplerBuffer faceIds; +#ifdef USE_GEOM_SHADER +out vec2 ssPos; +out float facingOut; /* abs(facing) > 1.0 if we do edge */ +#else flat out vec3 ssVec0; flat out vec3 ssVec1; flat out vec3 ssVec2; out float facing; +#endif /* project to screen space */ vec2 proj(vec4 pos) @@ -67,6 +77,21 @@ vec3 get_vertex_pos(int v_id) void main() { +#ifdef USE_GEOM_SHADER + int v_id = texelFetch(faceIds, gl_VertexID).r; + + bool do_edge = v_id < 0; + v_id = abs(v_id) - 1; + + vec3 pos = get_vertex_pos(v_id); + vec3 nor = get_vertex_nor(v_id); + facingOut = normalize(NormalMatrix * nor).z; + facingOut += (do_edge) ? ((facingOut > 0.0) ? 2.0 : -2.0) : 0.0; + + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + ssPos = proj(gl_Position); + +#else int v_0 = (gl_VertexID / 3) * 3; int v_n = gl_VertexID % 3; @@ -102,5 +127,6 @@ void main() gl_Position = p_pos[v_n]; vec3 nor = get_vertex_nor(v_id[v_n]); - facing = (NormalMatrix * nor).z; + facing = normalize(NormalMatrix * nor).z; +#endif } |