Newer
Older
DungeonShooting / DungeonShooting_Godot / resource / shader / GodRays.gdshader
@小李xl 小李xl on 21 Mar 2024 3 KB 测试特效
  1. /*
  2. Shader from Godot Shaders - the free shader library.
  3. godotshaders.com/shader/god-rays
  4.  
  5. Feel free to use, improve and change this shader according to your needs
  6. and consider sharing the modified result on godotshaders.com.
  7. */
  8.  
  9. shader_type canvas_item;
  10.  
  11. uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
  12.  
  13. uniform float angle = -0.3;
  14. uniform float position = -0.2;
  15. uniform float spread : hint_range(0.0, 1.0) = 0.5;
  16. uniform float cutoff : hint_range(-1.0, 1.0) = 0.1;
  17. uniform float falloff : hint_range(0.0, 1.0) = 0.2;
  18. uniform float edge_fade : hint_range(0.0, 1.0) = 0.15;
  19.  
  20. uniform float speed = 1.0;
  21. uniform float ray1_density = 8.0;
  22. uniform float ray2_density = 30.0;
  23. uniform float ray2_intensity : hint_range(0.0, 1.0) = 0.3;
  24.  
  25. uniform vec4 color : source_color = vec4(1.0, 0.9, 0.65, 0.8);
  26.  
  27. uniform bool hdr = false;
  28. uniform float seed = 5.0;
  29.  
  30. float random(vec2 _uv) {
  31. _uv += min(TIME,0.0);
  32. return fract(sin(dot(_uv.xy, vec2(12.9898, 78.233))) * 43758.5453123);
  33. }
  34.  
  35. float noise (in vec2 uv) {
  36. vec2 i = floor(uv);
  37. vec2 f = fract(uv);
  38.  
  39. // Four corners in 2D of a tile
  40. float a = random(i);
  41. float b = random(i + vec2(1.0, 0.0));
  42. float c = random(i + vec2(0.0, 1.0));
  43. float d = random(i + vec2(1.0, 1.0));
  44.  
  45.  
  46. // Smooth Interpolation
  47.  
  48. // Cubic Hermine Curve. Same as SmoothStep()
  49. vec2 u = f * f * (3.0-2.0 * f);
  50.  
  51. // Mix 4 coorners percentages
  52. return mix(a, b, u.x) +
  53. (c - a)* u.y * (1.0 - u.x) +
  54. (d - b) * u.x * u.y;
  55. }
  56.  
  57. mat2 rotate(float _angle){
  58. return mat2(vec2(cos(_angle), -sin(_angle)),
  59. vec2(sin(_angle), cos(_angle)));
  60. }
  61.  
  62. vec4 screen(vec4 base, vec4 blend){
  63. return 1.0 - (1.0 - base) * (1.0 - blend);
  64. }
  65.  
  66. void fragment()
  67. {
  68. // Rotate, skew and move the UVs
  69. vec2 transformed_uv = ( rotate(angle) * (UV - position) ) / ( (UV.y + spread) - (UV.y * spread) );
  70. // Animate the ray according the the new transformed UVs
  71. vec2 ray1 = vec2(transformed_uv.x * ray1_density + sin(TIME * 0.1 * speed) * (ray1_density * 0.2) + seed, 1.0);
  72. vec2 ray2 = vec2(transformed_uv.x * ray2_density + sin(TIME * 0.2 * speed) * (ray1_density * 0.2) + seed, 1.0);
  73. // Cut off the ray's edges
  74. float cut = step(cutoff, transformed_uv.x) * step(cutoff, 1.0 - transformed_uv.x);
  75. ray1 *= cut;
  76. ray2 *= cut;
  77. // Apply the noise pattern (i.e. create the rays)
  78. float rays;
  79. if (hdr){
  80. // This is not really HDR, but check this to not clamp the two merged rays making
  81. // their values go over 1.0. Can make for some nice effect
  82. rays = noise(ray1) + (noise(ray2) * ray2_intensity);
  83. }
  84. else{
  85. rays = clamp(noise(ray1) + (noise(ray2) * ray2_intensity), 0., 1.);
  86. }
  87. // Fade out edges
  88. rays *= smoothstep(0.0, falloff, (1.0 - UV.y)); // Bottom
  89. rays *= smoothstep(0.0 + cutoff, edge_fade + cutoff, transformed_uv.x); // Left
  90. rays *= smoothstep(0.0 + cutoff, edge_fade + cutoff, 1.0 - transformed_uv.x); // Right
  91. // Color to the rays
  92. vec3 shine = vec3(rays) * color.rgb;
  93.  
  94. // Try different blending modes for a nicer effect. "Screen" is included in the code,
  95. // but take a look at https://godotshaders.com/snippet/blending-modes/ for more.
  96. // With "Screen" blend mode:
  97. shine = screen(texture(SCREEN_TEXTURE, SCREEN_UV), vec4(color)).rgb;
  98. COLOR = vec4(shine, rays * color.a);
  99. }