diff options
author | Ray Molenkamp <github@lazydodo.com> | 2018-06-17 06:49:40 +0300 |
---|---|---|
committer | Ray Molenkamp <github@lazydodo.com> | 2018-06-17 06:49:40 +0300 |
commit | 75188552a113f4dc226f21076f883ac3c11c9a98 (patch) | |
tree | cc2f4bbde45164d6af64e2389eb95a19571fe090 | |
parent | 0a08c5cd36d32e72110e9452e0278527ef42bc70 (diff) | |
parent | fe98124a9821c2b5fdf5a81ac69f80ff2fa8e8bb (diff) |
Merge branch 'blender2.8' of git.blender.org:blender into blender2.8
-rw-r--r-- | source/blender/blenkernel/intern/studiolight.c | 123 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 7 |
2 files changed, 68 insertions, 62 deletions
diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index e73cd3c37a4..1735388d954 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -173,7 +173,7 @@ static void studiolight_calculate_radiance_buffer( } } -static void studiolight_load_equierectangular_image(StudioLight *sl) +static void studiolight_load_equirectangular_image(StudioLight *sl) { if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) { ImBuf *ibuf = NULL; @@ -186,7 +186,7 @@ static void studiolight_load_equierectangular_image(StudioLight *sl) sl->flag |= STUDIOLIGHT_EXTERNAL_IMAGE_LOADED; } -static void studiolight_create_equierectangular_radiance_gputexture(StudioLight *sl) +static void studiolight_create_equirectangular_radiance_gputexture(StudioLight *sl) { if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) { char error[256]; @@ -219,7 +219,7 @@ static void studiolight_create_equierectangular_radiance_gputexture(StudioLight sl->flag |= STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE; } -static void studiolight_create_equierectangular_irradiance_gputexture(StudioLight *sl) +static void studiolight_create_equirectangular_irradiance_gputexture(StudioLight *sl) { if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) { char error[256]; @@ -593,53 +593,62 @@ static int studiolight_cmp(const void *a, const void *b) } /* icons */ + +/* Takes normalized uvs as parameter (range from 0 to 1). + * inner_edge and outer_edge are distances (from the center) + * in uv space for the alpha mask falloff. */ +static uint alpha_circle_mask(float u, float v, float inner_edge, float outer_edge) +{ + /* Coords from center. */ + float co[2] = {u - 0.5f, v - 0.5f}; + float dist = len_v2(co); + float alpha = 1.0f + (inner_edge - dist) / (outer_edge - inner_edge); + uint mask = (uint)floorf(255.0f * min_ff(max_ff(alpha, 0.0f), 1.0f)); + return mask << 24; +} + +#define STUDIOLIGHT_DIAMETER 0.95f + static uint *studiolight_radiance_preview(StudioLight *sl, int icon_size) { BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EXTERNAL_IMAGE_LOADED); uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__); - int icon_center = icon_size / 2; - float sphere_radius = icon_center * 0.9; + float pixel_size = 1.0f / (float)icon_size; int offset = 0; for (int y = 0; y < icon_size; y++) { - float dy = y - icon_center; + float dy = (y + 0.5f) / (float)icon_size; + dy = dy / STUDIOLIGHT_DIAMETER - (1.0f - STUDIOLIGHT_DIAMETER) / 2.0f; for (int x = 0; x < icon_size; x++) { - float dx = x - icon_center; - /* calculate aliasing */ - float alias = 0; - const float alias_step = 0.333; - for (float ay = dy - 0.5; ay < dy + 0.5; ay += alias_step) { - for (float ax = dx - 0.5; ax < dx + 0.5; ax += alias_step) { - if (sqrt(ay * ay + ax * ax) < sphere_radius) { - alias += alias_step * alias_step; - } - } - } + float dx = (x + 0.5f) / (float)icon_size; + dx = dx / STUDIOLIGHT_DIAMETER - (1.0f - STUDIOLIGHT_DIAMETER) / 2.0f; + uint pixelresult = 0x0; - uint alias_i = clamp_i(alias * 256, 0, 255); - if (alias_i != 0) { - /* calculate normal */ - uint alias_mask = alias_i << 24; - float incoming[3]; - copy_v3_fl3(incoming, 0.0, 1.0, 0.0); + uint alphamask = alpha_circle_mask(dx, dy, 0.5f - pixel_size, 0.5f); + if (alphamask != 0) { + float incoming[3] = {0.0f, 0.0f, -1.0f}; float normal[3]; - normal[0] = dx / sphere_radius; - normal[2] = dy / sphere_radius; - normal[1] = -sqrt(-(normal[0] * normal[0]) - (normal[2] * normal[2]) + 1); - normalize_v3(normal); + normal[0] = dx * 2.0f - 1.0f; + normal[1] = dy * 2.0f - 1.0f; + float dist = len_v2(normal); + normal[2] = sqrtf(1.0f - dist*dist); float direction[3]; reflect_v3_v3v3(direction, incoming, normal); + /* We want to see horizon not poles. */ + SWAP(float, direction[1], direction[2]); + direction[1] = -direction[1]; + float color[4]; studiolight_calculate_radiance(sl->equirectangular_radiance_buffer, color, direction); pixelresult = rgb_to_cpack( linearrgb_to_srgb(color[0]), linearrgb_to_srgb(color[1]), - linearrgb_to_srgb(color[2])) | alias_mask; + linearrgb_to_srgb(color[2])) | alphamask; } rect[offset++] = pixelresult; } @@ -652,22 +661,25 @@ static uint *studiolight_matcap_preview(StudioLight *sl, int icon_size, bool fli BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EXTERNAL_IMAGE_LOADED); uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__); - const uint alphamask = 0xff000000; float color[4]; float fx, fy; + float pixel_size = 1.0f / (float)icon_size; int offset = 0; ImBuf *ibuf = sl->equirectangular_radiance_buffer; for (int y = 0; y < icon_size; y++) { - fy = y * ibuf->y / icon_size; + fy = (y + 0.5f) / (float)icon_size; + fy = fy / STUDIOLIGHT_DIAMETER - (1.0f - STUDIOLIGHT_DIAMETER) / 2.0f; for (int x = 0; x < icon_size; x++) { + fx = (x + 0.5f) / (float)icon_size; + fx = fx / STUDIOLIGHT_DIAMETER - (1.0f - STUDIOLIGHT_DIAMETER) / 2.0f; if (flipped) { - fx = ibuf->x - (x * ibuf->x / icon_size) - 1; - } - else { - fx = x * ibuf->x / icon_size; + fx = 1.0f - fx; } - nearest_interpolation_color(ibuf, NULL, color, fx, fy); + nearest_interpolation_color(ibuf, NULL, color, fx * ibuf->x, fy * ibuf->y); + + uint alphamask = alpha_circle_mask(fx, fy, 0.5f - pixel_size, 0.5f); + rect[offset++] = rgb_to_cpack( linearrgb_to_srgb(color[0]), linearrgb_to_srgb(color[1]), @@ -687,34 +699,25 @@ static uint *studiolight_irradiance_preview(StudioLight *sl, int icon_size) BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED); uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__); - int icon_center = icon_size / 2; - float sphere_radius = icon_center * 0.9; + float pixel_size = 1.0f / (float)icon_size; int offset = 0; for (int y = 0; y < icon_size; y++) { - float dy = y - icon_center; + float dy = (y + 0.5f) / (float)icon_size; + dy = dy / STUDIOLIGHT_DIAMETER - (1.0f - STUDIOLIGHT_DIAMETER) / 2.0f; for (int x = 0; x < icon_size; x++) { - float dx = x - icon_center; - /* calculate aliasing */ - float alias = 0; - const float alias_step = 0.333; - for (float ay = dy - 0.5; ay < dy + 0.5; ay += alias_step) { - for (float ax = dx - 0.5; ax < dx + 0.5; ax += alias_step) { - if (sqrt(ay * ay + ax * ax) < sphere_radius) { - alias += alias_step * alias_step; - } - } - } + float dx = (x + 0.5f) / (float)icon_size; + dx = dx / STUDIOLIGHT_DIAMETER - (1.0f - STUDIOLIGHT_DIAMETER) / 2.0f; + uint pixelresult = 0x0; - uint alias_i = clamp_i(alias * 256, 0, 255); - if (alias_i != 0) { + uint alphamask = alpha_circle_mask(dx, dy, 0.5f - pixel_size, 0.5f); + if (alphamask != 0) { /* calculate normal */ - uint alias_mask = alias_i << 24; float normal[3]; - normal[0] = dx / sphere_radius; - normal[1] = dy / sphere_radius; - normal[2] = sqrt(-(normal[0] * normal[0]) - (normal[1] * normal[1]) + 1); - normalize_v3(normal); + normal[0] = dx * 2.0f - 1.0f; + normal[1] = dy * 2.0f - 1.0f; + float dist = len_v2(normal); + normal[2] = sqrtf(1.0f - dist*dist); float color[3]; mul_v3_v3fl(color, sl->diffuse_light[STUDIOLIGHT_X_POS], clamp_f(normal[0], 0.0, 1.0)); @@ -726,7 +729,7 @@ static uint *studiolight_irradiance_preview(StudioLight *sl, int icon_size) pixelresult = rgb_to_cpack( linearrgb_to_srgb(color[0]), linearrgb_to_srgb(color[1]), - linearrgb_to_srgb(color[2])) | alias_mask; + linearrgb_to_srgb(color[2])) | alphamask; } rect[offset++] = pixelresult; } @@ -891,7 +894,7 @@ void BKE_studiolight_ensure_flag(StudioLight *sl, int flag) } if ((flag & STUDIOLIGHT_EXTERNAL_IMAGE_LOADED)) { - studiolight_load_equierectangular_image(sl); + studiolight_load_equirectangular_image(sl); } if ((flag & STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED)) { studiolight_calculate_radiance_cubemap_buffers(sl); @@ -900,13 +903,13 @@ void BKE_studiolight_ensure_flag(StudioLight *sl, int flag) studiolight_calculate_diffuse_light(sl); } if ((flag & STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE)) { - studiolight_create_equierectangular_radiance_gputexture(sl); + studiolight_create_equirectangular_radiance_gputexture(sl); } if ((flag & STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED)) { studiolight_calculate_light_direction(sl); } if ((flag & STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_GPUTEXTURE)) { - studiolight_create_equierectangular_irradiance_gputexture(sl); + studiolight_create_equirectangular_irradiance_gputexture(sl); } if ((flag & STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_IMAGE_CALCULATED)) { if (!studiolight_load_irradiance_equirectangular_image(sl)) { diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index f6fc58557f2..146e990500c 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -874,7 +874,8 @@ static void OBJECT_cache_init(void *vedata) DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); OBJECT_PrivateData *g_data; const DRWContextState *draw_ctx = DRW_context_state_get(); - const bool xray_enabled = ((draw_ctx->v3d->shading.flag & V3D_SHADING_XRAY) != 0); + const bool xray_enabled = ((draw_ctx->v3d->shading.flag & V3D_SHADING_XRAY) != 0) && + (draw_ctx->v3d->drawtype < OB_MATERIAL); /* TODO : use dpi setting for enabling the second pass */ const bool do_outline_expand = false; @@ -2110,7 +2111,9 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) if (do_outlines) { if ((ob != draw_ctx->object_edit) && !((ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT))) { struct Gwn_Batch *geom; - if (v3d->shading.flag & V3D_SHADING_XRAY) { + const bool xray_enabled = ((v3d->shading.flag & V3D_SHADING_XRAY) != 0) && + (v3d->drawtype < OB_MATERIAL); + if (xray_enabled) { geom = DRW_cache_object_edge_detection_get(ob, NULL); } else { |