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.
This commit is contained in:
Clément Foucault 2018-06-03 15:13:33 +02:00
parent 778a19a13a
commit d0f7ab27a8
4 changed files with 78 additions and 2 deletions

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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
}