1. /*
    2. * Hagelslag.osl by Michel J. Anders (c)2012
    3. * from https://github.com/sambler/osl-shaders
    4. *
    5. * license: cc-by-sa
    6. *
    7. * original script from -
    8. * http://blenderthings.blogspot.com.au/2012/12/a-hagelslag-sprinkles-osl-shader-for.html
    9. *
    10. *
    11. * In blender's homeland hagelslag is the name used for sprinkles.
    12. * Enjoy sprinkling blender's hagelslag on all your materials
    13. * to make them as delicious as can be ;)
    14. * Modified 1/4/2020 by Saul Espinosa for Redshift 3D
    15. */
    16. // replacement for the missing distance(a, b, q) function
    17. float minimum_distance(point v, point w, point p) {
    18. vector s = w - v;
    19. float l2 = dot(s,s);
    20. if (l2 == 0.0) return distance(p, v);
    21. float t = dot(p - v, s) / l2;
    22. if (t < 0.0) return distance(p, v);
    23. else if (t > 1.0) return distance(p, w);
    24. vector projection = v + t * (s);
    25. return distance(p, projection);
    26. }
    27. shader MAHagelslag
    28. [[ string help = "Hagelslag Noise Pattern",
    29. string label = "Hagelslag Noise" ]]
    30. (
    31. vector Vector = P,
    32. float Scale = 1.0
    33. [[
    34. float min = 0, float max = 25
    35. ]],
    36. int Density = 1
    37. [[
    38. float min = 0, float max = 25
    39. ]],
    40. int Seed = 0
    41. [[
    42. int min = 0, int max = 100
    43. ]],
    44. float Radius = 0.05
    45. [[
    46. float min = 0, float max = 1
    47. ]],
    48. float Size = 1.0
    49. [[
    50. float min = 0, float max = 25
    51. ]],
    52. output float Fac = 0 )
    53. {
    54. point p = Vector * Scale;
    55. point f = floor(p);
    56. int xx,yy,np;
    57. vector one = 1;
    58. for( xx=-1; xx<=1; xx++){
    59. for( yy=-1; yy<=1; yy++){
    60. point ff = f + vector(xx,yy,0);
    61. vector dp = vector(5,7,11);
    62. for( np=0; np < Density; np++){
    63. vector pd1 = 2*cellnoise(ff+dp)-one;
    64. vector pd2 = 2*cellnoise(ff+dp+Seed)-one;
    65. dp *= 17;
    66. point p1 = ff + pd1;
    67. point p2 = ff + pd2;
    68. p2 = (p2 - p1)*Size+p1;
    69. // reduce to 2D
    70. p1[2]=0;
    71. p2[2]=0;
    72. p [2]=0;
    73. float r = minimum_distance(p1,p2,p);
    74. if ( r < Radius ) {
    75. Fac = 1 - r/Radius;
    76. }
    77. }
    78. }
    79. }
    80. }