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-06-29 09:59:37 +02:00
|
|
|
#include "BIF_gl.h"
|
|
|
|
|
|
2018-05-04 14:07:00 +02:00
|
|
|
#include "BLI_dynstr.h"
|
2018-11-24 18:37:21 +01:00
|
|
|
#include "BLI_hash.h"
|
2018-05-04 14:07:00 +02:00
|
|
|
|
2018-05-22 14:12:47 +02:00
|
|
|
#define HSV_SATURATION 0.5
|
2018-11-28 15:57:40 +01:00
|
|
|
#define HSV_VALUE 0.8
|
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
|
|
|
{
|
2018-06-21 14:56:00 +02:00
|
|
|
/* When V3D_SHADING_TEXTURE_COLOR is active, use V3D_SHADING_MATERIAL_COLOR as fallback when no texture could be determined */
|
2018-06-25 12:02:57 +02:00
|
|
|
int color_type = wpd->shading.color_type == V3D_SHADING_TEXTURE_COLOR ? V3D_SHADING_MATERIAL_COLOR : wpd->shading.color_type;
|
2018-11-28 15:57:40 +01:00
|
|
|
copy_v4_fl4(data->diffuse_color, 0.8f, 0.8f, 0.8f, 1.0f);
|
|
|
|
|
copy_v4_fl4(data->specular_color, 0.05f, 0.05f, 0.05f, 1.0f); /* Dielectric: 5% reflective. */
|
|
|
|
|
data->roughness = 0.5; /* sqrtf(0.25f); */
|
2018-05-31 13:32:53 +02:00
|
|
|
|
2018-06-22 10:37:38 +02:00
|
|
|
if (color_type == V3D_SHADING_SINGLE_COLOR) {
|
2018-06-29 08:25:23 +02:00
|
|
|
copy_v3_v3(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);
|
|
|
|
|
}
|
2018-05-15 15:19:57 +02:00
|
|
|
|
2018-11-24 18:37:21 +01:00
|
|
|
float hue = BLI_hash_int_01(hash);
|
|
|
|
|
float hsv[3] = {hue, HSV_SATURATION, HSV_VALUE};
|
2018-06-29 08:25:23 +02:00
|
|
|
hsv_to_rgb_v(hsv, data->diffuse_color);
|
2018-05-22 14:12:47 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* V3D_SHADING_MATERIAL_COLOR */
|
|
|
|
|
if (mat) {
|
2018-11-28 15:57:40 +01:00
|
|
|
if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
|
|
|
|
|
mul_v3_v3fl(data->diffuse_color, &mat->r, 1.0f - mat->metallic);
|
|
|
|
|
mul_v3_v3fl(data->specular_color, &mat->r, mat->metallic);
|
|
|
|
|
add_v3_fl(data->specular_color, 0.05f * (1.0f - mat->metallic));
|
|
|
|
|
data->roughness = sqrtf(mat->roughness); /* Remap to disney roughness. */
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
copy_v3_v3(data->diffuse_color, &mat->r);
|
|
|
|
|
}
|
2018-05-22 14:12:47 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-05-15 15:19:57 +02:00
|
|
|
|
2018-06-21 14:56:00 +02:00
|
|
|
char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_textures, 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-11-30 01:53:50 +01:00
|
|
|
if (SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd)) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define WB_CAVITY\n");
|
2018-06-06 14:47:54 +02:00
|
|
|
}
|
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");
|
|
|
|
|
}
|
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-06-21 14:56:00 +02:00
|
|
|
if (use_textures) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define V3D_SHADING_TEXTURE_COLOR\n");
|
2018-05-07 14:59:27 +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-11-19 01:01:43 +01:00
|
|
|
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SH_BANDS %d\n", STUDIOLIGHT_SH_BANDS);
|
2018-11-19 18:03:06 +01:00
|
|
|
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SH_MAX_COMPONENTS %d\n", WORKBENCH_SH_DATA_LEN);
|
2018-06-20 16:07:31 +02:00
|
|
|
|
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-08-14 20:26:21 +02:00
|
|
|
uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template, bool is_ghost)
|
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-06-29 08:25:23 +02:00
|
|
|
float *color = material_template->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-06-29 08:25:23 +02:00
|
|
|
color = material_template->specular_color;
|
2018-05-31 13:32:53 +02:00
|
|
|
input[0] = (uint)(color[0] * 512);
|
|
|
|
|
input[1] = (uint)(color[1] * 512);
|
|
|
|
|
input[2] = (uint)(color[2] * 512);
|
2018-06-29 08:25:23 +02:00
|
|
|
input[3] = (uint)(material_template->roughness * 512);
|
2018-05-31 13:32:53 +02:00
|
|
|
result += BLI_ghashutil_uinthash_v4_murmur(input);
|
|
|
|
|
|
2018-08-14 20:26:21 +02:00
|
|
|
result += BLI_ghashutil_uinthash((uint)is_ghost);
|
|
|
|
|
|
2018-06-28 09:19:00 +02:00
|
|
|
/* add texture reference */
|
2018-07-10 09:29:30 +02:00
|
|
|
if (material_template->ima) {
|
2018-06-28 10:34:38 +02:00
|
|
|
result += BLI_ghashutil_inthash_p_murmur(material_template->ima);
|
|
|
|
|
}
|
2018-06-28 09:19:00 +02:00
|
|
|
|
2018-05-07 14:59:27 +02:00
|
|
|
return result;
|
2018-04-18 13:44:33 +02:00
|
|
|
}
|
|
|
|
|
|
2018-06-21 14:56:00 +02:00
|
|
|
int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, bool use_textures, 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;
|
2018-06-21 14:56:00 +02:00
|
|
|
/* 1 bit V3D_SHADING_TEXTURE_COLOR */
|
|
|
|
|
SET_FLAG_FROM_TEST(index, use_textures, 1 << 0);
|
2018-11-30 01:53:50 +01:00
|
|
|
/* 2 bits FLAT/STUDIO/MATCAP + Specular highlight */
|
|
|
|
|
int ligh_flag = SPECULAR_HIGHLIGHT_ENABLED(wpd) ? 3 : wpd->shading.light;
|
|
|
|
|
SET_FLAG_FROM_TEST(index, wpd->shading.light, ligh_flag << 1);
|
|
|
|
|
/* 3 bits for flags */
|
|
|
|
|
SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_SHADOW, 1 << 3);
|
|
|
|
|
SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_CAVITY, 1 << 4);
|
|
|
|
|
SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE, 1 << 5);
|
2018-06-05 08:15:30 +02:00
|
|
|
/* 1 bit for hair */
|
2018-11-30 01:53:50 +01:00
|
|
|
SET_FLAG_FROM_TEST(index, is_hair, 1 << 6);
|
2018-05-22 14:12:47 +02:00
|
|
|
return index;
|
2018-05-04 14:07:00 +02:00
|
|
|
}
|
|
|
|
|
|
2018-08-20 16:21:44 +02:00
|
|
|
int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd, Image *ima, Object *ob)
|
2018-06-21 14:56:00 +02:00
|
|
|
{
|
|
|
|
|
int color_type = wpd->shading.color_type;
|
2018-08-20 16:21:44 +02:00
|
|
|
if ((color_type == V3D_SHADING_TEXTURE_COLOR && ima == NULL) || (ob->dt < OB_TEXTURE)) {
|
2018-06-21 14:56:00 +02:00
|
|
|
color_type = V3D_SHADING_MATERIAL_COLOR;
|
|
|
|
|
}
|
|
|
|
|
return color_type;
|
2018-06-22 08:18:02 +02:00
|
|
|
}
|
2018-06-29 08:25:23 +02:00
|
|
|
|
2018-07-10 09:29:30 +02:00
|
|
|
void workbench_material_shgroup_uniform(
|
2018-08-20 16:21:44 +02:00
|
|
|
WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob)
|
2018-06-29 08:25:23 +02:00
|
|
|
{
|
2018-08-20 16:21:44 +02:00
|
|
|
if (workbench_material_determine_color_type(wpd, material->ima, ob) == V3D_SHADING_TEXTURE_COLOR) {
|
2018-06-29 09:59:37 +02:00
|
|
|
GPUTexture *tex = GPU_texture_from_blender(material->ima, NULL, GL_TEXTURE_2D, false, 0.0f);
|
|
|
|
|
DRW_shgroup_uniform_texture(grp, "image", tex);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
DRW_shgroup_uniform_vec4(grp, "materialDiffuseColor", material->diffuse_color, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
|
|
|
|
|
DRW_shgroup_uniform_vec4(grp, "materialSpecularColor", material->specular_color, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "materialRoughness", &material->roughness, 1);
|
|
|
|
|
}
|
2018-06-29 08:25:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void workbench_material_copy(WORKBENCH_MaterialData *dest_material, const WORKBENCH_MaterialData *source_material)
|
|
|
|
|
{
|
|
|
|
|
dest_material->object_id = source_material->object_id;
|
|
|
|
|
copy_v4_v4(dest_material->diffuse_color, source_material->diffuse_color);
|
|
|
|
|
copy_v4_v4(dest_material->specular_color, source_material->specular_color);
|
|
|
|
|
dest_material->roughness = source_material->roughness;
|
|
|
|
|
dest_material->ima = source_material->ima;
|
2018-06-29 09:25:40 +02:00
|
|
|
}
|