svm_fresnel.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. * Copyright 2011-2013 Blender Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. CCL_NAMESPACE_BEGIN
  17. /* Fresnel Node */
  18. ccl_device void svm_node_fresnel(
  19. ShaderData *sd, float *stack, uint ior_offset, uint ior_value, uint node)
  20. {
  21. uint normal_offset, out_offset;
  22. decode_node_uchar4(node, &normal_offset, &out_offset, NULL, NULL);
  23. float eta = (stack_valid(ior_offset)) ? stack_load_float(stack, ior_offset) :
  24. __uint_as_float(ior_value);
  25. float3 normal_in = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N;
  26. eta = fmaxf(eta, 1e-5f);
  27. eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
  28. float f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta);
  29. stack_store_float(stack, out_offset, f);
  30. }
  31. /* Layer Weight Node */
  32. ccl_device void svm_node_layer_weight(ShaderData *sd, float *stack, uint4 node)
  33. {
  34. uint blend_offset = node.y;
  35. uint blend_value = node.z;
  36. uint type, normal_offset, out_offset;
  37. decode_node_uchar4(node.w, &type, &normal_offset, &out_offset, NULL);
  38. float blend = (stack_valid(blend_offset)) ? stack_load_float(stack, blend_offset) :
  39. __uint_as_float(blend_value);
  40. float3 normal_in = (stack_valid(normal_offset)) ? stack_load_float3(stack, normal_offset) :
  41. sd->N;
  42. float f;
  43. if (type == NODE_LAYER_WEIGHT_FRESNEL) {
  44. float eta = fmaxf(1.0f - blend, 1e-5f);
  45. eta = (sd->flag & SD_BACKFACING) ? eta : 1.0f / eta;
  46. f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta);
  47. }
  48. else {
  49. f = fabsf(dot(sd->I, normal_in));
  50. if (blend != 0.5f) {
  51. blend = clamp(blend, 0.0f, 1.0f - 1e-5f);
  52. blend = (blend < 0.5f) ? 2.0f * blend : 0.5f / (1.0f - blend);
  53. f = powf(f, blend);
  54. }
  55. f = 1.0f - f;
  56. }
  57. stack_store_float(stack, out_offset, f);
  58. }
  59. CCL_NAMESPACE_END