2018-05-22 14:12:47 +02:00
|
|
|
#include "workbench_private.h"
|
|
|
|
|
|
2018-05-31 13:32:53 +02:00
|
|
|
#include "DNA_userdef_types.h"
|
|
|
|
|
|
2018-05-22 14:12:47 +02:00
|
|
|
#include "UI_resources.h"
|
|
|
|
|
|
2018-05-31 13:32:53 +02:00
|
|
|
|
2018-06-25 09:06:39 +02:00
|
|
|
void workbench_effect_info_init(WORKBENCH_EffectInfo *effect_info)
|
|
|
|
|
{
|
|
|
|
|
effect_info->jitter_index = 0;
|
|
|
|
|
effect_info->view_updated = true;
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-22 14:12:47 +02:00
|
|
|
void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
|
|
|
|
|
{
|
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
2018-05-31 13:32:53 +02:00
|
|
|
const Scene *scene = draw_ctx->scene;
|
2018-05-22 14:12:47 +02:00
|
|
|
wpd->material_hash = BLI_ghash_ptr_new(__func__);
|
2018-06-18 08:51:29 +02:00
|
|
|
wpd->user_preferences = &U;
|
2018-05-22 14:12:47 +02:00
|
|
|
|
|
|
|
|
View3D *v3d = draw_ctx->v3d;
|
2018-07-11 11:43:56 +02:00
|
|
|
if (!v3d) {
|
|
|
|
|
wpd->shading = scene->display.shading;
|
2018-07-30 15:44:25 +02:00
|
|
|
wpd->use_color_view_settings = true;
|
2018-07-11 11:43:56 +02:00
|
|
|
}
|
|
|
|
|
else if (v3d->shading.type == OB_RENDER &&
|
|
|
|
|
BKE_scene_uses_blender_opengl(scene))
|
|
|
|
|
{
|
|
|
|
|
wpd->shading = scene->display.shading;
|
2018-07-30 15:44:25 +02:00
|
|
|
wpd->use_color_view_settings = true;
|
2018-07-11 11:43:56 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2018-05-22 14:12:47 +02:00
|
|
|
wpd->shading = v3d->shading;
|
2018-07-30 15:44:25 +02:00
|
|
|
wpd->use_color_view_settings = false;
|
2018-07-11 11:43:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (wpd->shading.light == V3D_LIGHTING_MATCAP) {
|
|
|
|
|
wpd->studio_light = BKE_studiolight_find(
|
2018-07-19 16:06:37 +10:00
|
|
|
wpd->shading.matcap, STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
|
2018-05-22 14:12:47 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2018-07-11 11:43:56 +02:00
|
|
|
wpd->studio_light = BKE_studiolight_find(
|
2018-07-19 16:06:37 +10:00
|
|
|
wpd->shading.studio_light, STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD);
|
2018-05-22 14:12:47 +02:00
|
|
|
}
|
2018-07-31 16:44:35 +10:00
|
|
|
|
|
|
|
|
/* If matcaps are missing, use this as fallback. */
|
|
|
|
|
if (UNLIKELY(wpd->studio_light == NULL)) {
|
|
|
|
|
wpd->studio_light = BKE_studiolight_find(
|
|
|
|
|
wpd->shading.studio_light, STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD);
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-22 14:12:47 +02:00
|
|
|
wpd->shadow_multiplier = 1.0 - wpd->shading.shadow_intensity;
|
|
|
|
|
|
|
|
|
|
WORKBENCH_UBO_World *wd = &wpd->world_data;
|
2018-07-05 22:56:18 +02:00
|
|
|
wd->matcap_orientation = (wpd->shading.flag & V3D_SHADING_MATCAP_FLIP_X) != 0;
|
2018-07-11 11:43:56 +02:00
|
|
|
wd->background_alpha = (v3d || scene->r.alphamode == R_ADDSKY) ? 1.0f : 0.0f;
|
2018-06-01 08:15:50 +02:00
|
|
|
|
2018-07-27 15:05:46 +02:00
|
|
|
if (!v3d || ((v3d->shading.background_type & V3D_SHADING_BACKGROUND_WORLD) &&
|
|
|
|
|
(scene->world != NULL)))
|
|
|
|
|
{
|
2018-06-01 08:15:50 +02:00
|
|
|
copy_v3_v3(wd->background_color_low, &scene->world->horr);
|
|
|
|
|
copy_v3_v3(wd->background_color_high, &scene->world->horr);
|
|
|
|
|
}
|
2018-07-27 15:05:46 +02:00
|
|
|
else if (v3d->shading.background_type & V3D_SHADING_BACKGROUND_VIEWPORT) {
|
|
|
|
|
copy_v3_v3(wd->background_color_low, v3d->shading.background_color);
|
|
|
|
|
copy_v3_v3(wd->background_color_high, v3d->shading.background_color);
|
|
|
|
|
}
|
2018-07-11 11:43:56 +02:00
|
|
|
else if (v3d) {
|
2018-06-01 08:15:50 +02:00
|
|
|
UI_GetThemeColor3fv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_LOW_GRAD : TH_HIGH_GRAD, wd->background_color_low);
|
|
|
|
|
UI_GetThemeColor3fv(TH_HIGH_GRAD, wd->background_color_high);
|
2018-05-22 14:12:47 +02:00
|
|
|
|
2018-06-01 17:13:28 +02:00
|
|
|
/* XXX: Really quick conversion to avoid washed out background.
|
|
|
|
|
* Needs to be adressed properly (color managed using ocio). */
|
|
|
|
|
srgb_to_linearrgb_v3_v3(wd->background_color_high, wd->background_color_high);
|
|
|
|
|
srgb_to_linearrgb_v3_v3(wd->background_color_low, wd->background_color_low);
|
|
|
|
|
}
|
2018-07-11 11:43:56 +02:00
|
|
|
else {
|
|
|
|
|
zero_v3(wd->background_color_low);
|
|
|
|
|
zero_v3(wd->background_color_high);
|
|
|
|
|
}
|
2018-05-22 14:12:47 +02:00
|
|
|
|
|
|
|
|
studiolight_update_world(wpd->studio_light, wd);
|
|
|
|
|
|
|
|
|
|
copy_v3_v3(wd->object_outline_color, wpd->shading.object_outline_color);
|
|
|
|
|
wd->object_outline_color[3] = 1.0f;
|
|
|
|
|
|
|
|
|
|
wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), &wpd->world_data);
|
2018-06-06 14:47:54 +02:00
|
|
|
|
|
|
|
|
/* Cavity settings */
|
|
|
|
|
{
|
|
|
|
|
const int ssao_samples = scene->display.matcap_ssao_samples;
|
|
|
|
|
|
|
|
|
|
float invproj[4][4];
|
|
|
|
|
const bool is_persp = DRW_viewport_is_persp_get();
|
|
|
|
|
/* view vectors for the corners of the view frustum.
|
|
|
|
|
* Can be used to recreate the world space position easily */
|
|
|
|
|
float viewvecs[3][4] = {
|
|
|
|
|
{-1.0f, -1.0f, -1.0f, 1.0f},
|
|
|
|
|
{1.0f, -1.0f, -1.0f, 1.0f},
|
|
|
|
|
{-1.0f, 1.0f, -1.0f, 1.0f}
|
|
|
|
|
};
|
|
|
|
|
int i;
|
|
|
|
|
const float *size = DRW_viewport_size_get();
|
|
|
|
|
|
|
|
|
|
wpd->ssao_params[0] = ssao_samples;
|
|
|
|
|
wpd->ssao_params[1] = size[0] / 64.0;
|
|
|
|
|
wpd->ssao_params[2] = size[1] / 64.0;
|
2018-06-27 12:55:49 +02:00
|
|
|
wpd->ssao_params[3] = 0;
|
2018-06-06 14:47:54 +02:00
|
|
|
|
|
|
|
|
/* distance, factor, factor, attenuation */
|
|
|
|
|
copy_v4_fl4(wpd->ssao_settings, scene->display.matcap_ssao_distance, wpd->shading.cavity_valley_factor, wpd->shading.cavity_ridge_factor, scene->display.matcap_ssao_attenuation);
|
|
|
|
|
|
|
|
|
|
/* invert the view matrix */
|
|
|
|
|
DRW_viewport_matrix_get(wpd->winmat, DRW_MAT_WIN);
|
|
|
|
|
invert_m4_m4(invproj, wpd->winmat);
|
|
|
|
|
|
|
|
|
|
/* convert the view vectors to view space */
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
|
mul_m4_v4(invproj, viewvecs[i]);
|
|
|
|
|
/* normalized trick see:
|
|
|
|
|
* http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
|
|
|
|
|
mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]);
|
|
|
|
|
if (is_persp)
|
|
|
|
|
mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
|
|
|
|
|
viewvecs[i][3] = 1.0;
|
|
|
|
|
|
|
|
|
|
copy_v4_v4(wpd->viewvecs[i], viewvecs[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* we need to store the differences */
|
|
|
|
|
wpd->viewvecs[1][0] -= wpd->viewvecs[0][0];
|
|
|
|
|
wpd->viewvecs[1][1] = wpd->viewvecs[2][1] - wpd->viewvecs[0][1];
|
|
|
|
|
|
|
|
|
|
/* calculate a depth offset as well */
|
|
|
|
|
if (!is_persp) {
|
|
|
|
|
float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
|
|
|
|
|
mul_m4_v4(invproj, vec_far);
|
|
|
|
|
mul_v3_fl(vec_far, 1.0f / vec_far[3]);
|
|
|
|
|
wpd->viewvecs[1][2] = vec_far[2] - wpd->viewvecs[0][2];
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-07-16 15:01:44 +02:00
|
|
|
|
|
|
|
|
wpd->volumes_do = false;
|
|
|
|
|
BLI_listbase_clear(&wpd->smoke_domains);
|
2018-05-22 14:12:47 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-03 12:29:48 +02:00
|
|
|
void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float r_light_direction[3])
|
2018-05-30 14:40:57 +02:00
|
|
|
{
|
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
|
Scene *scene = draw_ctx->scene;
|
2018-05-31 13:32:53 +02:00
|
|
|
WORKBENCH_UBO_World *wd = &wpd->world_data;
|
|
|
|
|
float view_matrix[4][4];
|
|
|
|
|
DRW_viewport_matrix_get(view_matrix, DRW_MAT_VIEW);
|
|
|
|
|
|
2018-07-03 12:29:48 +02:00
|
|
|
copy_v3_v3(r_light_direction, scene->display.light_direction);
|
|
|
|
|
negate_v3(r_light_direction);
|
|
|
|
|
|
2018-06-01 11:48:53 +02:00
|
|
|
{
|
|
|
|
|
WORKBENCH_UBO_Light *light = &wd->lights[0];
|
2018-07-03 12:29:48 +02:00
|
|
|
mul_v3_mat3_m4v3(light->light_direction_vs, view_matrix, r_light_direction);
|
2018-06-01 11:48:53 +02:00
|
|
|
light->light_direction_vs[3] = 0.0f;
|
|
|
|
|
copy_v3_fl(light->specular_color, 1.0f);
|
|
|
|
|
light->energy = 1.0f;
|
2018-07-03 12:29:48 +02:00
|
|
|
copy_v4_v4(wd->shadow_direction_vs, light->light_direction_vs);
|
2018-06-01 11:48:53 +02:00
|
|
|
wd->num_lights = 1;
|
|
|
|
|
}
|
2018-05-31 13:32:53 +02:00
|
|
|
|
2018-06-05 08:15:30 +02:00
|
|
|
if (!STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
|
2018-05-31 13:32:53 +02:00
|
|
|
int light_index = 0;
|
2018-06-01 18:10:43 +02:00
|
|
|
for (int index = 0 ; index < 3; index++) {
|
2018-05-31 13:32:53 +02:00
|
|
|
SolidLight *sl = &U.light[index];
|
|
|
|
|
if (sl->flag) {
|
2018-06-01 12:04:24 +02:00
|
|
|
WORKBENCH_UBO_Light *light = &wd->lights[light_index++];
|
2018-05-31 13:32:53 +02:00
|
|
|
copy_v4_v4(light->light_direction_vs, sl->vec);
|
|
|
|
|
negate_v3(light->light_direction_vs);
|
|
|
|
|
copy_v4_v4(light->specular_color, sl->spec);
|
|
|
|
|
light->energy = 1.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
wd->num_lights = light_index;
|
|
|
|
|
}
|
2018-05-30 14:40:57 +02:00
|
|
|
|
2018-06-20 12:26:06 +02:00
|
|
|
DRW_uniformbuffer_update(wpd->world_ubo, wd);
|
2018-05-30 14:40:57 +02:00
|
|
|
}
|
|
|
|
|
|
2018-05-22 14:12:47 +02:00
|
|
|
void workbench_private_data_free(WORKBENCH_PrivateData *wpd)
|
|
|
|
|
{
|
2018-06-29 08:25:23 +02:00
|
|
|
BLI_ghash_free(wpd->material_hash, NULL, MEM_freeN);
|
2018-05-22 14:12:47 +02:00
|
|
|
DRW_UBO_FREE_SAFE(wpd->world_ubo);
|
|
|
|
|
}
|