lyapunov_texture.osl 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * Copyright 2013, Blender Foundation.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software Foundation,
  16. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. */
  18. /*
  19. * Lyapunov Shader - in memory of great mathematician Aleksandr Mikhailovich Lyapunov
  20. * Original code: Sylvio Sell - maitag.de - Rostock Germany 2013
  21. * OSL port by Thomas Dinges
  22. * More information: https://developer.blender.org/T32305
  23. */
  24. /* Fac_Type
  25. * 0, SPREAD, Spread indices for fac output
  26. * 1, ABS, Absolute values from indices
  27. * 2, COLOR, Get fac output from used colors
  28. * 3, REAL, Real indices
  29. */
  30. /* Render_Type
  31. * 0, NEG, Negative Lyapunov indices only
  32. * 1, POS, Positive Lyapunov indices only
  33. * 2, ALL, Positive and negative indices
  34. */
  35. float lyapunov(point p, float iteration_pre, float iteration_main, float p1, float p2)
  36. {
  37. /* Coordinates */
  38. float a = p[0];
  39. float b = p[1];
  40. float c = p[2];
  41. int iter_pre = (int)floor(iteration_pre);
  42. int iter_main = (int)floor(iteration_main);
  43. float nabla_pre = iteration_pre - (float)iter_pre;
  44. float nabla_main = iteration_main - (float)iter_main;
  45. float x = 0.0;
  46. float index = 0.0;
  47. float derivation = 0.0;
  48. int iter = 0;
  49. /* Pre-iteration */
  50. for (int i = 0; i < iter_pre; i++) {
  51. x = p1 * sin(x + a) * sin(x + a) + p2;
  52. x = p1 * sin(x + b) * sin(x + b) + p2;
  53. x = p1 * sin(x + c) * sin(x + c) + p2;
  54. }
  55. if (nabla_pre != 0.0) {
  56. float x_pre = x;
  57. x = p1 * sin(x + a) * sin(x + a) + p2;
  58. x = p1 * sin(x + b) * sin(x + b) + p2;
  59. x = p1 * sin(x + c) * sin(x + c) + p2;
  60. x = x * nabla_pre + x_pre * (1.0 - nabla_pre);
  61. }
  62. /* Main-iteration */
  63. for (int i = 0; i < iter_main; i++) {
  64. x = p1 * sin(x + a) * sin(x + a) + p2;
  65. derivation = 2.0 *p1 *sin(x + a) * cos(x + a);
  66. if (derivation != 0.0) { index += log(fabs(derivation)); iter++; }
  67. x = p1 * sin(x + b) * sin(x + b) + p2;
  68. derivation = 2.0 *p1 *sin(x + b) * cos(x + b);
  69. if (derivation != 0.0) { index += log(fabs(derivation)); iter++; }
  70. x = p1 * sin(x + c) * sin(x + c) + p2;
  71. derivation = 2.0 *p1 *sin(x + c) * cos(x + c);
  72. if (derivation != 0.0) { index += log(fabs(derivation)); iter++; }
  73. }
  74. if (nabla_main == 0.0) {
  75. index = (iter != 0) ? index / (float)(iter) : 0.0;
  76. }
  77. else {
  78. float index_pre = (iter != 0) ? index / (float)(iter) : 0.0;
  79. x = p1 * sin(x + a) * sin(x + a) + p2;
  80. derivation = 2.0 *p1 *sin(x + a) * cos(x + a);
  81. if (derivation != 0.0) { index += log(fabs(derivation)); iter++; }
  82. x = p1 * sin(x + b) * sin(x + b) + p2;
  83. derivation = 2.0 *p1 *sin(x + b) * cos(x + b);
  84. if (derivation != 0.0) { index += log(fabs(derivation)); iter++; }
  85. x = p1 * sin(x + c) * sin(x + c) + p2;
  86. derivation = 2.0 *p1 *sin(x + c) * cos(x + c);
  87. if (derivation != 0.0) { index += log(fabs(derivation)); iter++; }
  88. index = (iter != 0) ? index / (float)(iter) : 0.0;
  89. index = index * nabla_main + index_pre * (1.0 - nabla_main);
  90. }
  91. return index;
  92. }
  93. shader node_lyapunov(
  94. color Pos_Color = color(1.0, 0.0, 0.0),
  95. color Mid_Color = color(0.0, 0.0, 0.0),
  96. color Neg_Color = color(0.0, 0.0, 1.0),
  97. float Pre_Iteration = 0.0,
  98. float Main_Iteration = 1.0,
  99. float Pos_Scale = 0.5,
  100. float Neg_Scale = 0.5,
  101. float Param1 = 2.0,
  102. float Param2 = 2.0,
  103. int Fac_Type = 0,
  104. int Render_Type = 2,
  105. float Scale = 0.25,
  106. point Pos = P,
  107. output float Fac = 0.0,
  108. output color Color = 0.0)
  109. {
  110. /* Calculate Texture */
  111. float index = lyapunov(Pos * Scale, Pre_Iteration, Main_Iteration, Param1, Param2);
  112. /* Calculate Color */
  113. if (index > 0.0 && (Render_Type != 0)) {
  114. index *= Pos_Scale;
  115. if (index > 1.0) { index = 1.0; }
  116. Color = (Pos_Color - Mid_Color) * index + Mid_Color;
  117. }
  118. else if (index < 0.0 && (Render_Type != 1)) {
  119. index *= Neg_Scale;
  120. if (index < -1.0) { index = -1.0; }
  121. Color = (Mid_Color - Neg_Color) * index + Mid_Color;
  122. }
  123. else {
  124. Color = Mid_Color;
  125. }
  126. /* Adjust Index */
  127. if (Fac_Type == 0) {
  128. index = 0.5 + index * 0.5;
  129. }
  130. else if (Fac_Type == 1) {
  131. index = fabs(index);
  132. }
  133. else if (Fac_Type == 2) {
  134. index = (Color[0] + Color[1] + Color[2]) * (1.0 / 3.0);
  135. }
  136. Fac = index;
  137. }