2018-04-18 13:44:33 +02:00
|
|
|
|
2018-04-19 07:47:03 +02:00
|
|
|
|
2018-04-18 13:44:33 +02:00
|
|
|
#include "workbench_private.h"
|
2018-04-25 10:59:48 +02:00
|
|
|
|
2018-05-04 14:07:00 +02:00
|
|
|
#include "BLI_dynstr.h"
|
|
|
|
|
|
2018-05-22 14:12:47 +02:00
|
|
|
#define HSV_SATURATION 0.5
|
|
|
|
|
#define HSV_VALUE 0.9
|
2018-04-19 07:47:03 +02:00
|
|
|
|
2018-05-31 13:32:53 +02:00
|
|
|
void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, WORKBENCH_MaterialData *data)
|
2018-05-22 14:12:47 +02:00
|
|
|
{
|
|
|
|
|
/* When in OB_TEXTURE always uyse V3D_SHADING_MATERIAL_COLOR as fallback when no texture could be determined */
|
|
|
|
|
int color_type = wpd->drawtype == OB_SOLID ? wpd->shading.color_type : V3D_SHADING_MATERIAL_COLOR;
|
2018-05-31 13:32:53 +02:00
|
|
|
static float default_diffuse_color[] = {0.8f, 0.8f, 0.8f, 1.0f};
|
2018-06-08 15:07:05 +02:00
|
|
|
static float default_specular_color[] = {0.5f, 0.5f, 0.5f, 0.5f};
|
2018-05-31 13:32:53 +02:00
|
|
|
copy_v4_v4(data->material_data.diffuse_color, default_diffuse_color);
|
|
|
|
|
copy_v4_v4(data->material_data.specular_color, default_specular_color);
|
2018-06-08 15:07:05 +02:00
|
|
|
data->material_data.roughness = 0.5f;
|
2018-05-31 13:32:53 +02:00
|
|
|
|
2018-05-22 14:12:47 +02:00
|
|
|
if (DRW_object_is_paint_mode(ob) || color_type == V3D_SHADING_SINGLE_COLOR) {
|
2018-05-31 13:32:53 +02:00
|
|
|
copy_v3_v3(data->material_data.diffuse_color, wpd->shading.single_color);
|
2018-05-22 14:12:47 +02:00
|
|
|
}
|
|
|
|
|
else if (color_type == V3D_SHADING_RANDOM_COLOR) {
|
|
|
|
|
uint hash = BLI_ghashutil_strhash_p_murmur(ob->id.name);
|
|
|
|
|
if (ob->id.lib) {
|
|
|
|
|
hash = (hash * 13) ^ BLI_ghashutil_strhash_p_murmur(ob->id.lib->name);
|
|
|
|
|
}
|
|
|
|
|
float offset = fmodf((hash / 100000.0) * M_GOLDEN_RATION_CONJUGATE, 1.0);
|
2018-05-15 15:19:57 +02:00
|
|
|
|
2018-05-22 14:12:47 +02:00
|
|
|
float hsv[3] = {offset, HSV_SATURATION, HSV_VALUE};
|
2018-05-31 13:32:53 +02:00
|
|
|
hsv_to_rgb_v(hsv, data->material_data.diffuse_color);
|
2018-05-22 14:12:47 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* V3D_SHADING_MATERIAL_COLOR */
|
|
|
|
|
if (mat) {
|
2018-05-31 13:32:53 +02:00
|
|
|
copy_v3_v3(data->material_data.diffuse_color, &mat->r);
|
|
|
|
|
copy_v3_v3(data->material_data.specular_color, &mat->specr);
|
|
|
|
|
data->material_data.roughness = mat->roughness;
|
2018-05-22 14:12:47 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-05-15 15:19:57 +02:00
|
|
|
|
2018-06-03 12:13:19 +02:00
|
|
|
char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype, bool is_hair)
|
2018-04-19 07:47:03 +02:00
|
|
|
{
|
2018-04-25 10:59:48 +02:00
|
|
|
char *str = NULL;
|
2018-04-19 07:47:03 +02:00
|
|
|
|
2018-04-25 10:59:48 +02:00
|
|
|
DynStr *ds = BLI_dynstr_new();
|
|
|
|
|
|
2018-05-15 17:03:59 +02:00
|
|
|
if (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define V3D_SHADING_OBJECT_OUTLINE\n");
|
2018-04-25 10:59:48 +02:00
|
|
|
}
|
2018-05-15 15:19:57 +02:00
|
|
|
if (wpd->shading.flag & V3D_SHADING_SHADOW) {
|
2018-05-17 15:23:21 +02:00
|
|
|
BLI_dynstr_appendf(ds, "#define V3D_SHADING_SHADOW\n");
|
2018-05-15 15:19:57 +02:00
|
|
|
}
|
2018-06-06 14:47:54 +02:00
|
|
|
if (CAVITY_ENABLED(wpd)) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define V3D_SHADING_CAVITY\n");
|
|
|
|
|
}
|
2018-06-05 08:15:30 +02:00
|
|
|
if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
|
2018-05-30 15:32:08 +02:00
|
|
|
BLI_dynstr_appendf(ds, "#define V3D_SHADING_SPECULAR_HIGHLIGHT\n");
|
2018-05-30 14:40:57 +02:00
|
|
|
}
|
2018-06-05 08:15:30 +02:00
|
|
|
if (STUDIOLIGHT_ENABLED(wpd)) {
|
2018-04-25 10:59:48 +02:00
|
|
|
BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_STUDIO\n");
|
2018-06-05 08:15:30 +02:00
|
|
|
}
|
|
|
|
|
if (FLAT_ENABLED(wpd)) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_FLAT\n");
|
|
|
|
|
}
|
|
|
|
|
if (MATCAP_ENABLED(wpd)) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_MATCAP\n");
|
|
|
|
|
}
|
|
|
|
|
if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_WORLD\n");
|
|
|
|
|
}
|
|
|
|
|
if (STUDIOLIGHT_ORIENTATION_CAMERA_ENABLED(wpd)) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_CAMERA\n");
|
|
|
|
|
}
|
|
|
|
|
if (STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_VIEWNORMAL\n");
|
2018-04-25 10:59:48 +02:00
|
|
|
}
|
2018-05-15 15:19:57 +02:00
|
|
|
if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define NORMAL_VIEWPORT_PASS_ENABLED\n");
|
|
|
|
|
}
|
2018-05-08 16:57:07 +02:00
|
|
|
switch (drawtype) {
|
2018-05-07 14:59:27 +02:00
|
|
|
case OB_SOLID:
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define OB_SOLID\n");
|
|
|
|
|
break;
|
|
|
|
|
case OB_TEXTURE:
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define OB_TEXTURE\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-04-25 10:59:48 +02:00
|
|
|
|
2018-05-15 15:19:57 +02:00
|
|
|
if (NORMAL_ENCODING_ENABLED()) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define WORKBENCH_ENCODE_NORMALS\n");
|
|
|
|
|
}
|
2018-06-03 12:13:19 +02:00
|
|
|
if (is_hair) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define HAIR_SHADER\n");
|
|
|
|
|
}
|
2018-04-25 16:57:18 +02:00
|
|
|
|
2018-06-20 16:07:31 +02:00
|
|
|
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 0
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL 0\n");
|
|
|
|
|
#endif
|
|
|
|
|
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 1
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL 1\n");
|
|
|
|
|
#endif
|
|
|
|
|
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 2
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL 2\n");
|
|
|
|
|
#endif
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SPHERICAL_HARMONICS_MAX_COMPONENTS 9\n");
|
|
|
|
|
|
2018-04-25 10:59:48 +02:00
|
|
|
str = BLI_dynstr_get_cstring(ds);
|
|
|
|
|
BLI_dynstr_free(ds);
|
|
|
|
|
return str;
|
2018-04-18 13:44:33 +02:00
|
|
|
}
|
|
|
|
|
|
2018-05-22 14:12:47 +02:00
|
|
|
uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template)
|
2018-04-19 07:47:03 +02:00
|
|
|
{
|
2018-04-25 10:59:48 +02:00
|
|
|
uint input[4];
|
2018-05-07 14:59:27 +02:00
|
|
|
uint result;
|
2018-05-31 13:32:53 +02:00
|
|
|
float *color = material_template->material_data.diffuse_color;
|
2018-04-25 10:59:48 +02:00
|
|
|
input[0] = (uint)(color[0] * 512);
|
|
|
|
|
input[1] = (uint)(color[1] * 512);
|
|
|
|
|
input[2] = (uint)(color[2] * 512);
|
2018-05-05 15:31:10 +02:00
|
|
|
input[3] = material_template->object_id;
|
2018-05-07 14:59:27 +02:00
|
|
|
result = BLI_ghashutil_uinthash_v4_murmur(input);
|
2018-04-25 10:59:48 +02:00
|
|
|
|
2018-05-31 13:32:53 +02:00
|
|
|
color = material_template->material_data.specular_color;
|
|
|
|
|
input[0] = (uint)(color[0] * 512);
|
|
|
|
|
input[1] = (uint)(color[1] * 512);
|
|
|
|
|
input[2] = (uint)(color[2] * 512);
|
|
|
|
|
input[3] = (uint)(material_template->material_data.roughness * 512);
|
|
|
|
|
result += BLI_ghashutil_uinthash_v4_murmur(input);
|
|
|
|
|
|
2018-05-07 14:59:27 +02:00
|
|
|
if (material_template->drawtype == OB_TEXTURE) {
|
|
|
|
|
/* add texture reference */
|
|
|
|
|
result += BLI_ghashutil_inthash_p_murmur(material_template->ima);
|
|
|
|
|
}
|
|
|
|
|
return result;
|
2018-04-18 13:44:33 +02:00
|
|
|
}
|
|
|
|
|
|
2018-06-03 12:13:19 +02:00
|
|
|
int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, int drawtype, bool is_hair)
|
2018-04-19 10:41:24 +02:00
|
|
|
{
|
2018-06-03 12:13:19 +02:00
|
|
|
/* NOTE: change MAX_SHADERS accordingly when modifying this function. */
|
2018-06-05 08:15:30 +02:00
|
|
|
int index = 0;
|
|
|
|
|
/* 1 bit OB_SOLID and OB_TEXTURE */
|
|
|
|
|
SET_FLAG_FROM_TEST(index, drawtype == OB_TEXTURE, 1 << 0);
|
|
|
|
|
/* 2 bits FLAT/STUDIO/MATCAP/SCENE */
|
|
|
|
|
SET_FLAG_FROM_TEST(index, wpd->shading.light, wpd->shading.light << 1);
|
|
|
|
|
/* 1 bit V3D_SHADING_SPECULAR_HIGHLIGHT */
|
|
|
|
|
SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT, 1 << 3);
|
|
|
|
|
SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_SHADOW, 1 << 4);
|
2018-06-06 14:47:54 +02:00
|
|
|
SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_CAVITY, 1 << 5);
|
|
|
|
|
SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE, 1 << 6);
|
2018-06-05 08:15:30 +02:00
|
|
|
/* 2 bits STUDIOLIGHT_ORIENTATION */
|
2018-06-06 14:47:54 +02:00
|
|
|
SET_FLAG_FROM_TEST(index, wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD, 1 << 7);
|
|
|
|
|
SET_FLAG_FROM_TEST(index, wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_VIEWNORMAL, 1 << 8);
|
2018-06-05 08:15:30 +02:00
|
|
|
/* 1 bit for hair */
|
2018-06-06 14:47:54 +02:00
|
|
|
SET_FLAG_FROM_TEST(index, is_hair, 1 << 9);
|
2018-05-22 14:12:47 +02:00
|
|
|
return index;
|
2018-05-04 14:07:00 +02:00
|
|
|
}
|
|
|
|
|
|
2018-05-26 10:41:25 +02:00
|
|
|
void workbench_material_set_normal_world_matrix(
|
|
|
|
|
DRWShadingGroup *grp, WORKBENCH_PrivateData *wpd, float persistent_matrix[3][3])
|
2018-05-04 14:07:00 +02:00
|
|
|
{
|
2018-05-16 16:42:30 +02:00
|
|
|
if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
|
|
|
|
|
float view_matrix_inverse[4][4];
|
|
|
|
|
float rot_matrix[4][4];
|
|
|
|
|
float matrix[4][4];
|
|
|
|
|
axis_angle_to_mat4_single(rot_matrix, 'Z', -wpd->shading.studiolight_rot_z);
|
|
|
|
|
DRW_viewport_matrix_get(view_matrix_inverse, DRW_MAT_VIEWINV);
|
|
|
|
|
mul_m4_m4m4(matrix, rot_matrix, view_matrix_inverse);
|
2018-05-22 14:12:47 +02:00
|
|
|
copy_m3_m4(persistent_matrix, matrix);
|
|
|
|
|
DRW_shgroup_uniform_mat3(grp, "normalWorldMatrix", persistent_matrix);
|
2018-05-17 15:23:21 +02:00
|
|
|
}
|
2018-04-25 10:59:48 +02:00
|
|
|
}
|