diff options
author | Lukas Stockner <lukas.stockner@freenet.de> | 2016-07-16 21:48:12 +0300 |
---|---|---|
committer | Lukas Stockner <lukas.stockner@freenet.de> | 2016-07-16 21:54:14 +0300 |
commit | d9281a6332d2273356e0d3d042d64157fb7d06c8 (patch) | |
tree | 7209bbec482e73e77a08e5c3f70e1cd538ee9537 /intern/cycles/kernel/svm/svm_tex_coord.h | |
parent | 5ba78d76d4836fa2a8f9d8cef6c448ebd792170f (diff) |
Cycles: Fix three numerical issues in the fresnel, normal map and Beckmann code
- In fresnel_dielectric, the differentials calculation sometimes divided by zero.
- When the normal map was (0.5, 0.5, 0.5), the code would try to normalize a zero vector. Now, it just uses the regular normal as a fallback.
- The approximate error function used in Beckmann sampling sometimes overflowed to inf while calculating r^16. The final value is 1 - 1/r^16, however,
so now it just returns 1 if the computation would overflow otherwise.
Diffstat (limited to 'intern/cycles/kernel/svm/svm_tex_coord.h')
-rw-r--r-- | intern/cycles/kernel/svm/svm_tex_coord.h | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index 27fed89fdf7..0bac8362011 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -312,7 +312,7 @@ ccl_device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *st /* apply normal map */ float3 B = sign * cross(normal, tangent); - N = normalize(color.x * tangent + color.y * B + color.z * normal); + N = safe_normalize(color.x * tangent + color.y * B + color.z * normal); /* transform to world space */ object_normal_transform(kg, sd, &N); @@ -330,14 +330,18 @@ ccl_device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *st if(space == NODE_NORMAL_MAP_OBJECT || space == NODE_NORMAL_MAP_BLENDER_OBJECT) object_normal_transform(kg, sd, &N); else - N = normalize(N); + N = safe_normalize(N); } float strength = stack_load_float(stack, strength_offset); if(strength != 1.0f) { strength = max(strength, 0.0f); - N = normalize(ccl_fetch(sd, N) + (N - ccl_fetch(sd, N))*strength); + N = safe_normalize(ccl_fetch(sd, N) + (N - ccl_fetch(sd, N))*strength); + } + + if(N == make_float3(0.0f, 0.0f, 0.0f)) { + N = ccl_fetch(sd, N); } stack_store_float3(stack, normal_offset, N); |