diff options
-rw-r--r-- | intern/cycles/kernel/svm/svm_fresnel.h | 8 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 7 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_material.glsl | 2 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_fresnel.c | 7 |
4 files changed, 18 insertions, 6 deletions
diff --git a/intern/cycles/kernel/svm/svm_fresnel.h b/intern/cycles/kernel/svm/svm_fresnel.h index 549c0351d83..d97d6a3738f 100644 --- a/intern/cycles/kernel/svm/svm_fresnel.h +++ b/intern/cycles/kernel/svm/svm_fresnel.h @@ -18,13 +18,17 @@ CCL_NAMESPACE_BEGIN /* Fresnel Node */ -__device void svm_node_fresnel(ShaderData *sd, float *stack, uint ior_offset, uint ior_value, uint out_offset) +__device void svm_node_fresnel(ShaderData *sd, float *stack, uint ior_offset, uint ior_value, uint node) { + uint normal_offset, out_offset; + decode_node_uchar4(node, &normal_offset, &out_offset, NULL, NULL); float eta = (stack_valid(ior_offset))? stack_load_float(stack, ior_offset): __uint_as_float(ior_value); + float3 normal_in = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): sd->N; + eta = fmaxf(eta, 1.0f + 1e-5f); eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta; - float f = fresnel_dielectric_cos(dot(sd->I, sd->N), eta); + float f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta); stack_store_float(stack, out_offset, f); } diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 5352840d2cb..4919222e81c 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -3166,12 +3166,17 @@ FresnelNode::FresnelNode() void FresnelNode::compile(SVMCompiler& compiler) { + ShaderInput *normal_in = input("Normal"); ShaderInput *ior_in = input("IOR"); ShaderOutput *fac_out = output("Fac"); compiler.stack_assign(ior_in); compiler.stack_assign(fac_out); - compiler.add_node(NODE_FRESNEL, ior_in->stack_offset, __float_as_int(ior_in->value.x), fac_out->stack_offset); + + if(normal_in->link) + compiler.stack_assign(normal_in); + + compiler.add_node(NODE_FRESNEL, ior_in->stack_offset, __float_as_int(ior_in->value.x), compiler.encode_uchar4(normal_in->stack_offset, fac_out->stack_offset)); } void FresnelNode::compile(OSLCompiler& compiler) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 633112095a7..78664f3b539 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -2131,7 +2131,7 @@ void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader) void node_fresnel(float ior, vec3 N, vec3 I, out float result) { float eta = max(ior, 0.00001); - result = fresnel_dielectric(I, N, (gl_FrontFacing)? eta: 1.0/eta); + result = fresnel_dielectric(normalize(I), N, (gl_FrontFacing)? eta: 1.0/eta); } /* gamma */ diff --git a/source/blender/nodes/shader/nodes/node_shader_fresnel.c b/source/blender/nodes/shader/nodes/node_shader_fresnel.c index 1e5c10968a5..c22b0f41695 100644 --- a/source/blender/nodes/shader/nodes/node_shader_fresnel.c +++ b/source/blender/nodes/shader/nodes/node_shader_fresnel.c @@ -30,6 +30,7 @@ /* **************** Fresnel ******************** */ static bNodeSocketTemplate sh_node_fresnel_in[] = { { SOCK_FLOAT, 1, N_("IOR"), 1.45f, 0.0f, 0.0f, 0.0f, 1.0f, 1000.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,8 +41,10 @@ static bNodeSocketTemplate sh_node_fresnel_out[] = { static int node_shader_gpu_fresnel(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { - /* todo: is incoming vector normalized? */ - return GPU_stack_link(mat, "node_fresnel", in, out, GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_VIEW_POSITION)); + if (!in[1].link) + in[1].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_fresnel", in, out, GPU_builtin(GPU_VIEW_POSITION)); } /* node type definition */ |