diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2019-01-10 19:59:11 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2019-01-11 18:00:23 +0300 |
commit | 621a6d4a5de872a94f81d239ff627d24afecc56b (patch) | |
tree | e5b563f388f9a7f635b8255549c33b49d1ce83ff /source/blender | |
parent | 5f3fdee53a3e2716013147029e6da9e90e2c8ba8 (diff) |
UVEdit: Add back uv angle stretch aspect correction
This is now done in shader so that the batches are shared across ImageUV
areas.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 25 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_draw.c | 9 | ||||
-rw-r--r-- | source/blender/gpu/GPU_shader.h | 3 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_shader.c | 8 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl | 30 |
5 files changed, 62 insertions, 13 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 524e802e80d..0bac64df567 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -4771,7 +4771,7 @@ BLI_INLINE float edit_uv_get_stretch_area(float area, float uvarea) /* Compute face's normalized contour vectors. */ BLI_INLINE void edit_uv_preprocess_stretch_angle( - float (*auv)[2], float (*av)[3], const int cd_loop_uv_offset, BMFace *efa, float asp[2]) + float (*auv)[2], float (*av)[3], const int cd_loop_uv_offset, BMFace *efa) { BMLoop *l; BMIter liter; @@ -4781,7 +4781,6 @@ BLI_INLINE void edit_uv_preprocess_stretch_angle( MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset); sub_v2_v2v2(auv[i], luv_prev->uv, luv->uv); - mul_v2_v2(auv[i], asp); normalize_v2(auv[i]); sub_v3_v3v3(av[i], l->prev->v->co, l->v->co); @@ -4789,6 +4788,7 @@ BLI_INLINE void edit_uv_preprocess_stretch_angle( } } +#if 0 /* here for reference, this is done in shader now. */ BLI_INLINE float edit_uv_get_loop_stretch_angle( const float auv0[2], const float auv1[2], const float av0[3], const float av1[3]) { @@ -4797,6 +4797,7 @@ BLI_INLINE float edit_uv_get_loop_stretch_angle( float stretch = fabsf(uvang - ang) / (float)M_PI; return 1.0f - pow2f(1.0f - stretch); } +#endif #define VERTEX_SELECT (1 << 0) #define VERTEX_PINNED (1 << 1) @@ -4823,7 +4824,7 @@ BLI_INLINE uchar edit_uv_get_loop_flag(BMLoop *l, const int cd_loop_uv_offset, S } static struct EditUVFormatIndex { - uint uvs, area, angle, flag, fdots_uvs, fdots_flag; + uint uvs, area, angle, uv_adj, flag, fdots_uvs, fdots_flag; } uv_attr_id = {0}; static void uvedit_fill_buffer_data( @@ -4885,10 +4886,7 @@ static void uvedit_fill_buffer_data( if (vbo_angle) { av = (float (*)[3])BLI_buffer_reinit_data(&vec3_buf, vec3f, efa_len); auv = (float (*)[2])BLI_buffer_reinit_data(&vec2_buf, vec2f, efa_len); - /* TODO modify shader to apply the correct aspect on the fly, or get the correct aspect. - * But later solution would make it correct only in one editor at a time. */ - float asp[2] = {1.0f, 1.0f}; - edit_uv_preprocess_stretch_angle(auv, av, cd_loop_uv_offset, efa, asp); + edit_uv_preprocess_stretch_angle(auv, av, cd_loop_uv_offset, efa); } BM_ITER_ELEM_INDEX(l, &liter, efa, BM_LOOPS_OF_FACE, i) { @@ -4897,8 +4895,14 @@ static void uvedit_fill_buffer_data( GPU_vertbuf_attr_set(vbo_area, uv_attr_id.area, vidx, &area_stretch); } if (vbo_angle) { - ushort angle = 65534.0f * edit_uv_get_loop_stretch_angle(auv[i], auv[(i + 1) % efa_len], - av[i], av[(i + 1) % efa_len]); + int i_next = (i + 1) % efa_len; + short suv[4]; + /* Send uvs to the shader and let it compute the aspect corrected angle. */ + normal_float_to_short_v2(&suv[0], auv[i]); + normal_float_to_short_v2(&suv[2], auv[i_next]); + GPU_vertbuf_attr_set(vbo_angle, uv_attr_id.uv_adj, vidx, suv); + /* Compute 3D angle here */ + short angle = 32767.0f * angle_normalized_v3v3(av[i], av[i_next]) / (float)M_PI; GPU_vertbuf_attr_set(vbo_angle, uv_attr_id.angle, vidx, &angle); } if (vbo_pos) { @@ -4978,7 +4982,8 @@ static void mesh_create_uvedit_buffers( if (format_pos.attr_len == 0) { uv_attr_id.area = GPU_vertformat_attr_add(&format_area, "stretch", GPU_COMP_U16, 1, GPU_FETCH_INT_TO_FLOAT_UNIT); - uv_attr_id.angle = GPU_vertformat_attr_add(&format_angle, "stretch", GPU_COMP_U16, 1, GPU_FETCH_INT_TO_FLOAT_UNIT); + uv_attr_id.angle = GPU_vertformat_attr_add(&format_angle, "angle", GPU_COMP_I16, 1, GPU_FETCH_INT_TO_FLOAT_UNIT); + uv_attr_id.uv_adj = GPU_vertformat_attr_add(&format_angle, "uv_adj", GPU_COMP_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); uv_attr_id.flag = GPU_vertformat_attr_add(&format_flag, "flag", GPU_COMP_U8, 1, GPU_FETCH_INT); uv_attr_id.uvs = GPU_vertformat_attr_add(&format_pos, "u", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); GPU_vertformat_alias_add(&format_pos, "pos"); diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 30bc6301487..46c62c4a086 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -305,7 +305,9 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph * if (faces) { GPU_batch_program_set_builtin(faces, (draw_stretch) - ? GPU_SHADER_2D_UV_FACES_STRETCH + ? (sima->dt_uvstretch == SI_UVDT_STRETCH_AREA) + ? GPU_SHADER_2D_UV_FACES_STRETCH_AREA + : GPU_SHADER_2D_UV_FACES_STRETCH_ANGLE : GPU_SHADER_2D_UV_FACES); if (!draw_stretch) { @@ -319,6 +321,11 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph * GPU_batch_uniform_4fv(faces, "selectColor", col2); GPU_batch_uniform_4fv(faces, "activeColor", col3); } + else if (sima->dt_uvstretch == SI_UVDT_STRETCH_ANGLE) { + float asp[2]; + ED_space_image_get_uv_aspect(sima, &asp[0], &asp[1]); + GPU_batch_uniform_2fv(faces, "aspect", asp); + } GPU_batch_draw(faces); diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index ea7983f8a2e..71536523caf 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -349,7 +349,8 @@ typedef enum GPUBuiltinShader { GPU_SHADER_2D_UV_EDGES, GPU_SHADER_2D_UV_EDGES_SMOOTH, GPU_SHADER_2D_UV_FACES, - GPU_SHADER_2D_UV_FACES_STRETCH, + GPU_SHADER_2D_UV_FACES_STRETCH_AREA, + GPU_SHADER_2D_UV_FACES_STRETCH_ANGLE, /* Selection */ GPU_SHADER_3D_FLAT_SELECT_ID, GPU_SHADER_3D_UNIFORM_SELECT_ID, diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 88d4f1e5c52..8a3581c54df 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -933,7 +933,10 @@ static const GPUShaderStages builtin_shader_stages[GPU_NUM_BUILTIN_SHADERS] = { [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] = + [GPU_SHADER_2D_UV_FACES_STRETCH_AREA] = + { datatoc_gpu_shader_2D_edituvs_stretch_vert_glsl, + datatoc_gpu_shader_2D_smooth_color_frag_glsl }, + [GPU_SHADER_2D_UV_FACES_STRETCH_ANGLE] = { datatoc_gpu_shader_2D_edituvs_stretch_vert_glsl, datatoc_gpu_shader_2D_smooth_color_frag_glsl }, @@ -1010,6 +1013,9 @@ static const char *gpu_shader_get_builtin_shader_defines( case GPU_SHADER_3D_UNIFORM_SELECT_ID: return "#define UNIFORM_ID\n"; + case GPU_SHADER_2D_UV_FACES_STRETCH_ANGLE: + return "#define STRETCH_ANGLE\n"; + default: return NULL; } 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 index 4588e41573b..c575e06ed3b 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl @@ -1,8 +1,16 @@ uniform mat4 ModelViewProjectionMatrix; +uniform vec2 aspect; in vec2 pos; + +#ifndef STRETCH_ANGLE in float stretch; +#else + +in vec4 uv_adj; +in float angle; +#endif noperspective out vec4 finalColor; @@ -42,8 +50,30 @@ vec3 weight_to_rgb(float weight) return r_rgb; } +#define M_PI 3.1415926535897932 + +/* Adapted from BLI_math_vector.h */ +float angle_normalized_v2v2(vec2 v1, vec2 v2) +{ + v1 = normalize(v1 * aspect); + v2 = normalize(v2 * aspect); + /* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */ + bool q = (dot(v1, v2) >= 0.0); + vec2 v = (q) ? (v1 - v2) : (v1 + v2); + float a = 2.0 * asin(length(v) / 2.0); + return (q) ? a : M_PI - a; +} + void main() { gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + +#ifdef STRETCH_ANGLE + float uv_angle = angle_normalized_v2v2(uv_adj.xy, uv_adj.zw) / M_PI; + float stretch = 1.0 - abs(uv_angle - angle); + stretch = stretch; + stretch = 1.0 - stretch * stretch; +#endif + finalColor = vec4(weight_to_rgb(stretch), 1.0); } |