scene_forward_aa_inc.glsl 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #ifdef ALPHA_HASH_USED
  2. float hash_2d(vec2 p) {
  3. return fract(1.0e4 * sin(17.0 * p.x + 0.1 * p.y) *
  4. (0.1 + abs(sin(13.0 * p.y + p.x))));
  5. }
  6. float hash_3d(vec3 p) {
  7. return hash_2d(vec2(hash_2d(p.xy), p.z));
  8. }
  9. float compute_alpha_hash_threshold(vec3 pos, float hash_scale) {
  10. vec3 dx = dFdx(pos);
  11. vec3 dy = dFdy(pos);
  12. float delta_max_sqr = max(length(dx), length(dy));
  13. float pix_scale = 1.0 / (hash_scale * delta_max_sqr);
  14. vec2 pix_scales =
  15. vec2(exp2(floor(log2(pix_scale))), exp2(ceil(log2(pix_scale))));
  16. vec2 a_thresh = vec2(hash_3d(floor(pix_scales.x * pos.xyz)),
  17. hash_3d(floor(pix_scales.y * pos.xyz)));
  18. float lerp_factor = fract(log2(pix_scale));
  19. float a_interp = (1.0 - lerp_factor) * a_thresh.x + lerp_factor * a_thresh.y;
  20. float min_lerp = min(lerp_factor, 1.0 - lerp_factor);
  21. vec3 cases = vec3(a_interp * a_interp / (2.0 * min_lerp * (1.0 - min_lerp)),
  22. (a_interp - 0.5 * min_lerp) / (1.0 - min_lerp),
  23. 1.0 - ((1.0 - a_interp) * (1.0 - a_interp) / (2.0 * min_lerp * (1.0 - min_lerp))));
  24. float alpha_hash_threshold =
  25. (a_interp < (1.0 - min_lerp)) ? ((a_interp < min_lerp) ? cases.x : cases.y) : cases.z;
  26. return clamp(alpha_hash_threshold, 0.00001, 1.0);
  27. }
  28. #endif // ALPHA_HASH_USED
  29. #ifdef ALPHA_ANTIALIASING_EDGE_USED
  30. float calc_mip_level(vec2 texture_coord) {
  31. vec2 dx = dFdx(texture_coord);
  32. vec2 dy = dFdy(texture_coord);
  33. float delta_max_sqr = max(dot(dx, dx), dot(dy, dy));
  34. return max(0.0, 0.5 * log2(delta_max_sqr));
  35. }
  36. float compute_alpha_antialiasing_edge(float input_alpha, vec2 texture_coord, float alpha_edge) {
  37. input_alpha *= 1.0 + max(0, calc_mip_level(texture_coord)) * 0.25; // 0.25 mip scale, magic number
  38. input_alpha = (input_alpha - alpha_edge) / max(fwidth(input_alpha), 0.0001) + 0.5;
  39. return clamp(input_alpha, 0.0, 1.0);
  40. }
  41. #endif // ALPHA_ANTIALIASING_USED