From 12e1732f72bba6905da834a565885d4e8ecf9dc9 Mon Sep 17 00:00:00 2001 From: Alexander Romanov Date: Thu, 15 Dec 2016 15:03:28 +0300 Subject: Layer Weight node support for Blender Internal Render --- .../nodes/shader/nodes/node_shader_fresnel.c | 23 +-------------- .../nodes/shader/nodes/node_shader_layer_weight.c | 34 ++++++++++++++++++++-- 2 files changed, 33 insertions(+), 24 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/shader/nodes/node_shader_fresnel.c b/source/blender/nodes/shader/nodes/node_shader_fresnel.c index 917a06b3536..d5e11795fc0 100644 --- a/source/blender/nodes/shader/nodes/node_shader_fresnel.c +++ b/source/blender/nodes/shader/nodes/node_shader_fresnel.c @@ -51,27 +51,6 @@ static int node_shader_gpu_fresnel(GPUMaterial *mat, bNode *UNUSED(node), bNodeE return GPU_stack_link(mat, "node_fresnel", in, out, GPU_builtin(GPU_VIEW_POSITION)); } -static float fresnel_dielectric(float incoming[3], float normal[3], float eta) -{ - /* compute fresnel reflectance without explicitly computing - * the refracted direction */ - float c = fabs(dot_v3v3(incoming, normal)); - float g = eta * eta - 1.0 + c * c; - float result; - - if (g > 0.0) { - g = sqrtf(g); - float A = (g - c) / (g + c); - float B = (c * (g + c) - 1.0) / (c * (g - c) + 1.0); - result = 0.5 * A * A * (1.0 + B * B); - } - else { - result = 1.0; /* TIR (no refracted component) */ - } - - return result; -} - static void node_shader_exec_fresnel(void *data, int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) { ShadeInput *shi = ((ShaderCallData *)data)->shi; @@ -88,7 +67,7 @@ static void node_shader_exec_fresnel(void *data, int UNUSED(thread), bNode *UNUS if(shi->use_world_space_shading) mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), n); - out[0]->vec[0] = fresnel_dielectric(shi->view, n, shi->flippednor ? 1/eta : eta); + out[0]->vec[0] = RE_fresnel_dielectric(shi->view, n, shi->flippednor ? 1/eta : eta); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_layer_weight.c b/source/blender/nodes/shader/nodes/node_shader_layer_weight.c index 8cbc587e339..90e2625b961 100644 --- a/source/blender/nodes/shader/nodes/node_shader_layer_weight.c +++ b/source/blender/nodes/shader/nodes/node_shader_layer_weight.c @@ -45,23 +45,53 @@ static int node_shader_gpu_layer_weight(GPUMaterial *mat, bNode *UNUSED(node), b { if (!in[1].link) in[1].link = GPU_builtin(GPU_VIEW_NORMAL); - else + else if (GPU_material_use_world_space_shading(mat)) { GPU_link(mat, "direction_transform_m4v3", in[1].link, GPU_builtin(GPU_VIEW_MATRIX), &in[1].link); + } return GPU_stack_link(mat, "node_layer_weight", in, out, GPU_builtin(GPU_VIEW_POSITION)); } +static void node_shader_exec_layer_weight(void *data, int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) +{ + ShadeInput *shi = ((ShaderCallData *)data)->shi; + float blend = in[0]->vec[0]; + float eta = max_ff(1 - blend, 0.00001); + + float n[3]; + if (in[1]->hasinput) { + copy_v3_v3(n, in[1]->vec); + } + else { + copy_v3_v3(n, shi->vn); + } + + if (shi->use_world_space_shading) + mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), n); + + out[0]->vec[0] = RE_fresnel_dielectric(shi->view, n, shi->flippednor ? eta : 1/eta); + + float facing = fabs(dot_v3v3(shi->view, n)); + if (blend != 0.5) { + CLAMP(blend, 0.0, 0.99999); + blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend); + facing = pow(facing, blend); + } + out[1]->vec[0] = 1.0 - facing; +} + /* node type definition */ void register_node_type_sh_layer_weight(void) { static bNodeType ntype; sh_node_type_base(&ntype, SH_NODE_LAYER_WEIGHT, "Layer Weight", NODE_CLASS_INPUT, 0); - node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_compatibility(&ntype, NODE_NEW_SHADING | NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_layer_weight_in, sh_node_layer_weight_out); node_type_init(&ntype, NULL); node_type_storage(&ntype, "", NULL, NULL); node_type_gpu(&ntype, node_shader_gpu_layer_weight); + node_type_exec(&ntype, NULL, NULL, node_shader_exec_layer_weight); nodeRegisterType(&ntype); } -- cgit v1.2.3