diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_render.py | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_scene.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 6 | ||||
-rw-r--r-- | source/blender/gpu/GPU_material.h | 1 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_material.c | 5 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 5 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_geom.c | 11 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_lamp.c | 7 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_material.c | 18 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_normal_map.c | 40 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_shader_ext.h | 1 | ||||
-rw-r--r-- | source/blender/render/intern/source/shadeinput.c | 1 |
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; |