Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines/workbench/workbench_materials.c')
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
new file mode 100644
index 00000000000..76599fdce99
--- /dev/null
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -0,0 +1,176 @@
+
+
+#include "workbench_private.h"
+
+#include "BLI_dynstr.h"
+
+#define HSV_SATURATION 0.5
+#define HSV_VALUE 0.9
+
+void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, WORKBENCH_MaterialData *data)
+{
+ /* When V3D_SHADING_TEXTURE_COLOR is active, use V3D_SHADING_MATERIAL_COLOR as fallback when no texture could be determined */
+ int color_type = wpd->shading.color_type == V3D_SHADING_TEXTURE_COLOR ? V3D_SHADING_MATERIAL_COLOR : wpd->shading.color_type;
+ static float default_diffuse_color[] = {0.8f, 0.8f, 0.8f, 1.0f};
+ static float default_specular_color[] = {0.5f, 0.5f, 0.5f, 0.5f};
+ copy_v4_v4(data->material_data.diffuse_color, default_diffuse_color);
+ copy_v4_v4(data->material_data.specular_color, default_specular_color);
+ data->material_data.roughness = 0.5f;
+
+ if (color_type == V3D_SHADING_SINGLE_COLOR) {
+ copy_v3_v3(data->material_data.diffuse_color, wpd->shading.single_color);
+ }
+ 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);
+
+ float hsv[3] = {offset, HSV_SATURATION, HSV_VALUE};
+ hsv_to_rgb_v(hsv, data->material_data.diffuse_color);
+ }
+ else {
+ /* V3D_SHADING_MATERIAL_COLOR */
+ if (mat) {
+ 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;
+ }
+ }
+}
+
+char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair)
+{
+ char *str = NULL;
+
+ DynStr *ds = BLI_dynstr_new();
+
+ if (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE) {
+ BLI_dynstr_appendf(ds, "#define V3D_SHADING_OBJECT_OUTLINE\n");
+ }
+ if (wpd->shading.flag & V3D_SHADING_SHADOW) {
+ BLI_dynstr_appendf(ds, "#define V3D_SHADING_SHADOW\n");
+ }
+ if (CAVITY_ENABLED(wpd)) {
+ BLI_dynstr_appendf(ds, "#define V3D_SHADING_CAVITY\n");
+ }
+ if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
+ BLI_dynstr_appendf(ds, "#define V3D_SHADING_SPECULAR_HIGHLIGHT\n");
+ }
+ if (STUDIOLIGHT_ENABLED(wpd)) {
+ BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_STUDIO\n");
+ }
+ 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");
+ }
+ if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
+ BLI_dynstr_appendf(ds, "#define NORMAL_VIEWPORT_PASS_ENABLED\n");
+ }
+ if (use_textures) {
+ BLI_dynstr_appendf(ds, "#define V3D_SHADING_TEXTURE_COLOR\n");
+ }
+ if (NORMAL_ENCODING_ENABLED()) {
+ BLI_dynstr_appendf(ds, "#define WORKBENCH_ENCODE_NORMALS\n");
+ }
+ if (is_hair) {
+ BLI_dynstr_appendf(ds, "#define HAIR_SHADER\n");
+ }
+
+#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");
+
+ str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+ return str;
+}
+
+uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template)
+{
+ uint input[4];
+ uint result;
+ float *color = material_template->material_data.diffuse_color;
+ input[0] = (uint)(color[0] * 512);
+ input[1] = (uint)(color[1] * 512);
+ input[2] = (uint)(color[2] * 512);
+ input[3] = material_template->object_id;
+ result = BLI_ghashutil_uinthash_v4_murmur(input);
+
+ 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);
+
+ if (material_template->color_type == V3D_SHADING_TEXTURE_COLOR) {
+ /* add texture reference */
+ result += BLI_ghashutil_inthash_p_murmur(material_template->ima);
+ }
+ return result;
+}
+
+int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair)
+{
+ /* NOTE: change MAX_SHADERS accordingly when modifying this function. */
+ int index = 0;
+ /* 1 bit V3D_SHADING_TEXTURE_COLOR */
+ SET_FLAG_FROM_TEST(index, use_textures, 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);
+ 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);
+ /* 2 bits STUDIOLIGHT_ORIENTATION */
+ 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);
+ /* 1 bit for hair */
+ SET_FLAG_FROM_TEST(index, is_hair, 1 << 9);
+ return index;
+}
+
+void workbench_material_set_normal_world_matrix(
+ DRWShadingGroup *grp, WORKBENCH_PrivateData *wpd, float persistent_matrix[3][3])
+{
+ 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);
+ copy_m3_m4(persistent_matrix, matrix);
+ DRW_shgroup_uniform_mat3(grp, "normalWorldMatrix", persistent_matrix);
+ }
+}
+
+int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd, Image *ima)
+{
+ int color_type = wpd->shading.color_type;
+ if (color_type == V3D_SHADING_TEXTURE_COLOR && ima == NULL) {
+ color_type = V3D_SHADING_MATERIAL_COLOR;
+ }
+ return color_type;
+}