to_world.glslv 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #ifndef TO_WORLD_GLSLV
  2. #define TO_WORLD_GLSLV
  3. #include <math.glslv>
  4. /*==============================================================================
  5. VARS
  6. ==============================================================================*/
  7. #var BILLBOARD_ALIGN BILLBOARD_ALIGN_VIEW
  8. #var USE_INSTANCED_PARTCLS 0
  9. #var BILLBOARD_SPHERICAL 0
  10. #var BILLBOARD_RANDOM 0
  11. #var BILLBOARD 0
  12. #var BILLBOARD_JITTERED 0
  13. #var BILLBOARD_PRES_GLOB_ORIENTATION 0
  14. #var STATIC_BATCH 0
  15. #var REFLECTION_PASS REFL_PASS_NONE
  16. /*============================================================================*/
  17. #define MAX_BILLBOARD_ANGLE M_PI_4
  18. #if BILLBOARD_SPHERICAL || !BILLBOARD && (BILLBOARD_ALIGN == BILLBOARD_ALIGN_VIEW)
  19. mat3 billboard_spherical(vec3 center_pos, mat3 view_tsr) {
  20. vec4 bb_q = vec4(view_tsr[1][1], view_tsr[1][2], view_tsr[2][0],view_tsr[2][1]);
  21. // NOTE: camera is rotated downward by default,
  22. // inversed vertex order during reflection pass
  23. #if REFLECTION_PASS == REFL_PASS_PLANE
  24. vec4 right_q = qsetAxisAngle(RIGHT_VECTOR, -M_PI/2.0);
  25. #else
  26. vec4 right_q = qsetAxisAngle(RIGHT_VECTOR, M_PI/2.0);
  27. #endif
  28. bb_q = qmult(right_q, bb_q);
  29. bb_q = qinv(bb_q);
  30. mat3 bb_tsr = tsr_identity();
  31. bb_tsr[0] = center_pos;
  32. bb_tsr = tsr_set_quat(bb_q, bb_tsr);
  33. return bb_tsr;
  34. }
  35. #else
  36. mat3 billboard_cylindrical(vec3 camera_eye, vec3 center_pos) {
  37. vec3 center_to_cam = camera_eye - center_pos;
  38. center_to_cam.z = 0.0;
  39. center_to_cam = normalize(center_to_cam);
  40. vec4 bb_q = qfrom_dir(center_to_cam, TOWARD_VECTOR);
  41. mat3 bb_tsr = tsr_identity();
  42. bb_tsr[0] = center_pos;
  43. bb_tsr = tsr_set_quat(bb_q, bb_tsr);
  44. return bb_tsr;
  45. }
  46. #endif // BILLBOARD_SPHERICAL
  47. #if BILLBOARD_JITTERED
  48. mat3 bend_jitter_rotate_tsr(in vec3 wind_world, float wind_param, float jitter_amp,
  49. float jitter_freq, vec3 vec_seed, mat3 model_tsr) {
  50. float seed = fract(length(vec_seed) / 0.17); // [0, 1]
  51. float rand_freq = jitter_freq + seed / 10.0; // + 0%-10%
  52. float rand_phase = seed;
  53. if (jitter_freq != 0.0)
  54. rand_phase /= jitter_freq ; // [0, 1/freq]
  55. wind_world *= 1.0 + 0.5 * sin(wind_param); // make wind gusty
  56. // jitter rotation angle
  57. float bj_angle = length(wind_world) * jitter_amp * sin(2.0*3.14 * wind_param
  58. * rand_freq + rand_phase);
  59. vec4 bj_quat = qsetAxisAngle(TOWARD_VECTOR, bj_angle);
  60. // rotate tsr from the right
  61. vec4 model_quat = vec4(model_tsr[1][1], model_tsr[1][2], model_tsr[2][0], model_tsr[2][1]);
  62. model_quat = qmult(model_quat, bj_quat);
  63. model_tsr = tsr_set_quat(model_quat, model_tsr);
  64. return model_tsr;
  65. }
  66. #endif
  67. mat3 billboard_tsr(in vec3 camera_eye, in vec3 wcen, in mat3 view_tsr) {
  68. #if BILLBOARD_SPHERICAL || !BILLBOARD && (BILLBOARD_ALIGN == BILLBOARD_ALIGN_VIEW)
  69. mat3 bill_tsr = billboard_spherical(wcen, view_tsr);
  70. #elif BILLBOARD_RANDOM
  71. // get initial random rotation angle
  72. float seed = fract((wcen.x * 1.43 - wcen.z * 0.123 + wcen.y * 6.1));
  73. float alpha_rand = 2.0 * M_PI * seed;
  74. vec4 view_quat = vec4(view_tsr[1][1], view_tsr[1][2], view_tsr[2][0], view_tsr[2][1]);
  75. float alpha_cam = asin(2.0 * (view_quat.x * view_quat.y - view_quat.z * view_quat.w));
  76. float alpha_diff = alpha_cam - alpha_rand;
  77. if (alpha_diff < 0.0)
  78. alpha_diff = 2.0 * M_PI + alpha_diff;
  79. float res_angle = alpha_rand;
  80. if (alpha_diff <= MAX_BILLBOARD_ANGLE)
  81. res_angle += alpha_diff;
  82. else if (alpha_diff <= M_PI - MAX_BILLBOARD_ANGLE)
  83. res_angle += MAX_BILLBOARD_ANGLE * (2.0 * alpha_diff - M_PI)
  84. / (2.0 * MAX_BILLBOARD_ANGLE - M_PI);
  85. else if (alpha_diff <= M_PI + MAX_BILLBOARD_ANGLE)
  86. res_angle += alpha_diff - M_PI;
  87. else if (alpha_diff <= 2.0 * M_PI - MAX_BILLBOARD_ANGLE)
  88. res_angle += MAX_BILLBOARD_ANGLE * (2.0 * alpha_diff - M_PI)
  89. / (2.0 * MAX_BILLBOARD_ANGLE - M_PI) + M_PI;
  90. else
  91. res_angle += alpha_diff - 2.0 * M_PI;
  92. vec4 bill_quat = qsetAxisAngle(UP_VECTOR, res_angle);
  93. mat3 bill_tsr;
  94. bill_tsr[0] = wcen;
  95. bill_tsr[1][0] = 1.0;
  96. bill_tsr = tsr_set_quat(bill_quat, bill_tsr);
  97. #else
  98. mat3 bill_tsr = billboard_cylindrical(camera_eye, wcen);
  99. #endif
  100. return bill_tsr;
  101. }
  102. #if BILLBOARD_PRES_GLOB_ORIENTATION && !STATIC_BATCH || USE_INSTANCED_PARTCLS
  103. mat3 billboard_tsr_global(in vec3 camera_eye, in vec3 wcen, in mat3 view_tsr,
  104. in mat3 model_tsr) {
  105. mat3 bill_tsr = billboard_tsr(camera_eye, wcen, view_tsr);
  106. // NOTE: translation is already in bill_tsr
  107. model_tsr[0] = vec3(0.0, 0.0, 0.0);
  108. bill_tsr = tsr_multiply(bill_tsr, model_tsr);
  109. return bill_tsr;
  110. }
  111. #endif
  112. vertex to_world(in vec3 pos, in vec3 cen, in vec3 tng, in vec3 shd_tng, in vec3 bnr,
  113. in vec3 nrm, in mat3 model_tsr) {
  114. pos = tsr9_transform(model_tsr, pos);
  115. cen = tsr9_transform(model_tsr, cen);
  116. tng = tsr9_transform_dir(model_tsr, tng);
  117. shd_tng = tsr9_transform_dir(model_tsr, shd_tng);
  118. bnr = tsr9_transform_dir(model_tsr, bnr);
  119. nrm = tsr9_transform_dir(model_tsr, nrm);
  120. return tbn_norm(vertex(pos, cen, tng, shd_tng, bnr, nrm, vec3(0.0)));
  121. }
  122. #endif