svm_musgrave.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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. /* Musgrave fBm
  18. *
  19. * H: fractal increment parameter
  20. * lacunarity: gap between successive frequencies
  21. * octaves: number of frequencies in the fBm
  22. *
  23. * from "Texturing and Modelling: A procedural approach"
  24. */
  25. ccl_device_noinline float noise_musgrave_fBm(float3 p, float H, float lacunarity, float octaves)
  26. {
  27. float rmd;
  28. float value = 0.0f;
  29. float pwr = 1.0f;
  30. float pwHL = powf(lacunarity, -H);
  31. int i;
  32. for (i = 0; i < float_to_int(octaves); i++) {
  33. value += snoise(p) * pwr;
  34. pwr *= pwHL;
  35. p *= lacunarity;
  36. }
  37. rmd = octaves - floorf(octaves);
  38. if (rmd != 0.0f)
  39. value += rmd * snoise(p) * pwr;
  40. return value;
  41. }
  42. /* Musgrave Multifractal
  43. *
  44. * H: highest fractal dimension
  45. * lacunarity: gap between successive frequencies
  46. * octaves: number of frequencies in the fBm
  47. */
  48. ccl_device_noinline float noise_musgrave_multi_fractal(float3 p,
  49. float H,
  50. float lacunarity,
  51. float octaves)
  52. {
  53. float rmd;
  54. float value = 1.0f;
  55. float pwr = 1.0f;
  56. float pwHL = powf(lacunarity, -H);
  57. int i;
  58. for (i = 0; i < float_to_int(octaves); i++) {
  59. value *= (pwr * snoise(p) + 1.0f);
  60. pwr *= pwHL;
  61. p *= lacunarity;
  62. }
  63. rmd = octaves - floorf(octaves);
  64. if (rmd != 0.0f)
  65. value *= (rmd * pwr * snoise(p) + 1.0f); /* correct? */
  66. return value;
  67. }
  68. /* Musgrave Heterogeneous Terrain
  69. *
  70. * H: fractal dimension of the roughest area
  71. * lacunarity: gap between successive frequencies
  72. * octaves: number of frequencies in the fBm
  73. * offset: raises the terrain from `sea level'
  74. */
  75. ccl_device_noinline float noise_musgrave_hetero_terrain(
  76. float3 p, float H, float lacunarity, float octaves, float offset)
  77. {
  78. float value, increment, rmd;
  79. float pwHL = powf(lacunarity, -H);
  80. float pwr = pwHL;
  81. int i;
  82. /* first unscaled octave of function; later octaves are scaled */
  83. value = offset + snoise(p);
  84. p *= lacunarity;
  85. for (i = 1; i < float_to_int(octaves); i++) {
  86. increment = (snoise(p) + offset) * pwr * value;
  87. value += increment;
  88. pwr *= pwHL;
  89. p *= lacunarity;
  90. }
  91. rmd = octaves - floorf(octaves);
  92. if (rmd != 0.0f) {
  93. increment = (snoise(p) + offset) * pwr * value;
  94. value += rmd * increment;
  95. }
  96. return value;
  97. }
  98. /* Hybrid Additive/Multiplicative Multifractal Terrain
  99. *
  100. * H: fractal dimension of the roughest area
  101. * lacunarity: gap between successive frequencies
  102. * octaves: number of frequencies in the fBm
  103. * offset: raises the terrain from `sea level'
  104. */
  105. ccl_device_noinline float noise_musgrave_hybrid_multi_fractal(
  106. float3 p, float H, float lacunarity, float octaves, float offset, float gain)
  107. {
  108. float result, signal, weight, rmd;
  109. float pwHL = powf(lacunarity, -H);
  110. float pwr = pwHL;
  111. int i;
  112. result = snoise(p) + offset;
  113. weight = gain * result;
  114. p *= lacunarity;
  115. for (i = 1; (weight > 0.001f) && (i < float_to_int(octaves)); i++) {
  116. if (weight > 1.0f)
  117. weight = 1.0f;
  118. signal = (snoise(p) + offset) * pwr;
  119. pwr *= pwHL;
  120. result += weight * signal;
  121. weight *= gain * signal;
  122. p *= lacunarity;
  123. }
  124. rmd = octaves - floorf(octaves);
  125. if (rmd != 0.0f)
  126. result += rmd * ((snoise(p) + offset) * pwr);
  127. return result;
  128. }
  129. /* Ridged Multifractal Terrain
  130. *
  131. * H: fractal dimension of the roughest area
  132. * lacunarity: gap between successive frequencies
  133. * octaves: number of frequencies in the fBm
  134. * offset: raises the terrain from `sea level'
  135. */
  136. ccl_device_noinline float noise_musgrave_ridged_multi_fractal(
  137. float3 p, float H, float lacunarity, float octaves, float offset, float gain)
  138. {
  139. float result, signal, weight;
  140. float pwHL = powf(lacunarity, -H);
  141. float pwr = pwHL;
  142. int i;
  143. signal = offset - fabsf(snoise(p));
  144. signal *= signal;
  145. result = signal;
  146. weight = 1.0f;
  147. for (i = 1; i < float_to_int(octaves); i++) {
  148. p *= lacunarity;
  149. weight = saturate(signal * gain);
  150. signal = offset - fabsf(snoise(p));
  151. signal *= signal;
  152. signal *= weight;
  153. result += signal * pwr;
  154. pwr *= pwHL;
  155. }
  156. return result;
  157. }
  158. /* Shader */
  159. ccl_device float svm_musgrave(NodeMusgraveType type,
  160. float dimension,
  161. float lacunarity,
  162. float octaves,
  163. float offset,
  164. float intensity,
  165. float gain,
  166. float3 p)
  167. {
  168. if (type == NODE_MUSGRAVE_MULTIFRACTAL)
  169. return intensity * noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves);
  170. else if (type == NODE_MUSGRAVE_FBM)
  171. return intensity * noise_musgrave_fBm(p, dimension, lacunarity, octaves);
  172. else if (type == NODE_MUSGRAVE_HYBRID_MULTIFRACTAL)
  173. return intensity *
  174. noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
  175. else if (type == NODE_MUSGRAVE_RIDGED_MULTIFRACTAL)
  176. return intensity *
  177. noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
  178. else if (type == NODE_MUSGRAVE_HETERO_TERRAIN)
  179. return intensity * noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, offset);
  180. return 0.0f;
  181. }
  182. ccl_device void svm_node_tex_musgrave(
  183. KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
  184. {
  185. uint4 node2 = read_node(kg, offset);
  186. uint4 node3 = read_node(kg, offset);
  187. uint type, co_offset, color_offset, fac_offset;
  188. uint dimension_offset, lacunarity_offset, detail_offset, offset_offset;
  189. uint gain_offset, scale_offset;
  190. decode_node_uchar4(node.y, &type, &co_offset, &color_offset, &fac_offset);
  191. decode_node_uchar4(
  192. node.z, &dimension_offset, &lacunarity_offset, &detail_offset, &offset_offset);
  193. decode_node_uchar4(node.w, &gain_offset, &scale_offset, NULL, NULL);
  194. float3 co = stack_load_float3(stack, co_offset);
  195. float dimension = stack_load_float_default(stack, dimension_offset, node2.x);
  196. float lacunarity = stack_load_float_default(stack, lacunarity_offset, node2.y);
  197. float detail = stack_load_float_default(stack, detail_offset, node2.z);
  198. float foffset = stack_load_float_default(stack, offset_offset, node2.w);
  199. float gain = stack_load_float_default(stack, gain_offset, node3.x);
  200. float scale = stack_load_float_default(stack, scale_offset, node3.y);
  201. dimension = fmaxf(dimension, 1e-5f);
  202. detail = clamp(detail, 0.0f, 16.0f);
  203. lacunarity = fmaxf(lacunarity, 1e-5f);
  204. float f = svm_musgrave(
  205. (NodeMusgraveType)type, dimension, lacunarity, detail, foffset, 1.0f, gain, co * scale);
  206. if (stack_valid(fac_offset))
  207. stack_store_float(stack, fac_offset, f);
  208. if (stack_valid(color_offset))
  209. stack_store_float3(stack, color_offset, make_float3(f, f, f));
  210. }
  211. CCL_NAMESPACE_END