wind_bending.glslv 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #ifndef WIND_BENDING_GLSLV
  2. #define WIND_BENDING_GLSLV
  3. // #import a_bending_col_detail a_bending_col_main a_emitter_center
  4. // #import au_detail_bending_amp au_branch_bending_amp au_wind_bending_amp \
  5. // au_wind_bending_freq au_detail_bending_freq
  6. // #import u_wind u_time
  7. /*==============================================================================
  8. VARS
  9. ==============================================================================*/
  10. #var WIND_BEND 0
  11. #var MAIN_BEND_COL 0
  12. #var DETAIL_BEND 0
  13. #var BEND_CENTER_ONLY 0
  14. #var REFLECTION_PASS REFL_PASS_NONE
  15. #var BILLBOARD 0
  16. /*============================================================================*/
  17. #include <std.glsl>
  18. #if WIND_BEND
  19. void main_bend(inout vec3 pos_world,
  20. in vec3 center_world,
  21. in float wind_bending_amp,
  22. in float wind_bending_freq,
  23. in float time,
  24. in vec3 wind_world,
  25. in float bend_stiffness,
  26. in mat4 view_refl_matrix) {
  27. // http://http.developer.nvidia.com/GPUGems3/gpugems3_ch16.html
  28. # if REFLECTION_PASS == REFL_PASS_PLANE && BILLBOARD
  29. vec3 pw = (view_refl_matrix * vec4(pos_world, 1.0)).xyz;
  30. vec3 cw = (view_refl_matrix * vec4(center_world, 1.0)).xyz;
  31. # else
  32. vec3 pw = pos_world;
  33. vec3 cw = center_world;
  34. # endif
  35. // calc and smooth bend factor
  36. float phase = length(cw);
  37. float freq = wind_bending_freq * (1.0 + 0.1 * fract(phase)); // add some random variations
  38. float bend_scale = wind_bending_amp * bend_stiffness *
  39. (1.0 + sin(2.0*3.14 * time * freq + phase));
  40. float bf = (pw.z - cw.z) * abs(bend_scale);
  41. bf += 1.0;
  42. bf *= bf;
  43. bf = bf * bf - bf;
  44. // calculate bend
  45. vec3 pos_bend = pw;
  46. pos_bend.xy += wind_world.xy * bf * sign(bend_scale);
  47. vec3 bend_diff = pos_bend - cw;
  48. // NOTE: avoid normalizing issues
  49. if (all(equal(bend_diff, vec3(0.0))))
  50. pos_world = center_world;
  51. else {
  52. # if REFLECTION_PASS == REFL_PASS_PLANE && BILLBOARD
  53. bend_diff = (view_refl_matrix * vec4(bend_diff, 0.0)).xyz;
  54. # endif
  55. // normalize by non-bended length to keep overall form
  56. float len = length(pw - cw);
  57. pos_world = center_world + normalize(bend_diff) * len;
  58. }
  59. }
  60. # if DETAIL_BEND
  61. vec4 smooth_curve( vec4 x ) {
  62. return x * x *( 3.0 - 2.0 * x );
  63. }
  64. vec4 triangle_wave( vec4 x ) {
  65. return abs( fract( x + 0.5 ) * 2.0 - 1.0 );
  66. }
  67. vec4 smooth_triangle_wave( vec4 x ) {
  68. return smooth_curve( triangle_wave( x ) );
  69. }
  70. void detail_bend(inout vec3 pos_world,
  71. in float time,
  72. in vec3 normal,
  73. in vec3 wind_world,
  74. in vec3 center_world,
  75. in float detail_freq,
  76. in float detail_amp,
  77. in float branch_amp,
  78. in vec3 bend_params,
  79. in mat4 view_refl_matrix)
  80. {
  81. float obj_phase;
  82. float branch_phase;
  83. float vtx_phase;
  84. vec2 waves_in;
  85. vec4 waves;
  86. vec2 waves_sum;
  87. vec3 bend;
  88. # if REFLECTION_PASS == REFL_PASS_PLANE && BILLBOARD
  89. vec3 pw = (view_refl_matrix * vec4(pos_world, 1.0)).xyz;
  90. vec3 cw = (view_refl_matrix * vec4(center_world, 1.0)).xyz;
  91. # else
  92. vec3 pw = pos_world;
  93. vec3 cw = center_world;
  94. # endif
  95. // Phases (object, vertex, branch)
  96. obj_phase = dot(cw, vec3(1.0));
  97. branch_phase = obj_phase + bend_params.g;
  98. vtx_phase = dot(pw, vec3(bend_params.g));
  99. // x is used for edges; y is used for branches
  100. waves_in = (time + vec2(vtx_phase, branch_phase));
  101. waves = ((fract( (waves_in.xxyy *
  102. vec4(1.975, 0.793, 0.375, 0.193)) ) *
  103. 2.0) - 1.0) * length(wind_world) * detail_freq;
  104. waves = smooth_triangle_wave(waves);
  105. waves_sum = waves.xz + waves.yw;
  106. // move branches both up and down
  107. waves_sum.y = 0.5 - waves_sum.y;
  108. bend = waves_sum.xxy * bend_params.rrb * vec3(detail_amp * normal.x,
  109. detail_amp * normal.y,
  110. branch_amp);
  111. # if REFLECTION_PASS == REFL_PASS_PLANE && BILLBOARD
  112. bend = (view_refl_matrix * vec4(bend, 0.0)).xyz;
  113. # endif
  114. pos_world += bend;
  115. }
  116. # endif // DETAIL_BEND
  117. void bend_vertex(inout vec3 position, inout vec3 center, in vec3 normal, in mat4 view_refl_matrix) {
  118. vec3 wind = u_wind * 1.0 + 0.7 * sin(u_time); // make wind gusty;
  119. # if BEND_CENTER_ONLY
  120. vec3 vertex_position = center;
  121. vec3 object_center = a_emitter_center;
  122. # if REFLECTION_PASS == REFL_PASS_PLANE && BILLBOARD
  123. object_center = (view_refl_matrix * vec4(object_center, 1.0)).xyz;
  124. # endif
  125. # else
  126. vec3 vertex_position = position;
  127. vec3 object_center = center;
  128. # endif
  129. # if MAIN_BEND_COL
  130. # if DETAIL_BEND
  131. detail_bend(vertex_position, u_time, normal, wind, object_center,
  132. au_detail_bending_freq, au_detail_bending_amp, au_branch_bending_amp,
  133. a_bending_col_detail, view_refl_matrix);
  134. # endif
  135. main_bend(vertex_position, object_center, au_wind_bending_amp, au_wind_bending_freq,
  136. u_time, wind, a_bending_col_main, view_refl_matrix);
  137. # else
  138. main_bend(vertex_position, object_center, au_wind_bending_amp, au_wind_bending_freq,
  139. u_time, wind, 1.0, view_refl_matrix);
  140. # endif
  141. # if BEND_CENTER_ONLY
  142. position += vertex_position - center;
  143. center = vertex_position;
  144. # else
  145. position = vertex_position;
  146. center = object_center;
  147. # endif
  148. }
  149. #endif // WIND_BEND
  150. #endif