[Bf-blender-cvs] [bd5da19] master: Cycles: Add a "Normal" input socket to the Layer Weight node + GLSL drawing code.

Thomas Dinges noreply at git.blender.org
Fri Nov 22 00:34:28 CET 2013


Commit: bd5da19d86e5c490e4945bb4befc50b6eac48a86
Author: Thomas Dinges
Date:   Fri Nov 22 00:33:28 2013 +0100
http://developer.blender.org/rBbd5da19d86e5c490e4945bb4befc50b6eac48a86

Cycles: Add a "Normal" input socket to the Layer Weight node + GLSL drawing code.

Patch by lichtwerk (Philipp Oeser).

Differential Revision: http://developer.blender.org/D28

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

M	intern/cycles/kernel/svm/svm_fresnel.h
M	intern/cycles/render/nodes.cpp
M	source/blender/gpu/shaders/gpu_shader_material.glsl
M	source/blender/nodes/shader/nodes/node_shader_layer_weight.c

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

diff --git a/intern/cycles/kernel/svm/svm_fresnel.h b/intern/cycles/kernel/svm/svm_fresnel.h
index bb70a3f..0a3d576 100644
--- a/intern/cycles/kernel/svm/svm_fresnel.h
+++ b/intern/cycles/kernel/svm/svm_fresnel.h
@@ -39,10 +39,12 @@ ccl_device void svm_node_layer_weight(ShaderData *sd, float *stack, uint4 node)
 {
 	uint blend_offset = node.y;
 	uint blend_value = node.z;
-	float blend = (stack_valid(blend_offset))? stack_load_float(stack, blend_offset): __uint_as_float(blend_value);
 
-	uint type, out_offset;
-	decode_node_uchar4(node.w, &type, &out_offset, NULL, NULL);
+	uint type, normal_offset, out_offset;
+	decode_node_uchar4(node.w, &type, &normal_offset, &out_offset, NULL);
+
+	float blend = (stack_valid(blend_offset))? stack_load_float(stack, blend_offset): __uint_as_float(blend_value);
+	float3 normal_in = (stack_valid(normal_offset))? stack_load_float3(stack, normal_offset): sd->N;
 
 	float f;
 
@@ -50,10 +52,10 @@ ccl_device void svm_node_layer_weight(ShaderData *sd, float *stack, uint4 node)
 		float eta = fmaxf(1.0f - blend, 1e-5f);
 		eta = (sd->flag & SD_BACKFACING)? eta: 1.0f/eta;
 
-		f = fresnel_dielectric_cos(dot(sd->I, sd->N), eta);
+		f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta);
 	}
 	else {
-		f = fabsf(dot(sd->I, sd->N));
+		f = fabsf(dot(sd->I, normal_in));
 
 		if(blend != 0.5f) {
 			blend = clamp(blend, 0.0f, 1.0f-1e-5f);
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 4919222..daf75c8 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -3198,8 +3198,12 @@ LayerWeightNode::LayerWeightNode()
 
 void LayerWeightNode::compile(SVMCompiler& compiler)
 {
+	ShaderInput *normal_in = input("Normal");
 	ShaderInput *blend_in = input("Blend");
 
+	if(normal_in->link)
+		compiler.stack_assign(normal_in);
+
 	if(blend_in->link)
 		compiler.stack_assign(blend_in);
 
@@ -3207,14 +3211,14 @@ void LayerWeightNode::compile(SVMCompiler& compiler)
 	if(!fresnel_out->links.empty()) {
 		compiler.stack_assign(fresnel_out);
 		compiler.add_node(NODE_LAYER_WEIGHT, blend_in->stack_offset, __float_as_int(blend_in->value.x),
-			compiler.encode_uchar4(NODE_LAYER_WEIGHT_FRESNEL, fresnel_out->stack_offset));
+			compiler.encode_uchar4(NODE_LAYER_WEIGHT_FRESNEL, normal_in->stack_offset, fresnel_out->stack_offset));
 	}
 
 	ShaderOutput *facing_out = output("Facing");
 	if(!facing_out->links.empty()) {
 		compiler.stack_assign(facing_out);
 		compiler.add_node(NODE_LAYER_WEIGHT, blend_in->stack_offset, __float_as_int(blend_in->value.x),
-			compiler.encode_uchar4(NODE_LAYER_WEIGHT_FACING, facing_out->stack_offset));
+			compiler.encode_uchar4(NODE_LAYER_WEIGHT_FACING, normal_in->stack_offset, facing_out->stack_offset));
 	}
 }
 
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index b2c7c2e..f5881cd 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -2159,6 +2159,24 @@ void node_fresnel(float ior, vec3 N, vec3 I, out float result)
 	result = fresnel_dielectric(normalize(I), N, (gl_FrontFacing)? eta: 1.0/eta);
 }
 
+/* layer_weight */
+
+void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float facing)
+{
+	/* fresnel */
+	float eta = max(1.0 - blend, 0.00001);
+	fresnel = fresnel_dielectric(normalize(I), N, (gl_FrontFacing)? 1.0/eta : eta );
+
+	/* facing */
+	facing = abs(dot(normalize(I), N));
+	if(blend != 0.5) {
+		blend = clamp(blend, 0.0, 0.99999);
+		blend = (blend < 0.5)? 2.0*blend: 0.5/(1.0 - blend);
+		facing = pow(facing, blend);
+	}
+	facing = 1.0 - facing;
+}
+
 /* gamma */
 
 void node_gamma(vec4 col, float gamma, out vec4 outcol)
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 9b9c3cf..832ce58 100644
--- a/source/blender/nodes/shader/nodes/node_shader_layer_weight.c
+++ b/source/blender/nodes/shader/nodes/node_shader_layer_weight.c
@@ -31,6 +31,7 @@
 
 static bNodeSocketTemplate sh_node_layer_weight_in[] = {
 	{	SOCK_FLOAT, 1, N_("Blend"),		0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+	{	SOCK_VECTOR, 1, N_("Normal"),	0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
 	{	-1, 0, ""	}
 };
 
@@ -40,9 +41,12 @@ static bNodeSocketTemplate sh_node_layer_weight_out[] = {
 	{	-1, 0, ""	}
 };
 
-static int node_shader_gpu_layer_weight(GPUMaterial *UNUSED(mat), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *UNUSED(in), GPUNodeStack *UNUSED(out))
+static int node_shader_gpu_layer_weight(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
 {
-	return 0;
+	if (!in[1].link)
+		in[1].link = GPU_builtin(GPU_VIEW_NORMAL);
+
+	return GPU_stack_link(mat, "node_layer_weight", in, out, GPU_builtin(GPU_VIEW_POSITION));
 }
 
 /* node type definition */




More information about the Bf-blender-cvs mailing list