diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-09-29 20:42:09 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-10-01 16:14:46 +0300 |
commit | 781995a09c0b52ad2fd073510c2f7dc52383d461 (patch) | |
tree | f821cce3fa5f69435a20e450d709fec37cb95b4a /source/blender/gpu | |
parent | a5101de6a95647d19821bde9f8d68776ce8881fa (diff) |
Edit UVs: Refactor drawing Edit UV in Image Editor
NOTE: This commit only concern edit UVs and not the "shadow" mesh displayed
when texture painting. This will be address in a future commit.
We now cache the uv mesh in the mesh batch cache and only reupload data on
changes.
Update could be more granular (and a bit faster) but it's not our main
concern ATM.
This should fix problem caused by the IMM api used to draw large meshes.
This makes performance skyrocket compared to previous implementation.
There is still a big CPU bottleneck when not in sync selection mode but it
is not related to the drawing function directly.
Diffstat (limited to 'source/blender/gpu')
9 files changed, 234 insertions, 0 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 5c010a58137..e8ed5de82cb 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -205,6 +205,7 @@ data_to_c_simple(shaders/gpu_shader_point_uniform_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_point_uniform_color_aa_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_point_varying_color_outline_aa_frag.glsl SRC) +data_to_c_simple(shaders/gpu_shader_point_varying_color_varying_outline_aa_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_point_varying_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_3D_point_varying_size_vert.glsl SRC) @@ -216,6 +217,12 @@ data_to_c_simple(shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert.glsl SRC) +data_to_c_simple(shaders/gpu_shader_2D_edituvs_points_vert.glsl SRC) +data_to_c_simple(shaders/gpu_shader_2D_edituvs_facedots_vert.glsl SRC) +data_to_c_simple(shaders/gpu_shader_2D_edituvs_edges_vert.glsl SRC) +data_to_c_simple(shaders/gpu_shader_2D_edituvs_faces_vert.glsl SRC) +data_to_c_simple(shaders/gpu_shader_2D_edituvs_stretch_vert.glsl SRC) + data_to_c_simple(shaders/gpu_shader_edges_front_back_persp_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_edges_front_back_persp_geom.glsl SRC) data_to_c_simple(shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl SRC) diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 1a1d40b32c2..86d68ebfc58 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -352,6 +352,13 @@ typedef enum GPUBuiltinShader { GPU_SHADER_2D_WIDGET_SHADOW, GPU_SHADER_2D_NODELINK, GPU_SHADER_2D_NODELINK_INST, + /* specialized for edituv drawing */ + GPU_SHADER_2D_UV_VERTS, + GPU_SHADER_2D_UV_FACEDOTS, + GPU_SHADER_2D_UV_EDGES, + GPU_SHADER_2D_UV_EDGES_SMOOTH, + GPU_SHADER_2D_UV_FACES, + GPU_SHADER_2D_UV_FACES_STRETCH, GPU_NUM_BUILTIN_SHADERS /* (not an actual shader) */ } GPUBuiltinShader; diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index e0172579b3c..4fa0fae4c87 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -128,6 +128,7 @@ extern char datatoc_gpu_shader_point_uniform_color_frag_glsl[]; extern char datatoc_gpu_shader_point_uniform_color_aa_frag_glsl[]; extern char datatoc_gpu_shader_point_uniform_color_outline_aa_frag_glsl[]; extern char datatoc_gpu_shader_point_varying_color_outline_aa_frag_glsl[]; +extern char datatoc_gpu_shader_point_varying_color_varying_outline_aa_frag_glsl[]; extern char datatoc_gpu_shader_point_varying_color_frag_glsl[]; extern char datatoc_gpu_shader_3D_point_fixed_size_varying_color_vert_glsl[]; extern char datatoc_gpu_shader_3D_point_varying_size_vert_glsl[]; @@ -139,6 +140,12 @@ extern char datatoc_gpu_shader_2D_point_uniform_size_aa_vert_glsl[]; extern char datatoc_gpu_shader_2D_point_uniform_size_outline_aa_vert_glsl[]; extern char datatoc_gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert_glsl[]; +extern char datatoc_gpu_shader_2D_edituvs_points_vert_glsl[]; +extern char datatoc_gpu_shader_2D_edituvs_facedots_vert_glsl[]; +extern char datatoc_gpu_shader_2D_edituvs_edges_vert_glsl[]; +extern char datatoc_gpu_shader_2D_edituvs_faces_vert_glsl[]; +extern char datatoc_gpu_shader_2D_edituvs_stretch_vert_glsl[]; + extern char datatoc_gpu_shader_2D_line_dashed_uniform_color_vert_glsl[]; extern char datatoc_gpu_shader_2D_line_dashed_frag_glsl[]; extern char datatoc_gpu_shader_2D_line_dashed_geom_glsl[]; @@ -928,6 +935,25 @@ static const GPUShaderStages builtin_shader_stages[GPU_NUM_BUILTIN_SHADERS] = { { datatoc_gpu_shader_2D_nodelink_vert_glsl, datatoc_gpu_shader_2D_nodelink_frag_glsl }, + [GPU_SHADER_2D_UV_VERTS] = + { datatoc_gpu_shader_2D_edituvs_points_vert_glsl, + datatoc_gpu_shader_point_varying_color_varying_outline_aa_frag_glsl }, + [GPU_SHADER_2D_UV_FACEDOTS] = + { datatoc_gpu_shader_2D_edituvs_facedots_vert_glsl, + datatoc_gpu_shader_point_varying_color_frag_glsl }, + [GPU_SHADER_2D_UV_EDGES] = + { datatoc_gpu_shader_2D_edituvs_edges_vert_glsl, + datatoc_gpu_shader_flat_color_frag_glsl }, + [GPU_SHADER_2D_UV_EDGES_SMOOTH] = + { datatoc_gpu_shader_2D_edituvs_edges_vert_glsl, + datatoc_gpu_shader_2D_smooth_color_frag_glsl }, + [GPU_SHADER_2D_UV_FACES] = + { datatoc_gpu_shader_2D_edituvs_faces_vert_glsl, + datatoc_gpu_shader_flat_color_frag_glsl }, + [GPU_SHADER_2D_UV_FACES_STRETCH] = + { datatoc_gpu_shader_2D_edituvs_stretch_vert_glsl, + datatoc_gpu_shader_2D_smooth_color_frag_glsl }, + [GPU_SHADER_GPENCIL_STROKE] = { datatoc_gpu_shader_gpencil_stroke_vert_glsl, datatoc_gpu_shader_gpencil_stroke_frag_glsl, @@ -995,6 +1021,9 @@ static const char *gpu_shader_get_builtin_shader_defines( case GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR: return "#define USE_FLAT_NORMAL\n"; + case GPU_SHADER_2D_UV_EDGES_SMOOTH: + return "#define SMOOTH_COLOR\n"; + default: return NULL; } diff --git a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_edges_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_edges_vert.glsl new file mode 100644 index 00000000000..76e9c066103 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_edges_vert.glsl @@ -0,0 +1,29 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform vec4 edgeColor; +uniform vec4 selectColor; + +in vec2 pos; +in int flag; + +#ifdef SMOOTH_COLOR +noperspective out vec4 finalColor; +#else +flat out vec4 finalColor; +#endif + +#define VERTEX_SELECT (1 << 0) +#define EDGE_SELECT (1 << 4) + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + +#ifdef SMOOTH_COLOR + bool is_select = (flag & VERTEX_SELECT) != 0; +#else + bool is_select = (flag & EDGE_SELECT) != 0; +#endif + + finalColor = (is_select) ? selectColor : edgeColor; +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_facedots_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_facedots_vert.glsl new file mode 100644 index 00000000000..4f3f8917286 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_facedots_vert.glsl @@ -0,0 +1,17 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform vec4 vertColor; +uniform vec4 selectColor; + +in vec2 pos; +in int flag; + +out vec4 finalColor; + +#define FACE_SELECT (1 << 2) + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + finalColor = ((flag & FACE_SELECT) != 0) ? selectColor : vertColor; +}
\ No newline at end of file diff --git a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_faces_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_faces_vert.glsl new file mode 100644 index 00000000000..82c8d3f0c4a --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_faces_vert.glsl @@ -0,0 +1,24 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform vec4 faceColor; +uniform vec4 selectColor; +uniform vec4 activeColor; + +in vec2 pos; +in int flag; + +flat out vec4 finalColor; + +#define FACE_SELECT (1 << 2) +#define FACE_ACTIVE (1 << 3) + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + + bool is_selected = (flag & FACE_SELECT) != 0; + bool is_active = (flag & FACE_ACTIVE) != 0; + + finalColor = (is_selected) ? selectColor : faceColor; + finalColor = (is_active) ? activeColor : finalColor; +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_points_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_points_vert.glsl new file mode 100644 index 00000000000..d59e15a8f63 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_points_vert.glsl @@ -0,0 +1,42 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform vec4 vertColor; +uniform vec4 selectColor; +uniform vec4 pinnedColor; +uniform float pointSize; +uniform float outlineWidth; + +in vec2 pos; +in int flag; + +out vec4 fillColor; +out vec4 outlineColor; +out vec4 radii; + +#define VERTEX_SELECT (1 << 0) +#define VERTEX_PINNED (1 << 1) + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + gl_PointSize = pointSize; + + bool is_selected = (flag & VERTEX_SELECT) != 0; + bool is_pinned = (flag & VERTEX_PINNED) != 0; + + vec4 deselect_col = (is_pinned) ? pinnedColor : vertColor; + fillColor = (is_selected) ? selectColor : deselect_col; + outlineColor = (is_pinned) ? pinnedColor : vec4(fillColor.rgb, 0.0); + + // calculate concentric radii in pixels + float radius = 0.5 * pointSize; + + // start at the outside and progress toward the center + radii[0] = radius; + radii[1] = radius - 1.0; + radii[2] = radius - outlineWidth; + radii[3] = radius - outlineWidth - 1.0; + + // convert to PointCoord units + radii /= pointSize; +}
\ No newline at end of file diff --git a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl new file mode 100644 index 00000000000..4588e41573b --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl @@ -0,0 +1,49 @@ + +uniform mat4 ModelViewProjectionMatrix; + +in vec2 pos; +in float stretch; + +noperspective out vec4 finalColor; + +vec3 weight_to_rgb(float weight) +{ + vec3 r_rgb; + float blend = ((weight / 2.0) + 0.5); + + if (weight <= 0.25) { /* blue->cyan */ + r_rgb[0] = 0.0; + r_rgb[1] = blend * weight * 4.0; + r_rgb[2] = blend; + } + else if (weight <= 0.50) { /* cyan->green */ + r_rgb[0] = 0.0; + r_rgb[1] = blend; + r_rgb[2] = blend * (1.0 - ((weight - 0.25) * 4.0)); + } + else if (weight <= 0.75) { /* green->yellow */ + r_rgb[0] = blend * ((weight - 0.50) * 4.0); + r_rgb[1] = blend; + r_rgb[2] = 0.0; + } + else if (weight <= 1.0) { /* yellow->red */ + r_rgb[0] = blend; + r_rgb[1] = blend * (1.0 - ((weight - 0.75) * 4.0)); + r_rgb[2] = 0.0; + } + else { + /* exceptional value, unclamped or nan, + * avoid uninitialized memory use */ + r_rgb[0] = 1.0; + r_rgb[1] = 0.0; + r_rgb[2] = 1.0; + } + + return r_rgb; +} + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + finalColor = vec4(weight_to_rgb(stretch), 1.0); +} diff --git a/source/blender/gpu/shaders/gpu_shader_point_varying_color_varying_outline_aa_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_varying_color_varying_outline_aa_frag.glsl new file mode 100644 index 00000000000..e1f8203cb26 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_point_varying_color_varying_outline_aa_frag.glsl @@ -0,0 +1,30 @@ + +in vec4 radii; +in vec4 fillColor; +in vec4 outlineColor; +out vec4 fragColor; + +void main() { + float dist = length(gl_PointCoord - vec2(0.5)); + +// transparent outside of point +// --- 0 --- +// smooth transition +// --- 1 --- +// pure outline color +// --- 2 --- +// smooth transition +// --- 3 --- +// pure fill color +// ... +// dist = 0 at center of point + + float midStroke = 0.5 * (radii[1] + radii[2]); + + if (dist > midStroke) { + fragColor.rgb = outlineColor.rgb; + fragColor.a = mix(outlineColor.a, 0.0, smoothstep(radii[1], radii[0], dist)); + } + else + fragColor = mix(fillColor, outlineColor, smoothstep(radii[3], radii[2], dist)); +} |