@@ -19,13 +19,21 @@ const RAIN_DROP_SPEED = 20;
19
19
const RAIN_DROP_COUNT = 1000 ;
20
20
const RAINING_RANGE = 20 ;
21
21
const RAINING_FROM_HEIGHT = 10 ;
22
- const RAINDROP_TAIL_LENGTH = 0.1 ;
23
- const RANIDROP_MAX_ALPHA = 0.7 ;
24
- const RANIDROP_MAX_ALPHA_TAIL = 0.1 ;
25
-
26
- const RIPPLE_EXPAND_SPEED = 1 ;
27
- const RIPPLE_RADIUS_MAX = 0.1 ;
28
- const RIPPLE_MAX_ALPHA = 0.25 ;
22
+ const RAINDROP_TAIL_LENGTH = 0.5 ;
23
+ const RANIDROP_MAX_ALPHA = 0.6 ;
24
+ const RANIDROP_MAX_ALPHA_TAIL = 0.2 ;
25
+
26
+ const RIPPLE_EXPAND_SPEED = 0.5 ;
27
+ const RIPPLE_RADIUS_MAX = 0.25 ;
28
+ const RIPPLE_MAX_ALPHA = 0.5 ;
29
+ const RIPPLE_CIRCLE_SEGMENT_COUNT = 16 ;
30
+
31
+ const LIGHTNING_INTERVAL_MIN = 5 ;
32
+ const LIGHTNING_INTERVAL_MAX = 60 ;
33
+ const LIGHTNING_INTERVAL_SUB_COUNT_MAX = 3 ;
34
+ const LIGHTNING_PEAK_PROBABILITY = 0.5 ;
35
+ const LIGHTNING_ALPHA_DECAY_SPEED = 5 ;
36
+ const LIGHTNING_ALPHA_MIN = 0.5 ;
29
37
30
38
export class RainRenderer implements RendererInterface {
31
39
canvas : HTMLCanvasElement ;
@@ -46,6 +54,11 @@ export class RainRenderer implements RendererInterface {
46
54
47
55
ripples : Ripple [ ] = [ ] ;
48
56
57
+ nextLightningTime : number = 0 ;
58
+ currentLightningCount : number = 0 ;
59
+ currentRemainedLightningCount : number = 0 ;
60
+ currentLightningAlpha : number = 0 ;
61
+
49
62
constructor ( canvasElement : HTMLCanvasElement ) {
50
63
this . canvas = canvasElement ;
51
64
this . canvas . width = this . canvas . clientWidth ;
@@ -131,6 +144,28 @@ void main() {
131
144
update ( dt : number ) {
132
145
this . updateDrops ( dt ) ;
133
146
this . updateRipples ( dt ) ;
147
+ this . updateLightning ( dt ) ;
148
+ }
149
+
150
+ updateLightning ( dt : number ) {
151
+ const now = performance . now ( ) ;
152
+ if ( now > this . nextLightningTime ) {
153
+ const nextInterval = rangedRandom ( LIGHTNING_INTERVAL_MIN , LIGHTNING_INTERVAL_MAX ) ;
154
+ console . log ( 'Next lightning in ' , Math . floor ( nextInterval ) , ' seconds' ) ;
155
+ this . nextLightningTime = now + nextInterval * 1000 ;
156
+ this . currentLightningCount = this . currentRemainedLightningCount = Math . floor ( rangedRandom ( 1 , LIGHTNING_INTERVAL_SUB_COUNT_MAX ) ) ;
157
+ } else {
158
+ const decaySpeed = ( this . currentRemainedLightningCount > 0 ) ? LIGHTNING_ALPHA_DECAY_SPEED : 1 ;
159
+ this . currentLightningAlpha = Math . max ( 0 , this . currentLightningAlpha - dt * decaySpeed ) ;
160
+ if ( this . currentRemainedLightningCount > 0 && this . currentLightningAlpha < 1e-4 ) {
161
+ const rng = Math . random ( ) ;
162
+ if ( rng < LIGHTNING_PEAK_PROBABILITY ) {
163
+ console . log ( 'Lightning!' , this . currentRemainedLightningCount , this . currentLightningAlpha ) ;
164
+ this . currentLightningAlpha = rangedRandom ( LIGHTNING_ALPHA_MIN , 1 ) ;
165
+ this . currentRemainedLightningCount -= 1 ;
166
+ }
167
+ }
168
+ }
134
169
}
135
170
136
171
updateDrops ( dt : number ) {
@@ -217,7 +252,7 @@ void main() {
217
252
gl . bindBuffer ( gl . ARRAY_BUFFER , vertexBuffer ) ;
218
253
219
254
const activeRipples = this . getActiveRipples ( ) ;
220
- const rippleSegmentCount = 8 ;
255
+ const rippleSegmentCount = RIPPLE_CIRCLE_SEGMENT_COUNT ;
221
256
222
257
const vertexData = new Float32Array ( this . raindrops . length * dropStride + activeRipples . length * rippleSegmentCount * 2 * vertexStride ) ;
223
258
this . raindrops . forEach ( ( drop , index ) => {
@@ -298,7 +333,8 @@ void main() {
298
333
299
334
// clear black.
300
335
const gl = this . context ;
301
- gl . clearColor ( 0 , 0 , 0 , 1 ) ;
336
+ const clearColorIntensity = this . currentLightningAlpha * 0.75 + 0.25 ;
337
+ gl . clearColor ( clearColorIntensity , clearColorIntensity , clearColorIntensity , 1 ) ;
302
338
gl . clear ( this . context . COLOR_BUFFER_BIT | this . context . DEPTH_BUFFER_BIT ) ;
303
339
304
340
// alpha blend
0 commit comments