svm_brick.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. /* Brick */
  18. ccl_device_noinline float brick_noise(uint n) /* fast integer noise */
  19. {
  20. uint nn;
  21. n = (n + 1013) & 0x7fffffff;
  22. n = (n >> 13) ^ n;
  23. nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
  24. return 0.5f * ((float)nn / 1073741824.0f);
  25. }
  26. ccl_device_noinline float2 svm_brick(float3 p,
  27. float mortar_size,
  28. float mortar_smooth,
  29. float bias,
  30. float brick_width,
  31. float row_height,
  32. float offset_amount,
  33. int offset_frequency,
  34. float squash_amount,
  35. int squash_frequency)
  36. {
  37. int bricknum, rownum;
  38. float offset = 0.0f;
  39. float x, y;
  40. rownum = floor_to_int(p.y / row_height);
  41. if (offset_frequency && squash_frequency) {
  42. brick_width *= (rownum % squash_frequency) ? 1.0f : squash_amount; /* squash */
  43. offset = (rownum % offset_frequency) ? 0.0f : (brick_width * offset_amount); /* offset */
  44. }
  45. bricknum = floor_to_int((p.x + offset) / brick_width);
  46. x = (p.x + offset) - brick_width * bricknum;
  47. y = p.y - row_height * rownum;
  48. float tint = saturate((brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias));
  49. float min_dist = min(min(x, y), min(brick_width - x, row_height - y));
  50. float mortar;
  51. if (min_dist >= mortar_size) {
  52. mortar = 0.0f;
  53. }
  54. else if (mortar_smooth == 0.0f) {
  55. mortar = 1.0f;
  56. }
  57. else {
  58. min_dist = 1.0f - min_dist / mortar_size;
  59. mortar = (min_dist < mortar_smooth) ? smoothstepf(min_dist / mortar_smooth) : 1.0f;
  60. }
  61. return make_float2(tint, mortar);
  62. }
  63. ccl_device void svm_node_tex_brick(
  64. KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
  65. {
  66. uint4 node2 = read_node(kg, offset);
  67. uint4 node3 = read_node(kg, offset);
  68. uint4 node4 = read_node(kg, offset);
  69. /* Input and Output Sockets */
  70. uint co_offset, color1_offset, color2_offset, mortar_offset, scale_offset;
  71. uint mortar_size_offset, bias_offset, brick_width_offset, row_height_offset;
  72. uint color_offset, fac_offset, mortar_smooth_offset;
  73. /* RNA properties */
  74. uint offset_frequency, squash_frequency;
  75. decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &mortar_offset);
  76. decode_node_uchar4(
  77. node.z, &scale_offset, &mortar_size_offset, &bias_offset, &brick_width_offset);
  78. decode_node_uchar4(
  79. node.w, &row_height_offset, &color_offset, &fac_offset, &mortar_smooth_offset);
  80. decode_node_uchar4(node2.x, &offset_frequency, &squash_frequency, NULL, NULL);
  81. float3 co = stack_load_float3(stack, co_offset);
  82. float3 color1 = stack_load_float3(stack, color1_offset);
  83. float3 color2 = stack_load_float3(stack, color2_offset);
  84. float3 mortar = stack_load_float3(stack, mortar_offset);
  85. float scale = stack_load_float_default(stack, scale_offset, node2.y);
  86. float mortar_size = stack_load_float_default(stack, mortar_size_offset, node2.z);
  87. float mortar_smooth = stack_load_float_default(stack, mortar_smooth_offset, node4.x);
  88. float bias = stack_load_float_default(stack, bias_offset, node2.w);
  89. float brick_width = stack_load_float_default(stack, brick_width_offset, node3.x);
  90. float row_height = stack_load_float_default(stack, row_height_offset, node3.y);
  91. float offset_amount = __int_as_float(node3.z);
  92. float squash_amount = __int_as_float(node3.w);
  93. float2 f2 = svm_brick(co * scale,
  94. mortar_size,
  95. mortar_smooth,
  96. bias,
  97. brick_width,
  98. row_height,
  99. offset_amount,
  100. offset_frequency,
  101. squash_amount,
  102. squash_frequency);
  103. float tint = f2.x;
  104. float f = f2.y;
  105. if (f != 1.0f) {
  106. float facm = 1.0f - tint;
  107. color1 = facm * color1 + tint * color2;
  108. }
  109. if (stack_valid(color_offset))
  110. stack_store_float3(stack, color_offset, color1 * (1.0f - f) + mortar * f);
  111. if (stack_valid(fac_offset))
  112. stack_store_float(stack, fac_offset, f);
  113. }
  114. CCL_NAMESPACE_END