Commit: 12e1732f72bba6905da834a565885d4e8ecf9dc9
Author: Alexander Romanov
Date:   Thu Dec 15 15:03:28 2016 +0300
Branches: master
https://developer.blender.org/rB12e1732f72bba6905da834a565885d4e8ecf9dc9

Layer Weight node support for Blender Internal Render

===================================================================

M       source/blender/nodes/shader/nodes/node_shader_fresnel.c
M       source/blender/nodes/shader/nodes/node_shader_layer_weight.c
M       source/blender/render/extern/include/RE_shader_ext.h
M       source/blender/render/intern/include/shading.h
M       source/blender/render/intern/source/shadeoutput.c

===================================================================

diff --git a/source/blender/nodes/shader/nodes/node_shader_fresnel.c 
b/source/blender/nodes/shader/nodes/node_shader_fresnel.c
index 917a06b..d5e1179 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 8cbc587..90e2625 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);
 }
diff --git a/source/blender/render/extern/include/RE_shader_ext.h 
b/source/blender/render/extern/include/RE_shader_ext.h
index 73867de..ae389fd 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -218,6 +218,8 @@ int multitex_nodes(struct Tex *tex, float texvec[3], float 
dxt[3], float dyt[3],
 float RE_lamp_get_data(struct ShadeInput *shi, struct Object *lamp_obj, float 
col[4], float lv[3], float *dist, float shadow[4]);
 void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float 
*index, float *age, float *lifetime, float co[3], float *size, float vel[3], 
float angvel[3]);
 
+float RE_fresnel_dielectric(float incoming[3], float normal[3], float eta);
+
 /* shaded view and bake */
 struct Render;
 struct Image;
diff --git a/source/blender/render/intern/include/shading.h 
b/source/blender/render/intern/include/shading.h
index 27867ea..13f16ce 100644
--- a/source/blender/render/intern/include/shading.h
+++ b/source/blender/render/intern/include/shading.h
@@ -99,7 +99,7 @@ ListBase *get_lights(struct ShadeInput *shi);
 float lamp_get_visibility(struct LampRen *lar, const float co[3], float lv[3], 
float *dist);
 void lamp_get_shadow(struct LampRen *lar, ShadeInput *shi, float inp, float 
shadfac[4], int do_real);
 
-float  fresnel_fac(const float view[3], const float vn[3], float fresnel, 
float fac);
+float fresnel_fac(const float view[3], const float vn[3], float fresnel, float 
fac);
 
 /* rayshade.c */
 extern void shade_ray(struct Isect *is, struct ShadeInput *shi, struct 
ShadeResult *shr);
diff --git a/source/blender/render/intern/source/shadeoutput.c 
b/source/blender/render/intern/source/shadeoutput.c
index 3d6462e..c4de95e 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -2151,3 +2151,24 @@ const float (*RE_render_current_get_matrix(int 
matrix_id))[4]
        }
        return NULL;
 }
+
+float RE_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;
+}
\ No newline at end of file

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to