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:
authorAlexander Romanov <a.romanov@blend4web.com>2016-06-07 10:33:32 +0300
committerAlexander Romanov <a.romanov@blend4web.com>2016-06-07 10:42:29 +0300
commit0da13ad1ebea9e880a0cd7e1d8b32ea567aef174 (patch)
tree53fc3b010e14d615161f908a6b93fdc3b333e284
parent441a440cbbb700511d6d1ec01e2f149355adcc02 (diff)
World space switch for BI nodes.
At the moment light shading in Blender is produced in viewspace. Apparently, that's why shader nodes work with normals in camera space. But it is not convenient for artists. The more convenient approach is implemented in Cycles where normals are represented in world space. Blend4Web Team designed the engine keeping in mind shader parameters readability, so normals are interpreted in world space as well. And now our users have to use some tweaks, like empty node group with the name "Replace", which is replacing one input by another on the engine side (replacing working configuration in Blender Viewport by the configuration that has the same behavior in the engine). This patch adds the ability to switch to world space for normals and lamp vector in BI and Viewport. This patch is very important to us and we crave to see this patch in Blender 2.7 because it will significantly simplify Blend4Web material creation workflow. {F315547} {F315548} Reviewers: campbellbarton, brecht Reviewed By: brecht Subscribers: homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov Differential Revision: https://developer.blender.org/D2046
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py1
-rw-r--r--source/blender/blenkernel/BKE_scene.h1
-rw-r--r--source/blender/blenkernel/intern/scene.c6
-rw-r--r--source/blender/gpu/GPU_material.h1
-rw-r--r--source/blender/gpu/intern/gpu_material.c5
-rw-r--r--source/blender/makesdna/DNA_scene_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_scene.c5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_geom.c11
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_lamp.c7
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_material.c18
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal_map.c40
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h1
-rw-r--r--source/blender/render/intern/source/shadeinput.c1
13 files changed, 80 insertions, 18 deletions
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 13e7265319b..4ea1c3a5cc7 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -248,6 +248,7 @@ class RENDER_PT_shading(RenderButtonsPanel, Panel):
col = split.column()
col.prop(rd, "use_raytrace", text="Ray Tracing")
col.prop(rd, "alpha_mode", text="Alpha")
+ col.prop(rd, "use_world_space_shading", text="World Space Shading")
class RENDER_PT_performance(RenderButtonsPanel, Panel):
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index a4c44b9934e..12bfc07e958 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -135,6 +135,7 @@ float get_render_aosss_error(const struct RenderData *r, float error);
bool BKE_scene_use_new_shading_nodes(const struct Scene *scene);
bool BKE_scene_use_shading_nodes_custom(struct Scene *scene);
+bool BKE_scene_use_world_space_shading(struct Scene *scene);
bool BKE_scene_use_spherical_stereo(struct Scene *scene);
bool BKE_scene_uses_blender_internal(const struct Scene *scene);
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index d307ba1811b..d16e6d5d17a 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -2193,6 +2193,12 @@ bool BKE_scene_use_shading_nodes_custom(Scene *scene)
return (type && type->flag & RE_USE_SHADING_NODES_CUSTOM);
}
+bool BKE_scene_use_world_space_shading(Scene *scene)
+{
+ const RenderEngineType *type = RE_engines_find(scene->r.engine);
+ return (type && (type->flag & RE_USE_SHADING_NODES) || (scene->r.mode & R_USE_WS_SHADING));
+}
+
bool BKE_scene_use_spherical_stereo(Scene *scene)
{
RenderEngineType *type = RE_engines_find(scene->r.engine);
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index fc2ca16db59..a79334df8ce 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -241,6 +241,7 @@ void GPU_material_vertex_attributes(GPUMaterial *material,
bool GPU_material_do_color_management(GPUMaterial *mat);
bool GPU_material_use_new_shading_nodes(GPUMaterial *mat);
+bool GPU_material_use_world_space_shading(GPUMaterial *mat);
/* Exported shading */
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 99ecf687f70..02f58ea6df2 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -517,6 +517,11 @@ bool GPU_material_use_new_shading_nodes(GPUMaterial *mat)
return BKE_scene_use_new_shading_nodes(mat->scene);
}
+bool GPU_material_use_world_space_shading(GPUMaterial *mat)
+{
+ return BKE_scene_use_world_space_shading(mat->scene);
+}
+
static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist)
{
GPUNodeLink *visifac;
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 1bf044ffecb..79af1813a8f 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1639,6 +1639,7 @@ typedef struct Scene {
#define R_SIMPLIFY 0x1000000
#define R_EDGE_FRS 0x2000000 /* R_EDGE reserved for Freestyle */
#define R_PERSISTENT_DATA 0x4000000 /* keep data around for re-render */
+#define R_USE_WS_SHADING 0x8000000 /* use world space interpretation of lighting data */
/* seq_flag */
#define R_SEQ_GL_PREV 1
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 79b8ddec08a..533c0f86460 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -5567,6 +5567,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_SSS);
RNA_def_property_ui_text(prop, "Subsurface Scattering", "Calculate sub-surface scattering in materials rendering");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
+
+ prop = RNA_def_property(srna, "use_world_space_shading", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mode", R_USE_WS_SHADING);
+ RNA_def_property_ui_text(prop, "World Space Shading", "Use world space interpretation of lighting data for node materials");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
prop = RNA_def_property(srna, "use_raytrace", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_RAYTRACE);
diff --git a/source/blender/nodes/shader/nodes/node_shader_geom.c b/source/blender/nodes/shader/nodes/node_shader_geom.c
index cd52c4e2547..b289d66efc3 100644
--- a/source/blender/nodes/shader/nodes/node_shader_geom.c
+++ b/source/blender/nodes/shader/nodes/node_shader_geom.c
@@ -78,6 +78,10 @@ static void node_shader_exec_geom(void *data, int UNUSED(thread), bNode *node, b
copy_v3_v3(out[GEOM_OUT_UV]->vec, suv->uv);
copy_v3_v3(out[GEOM_OUT_NORMAL]->vec, shi->vno);
+ if (shi->use_world_space_shading) {
+ negate_v3(out[GEOM_OUT_NORMAL]->vec);
+ mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), out[GEOM_OUT_NORMAL]->vec);
+ }
if (shi->totcol) {
/* find vertex color layer by name */
ShadeInputCol *scol = &shi->col[0];
@@ -132,9 +136,14 @@ static int gpu_shader_geom(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(
GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, ngeo->uvname);
GPUNodeLink *mcol = GPU_attribute(CD_MCOL, ngeo->colname);
- return GPU_stack_link(mat, "geom", in, out,
+ bool ret = GPU_stack_link(mat, "geom", in, out,
GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
GPU_builtin(GPU_INVERSE_VIEW_MATRIX), orco, mtface, mcol);
+ if (GPU_material_use_world_space_shading(mat)) {
+ GPU_link(mat, "vec_math_negate", out[5].link, &out[5].link);
+ ret &= GPU_link(mat, "direction_transform_m4v3", out[5].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[5].link);
+ }
+ return ret;
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_lamp.c b/source/blender/nodes/shader/nodes/node_shader_lamp.c
index d5dac3b7ff8..2c96c91958e 100644
--- a/source/blender/nodes/shader/nodes/node_shader_lamp.c
+++ b/source/blender/nodes/shader/nodes/node_shader_lamp.c
@@ -54,6 +54,8 @@ static void node_shader_exec_lamp(void *data, int UNUSED(thread), bNode *node, b
shi->nodes = 1; /* temp hack to prevent trashadow recursion */
out[4]->vec[0] = RE_lamp_get_data(shi, ob, out[0]->vec, out[1]->vec, out[2]->vec, out[3]->vec);
shi->nodes = 0;
+ if (shi->use_world_space_shading)
+ mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), out[1]->vec);
}
}
}
@@ -66,7 +68,10 @@ static int gpu_shader_lamp(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(
visifac = GPU_lamp_get_data(mat, lamp, &col, &lv, &dist, &shadow, &energy);
- return GPU_stack_link(mat, "lamp", in, out, col, energy, lv, dist, shadow, visifac);
+ bool ret = GPU_stack_link(mat, "lamp", in, out, col, energy, lv, dist, shadow, visifac);
+ if (GPU_material_use_world_space_shading(mat))
+ ret &= GPU_link(mat, "direction_transform_m4v3", out[1].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[1].link);
+ return ret;
}
return false;
diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c
index fa13f6191ad..8b21b1ff33b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_material.c
+++ b/source/blender/nodes/shader/nodes/node_shader_material.c
@@ -114,6 +114,10 @@ static void node_shader_exec_material(void *data, int UNUSED(thread), bNode *nod
/* retrieve normal */
if (hasinput[MAT_IN_NORMAL]) {
nodestack_get_vec(shi->vn, SOCK_VECTOR, in[MAT_IN_NORMAL]);
+ if (shi->use_world_space_shading) {
+ negate_v3(shi->vn);
+ mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), shi->vn);
+ }
normalize_v3(shi->vn);
}
else
@@ -181,7 +185,11 @@ static void node_shader_exec_material(void *data, int UNUSED(thread), bNode *nod
}
copy_v3_v3(out[MAT_OUT_NORMAL]->vec, shi->vn);
-
+
+ if (shi->use_world_space_shading) {
+ negate_v3(out[MAT_OUT_NORMAL]->vec);
+ mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), out[MAT_OUT_NORMAL]->vec);
+ }
/* Extended material options */
if (node->type == SH_NODE_MATERIAL_EXT) {
/* Shadow, Reflect, Refract, Radiosity, Speed seem to cause problems inside
@@ -255,6 +263,10 @@ static int gpu_shader_material(GPUMaterial *mat, bNode *node, bNodeExecData *UNU
if (hasinput[MAT_IN_NORMAL]) {
GPUNodeLink *tmp;
shi.vn = gpu_get_input_link(&in[MAT_IN_NORMAL]);
+ if (GPU_material_use_world_space_shading(mat)) {
+ GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn);
+ GPU_link(mat, "direction_transform_m4v3", shi.vn, GPU_builtin(GPU_VIEW_MATRIX), &shi.vn);
+ }
GPU_link(mat, "vec_math_normalize", shi.vn, &shi.vn, &tmp);
}
@@ -299,6 +311,10 @@ static int gpu_shader_material(GPUMaterial *mat, bNode *node, bNodeExecData *UNU
if (node->custom1 & SH_NODE_MAT_NEG)
GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn);
out[MAT_OUT_NORMAL].link = shi.vn;
+ if (GPU_material_use_world_space_shading(mat)) {
+ GPU_link(mat, "vec_math_negate", out[MAT_OUT_NORMAL].link, &out[MAT_OUT_NORMAL].link);
+ GPU_link(mat, "direction_transform_m4v3", out[MAT_OUT_NORMAL].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[MAT_OUT_NORMAL].link);
+ }
if (node->type == SH_NODE_MATERIAL_EXT) {
out[MAT_OUT_DIFFUSE].link = shr.diff;
diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
index 85e2c77662d..57014bdc476 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c
+++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
@@ -89,20 +89,34 @@ static void node_shader_exec_normal_map(void *data, int UNUSED(thread), bNode *n
for (int j = 0; j < 3; j++)
out[0]->vec[j] = vecIn[0] * T[j] + vecIn[1] * B[j] + vecIn[2] * N[j];
interp_v3_v3v3(out[0]->vec, N, out[0]->vec, strength);
+ if (shi->use_world_space_shading) {
+ mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), out[0]->vec);
+ }
break;
case SHD_NORMAL_MAP_OBJECT:
case SHD_NORMAL_MAP_BLENDER_OBJECT:
- mul_mat3_m4_v3((float (*)[4])RE_object_instance_get_matrix(shi->obi, RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEW), vecIn);
+ if (shi->use_world_space_shading) {
+ mul_mat3_m4_v3((float (*)[4])RE_object_instance_get_matrix(shi->obi, RE_OBJECT_INSTANCE_MATRIX_OB), vecIn);
+ mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), N);
+ }
+ else
+ mul_mat3_m4_v3((float (*)[4])RE_object_instance_get_matrix(shi->obi, RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEW), vecIn);
interp_v3_v3v3(out[0]->vec, N, vecIn, strength);
break;
case SHD_NORMAL_MAP_WORLD:
case SHD_NORMAL_MAP_BLENDER_WORLD:
- mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), vecIn);
+ if (shi->use_world_space_shading)
+ mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), N);
+ else
+ mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), vecIn);
interp_v3_v3v3(out[0]->vec, N, vecIn, strength);
break;
}
+ if (shi->use_world_space_shading) {
+ negate_v3(out[0]->vec);
+ }
normalize_v3(out[0]->vec);
}
}
@@ -129,10 +143,13 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U
negnorm = GPU_builtin(GPU_VIEW_NORMAL);
GPU_link(mat, "math_max", strength, GPU_uniform(d), &strength);
- if (GPU_material_use_new_shading_nodes(mat)) {
+ if (GPU_material_use_world_space_shading(mat)) {
- /* **************** CYCLES ******************** */
+ /* ******* CYCLES or BLENDER INTERNAL with world space shading flag ******* */
+ const char *color_to_normal_fnc_name = "color_to_normal_new_shading";
+ if (nm->space == SHD_NORMAL_MAP_BLENDER_OBJECT || nm->space == SHD_NORMAL_MAP_BLENDER_WORLD || !GPU_material_use_new_shading_nodes(mat))
+ color_to_normal_fnc_name = "color_to_blender_normal_new_shading";
switch (nm->space) {
case SHD_NORMAL_MAP_TANGENT:
GPU_link(mat, "color_to_normal_new_shading", realnorm, &realnorm);
@@ -143,28 +160,21 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U
GPU_link(mat, "vect_normalize", out[0].link, &out[0].link);
return true;
case SHD_NORMAL_MAP_OBJECT:
- GPU_link(mat, "direction_transform_m4v3", negnorm, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &negnorm);
- GPU_link(mat, "color_to_normal_new_shading", realnorm, &realnorm);
- GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_OBJECT_MATRIX), &realnorm);
- break;
case SHD_NORMAL_MAP_BLENDER_OBJECT:
GPU_link(mat, "direction_transform_m4v3", negnorm, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &negnorm);
- GPU_link(mat, "color_to_blender_normal_new_shading", realnorm, &realnorm);
- GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_OBJECT_MATRIX), &realnorm);
+ GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm);
+ GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_OBJECT_MATRIX), &realnorm);
break;
case SHD_NORMAL_MAP_WORLD:
- GPU_link(mat, "direction_transform_m4v3", negnorm, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &negnorm);
- GPU_link(mat, "color_to_normal_new_shading", realnorm, &realnorm);
- break;
case SHD_NORMAL_MAP_BLENDER_WORLD:
GPU_link(mat, "direction_transform_m4v3", negnorm, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &negnorm);
- GPU_link(mat, "color_to_blender_normal_new_shading", realnorm, &realnorm);
+ GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm);
break;
}
} else {
- /* *********** BLENDER INTERNAL *************** */
+ /* ************** BLENDER INTERNAL without world space shading flag ******* */
GPU_link(mat, "color_to_normal", realnorm, &realnorm);
GPU_link(mat, "mtex_negate_texnormal", realnorm, &realnorm);
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index 8b6dfb88b73..73867de6b2e 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -172,6 +172,7 @@ typedef struct ShadeInput {
/* from initialize, part or renderlayer */
bool do_preview; /* for nodes, in previewrender */
bool do_manage; /* color management flag */
+ bool use_world_space_shading;
short thread, sample; /* sample: ShadeSample array index */
short nodes; /* indicate node shading, temp hack to prevent recursion */
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index 6e01921a6a7..20602314526 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -1339,6 +1339,7 @@ void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, in
shi->do_preview = (R.r.scemode & R_MATNODE_PREVIEW) != 0;
shi->do_manage = BKE_scene_check_color_management_enabled(R.scene);
+ shi->use_world_space_shading = BKE_scene_use_world_space_shading(R.scene);
shi->lay = rl->lay;
shi->layflag = rl->layflag;