-
Notifications
You must be signed in to change notification settings - Fork 41
/
Optimizer.js
180 lines (118 loc) · 3.82 KB
/
Optimizer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
function Optimizer() {
/*
These two constants define in what range of FPS the game
will be displayed. The larger the range, the more stable
it will be, as there will be fewer attempts or optimization/ deoptimization
*/
const OPTFPS = 1 / 28 ; // FPS rate above which optimization must occur
const DEOPTFPS = 1 / 53 ; // FPS rate under which de-optimisation will occur
//
var optStep = 50 ; // ms duration of FPS sampling between each opti
var lastOptiTime = 0 ;
var samples = [];
//
const domWorldCheap = document.getElementById('worldCheap');
const domWorldHigh = document.getElementById('worldHigh');
var params = {
level: 0,
attempts: [ 0, 0, 0, 0, 0 ], // holds the number of failed attempt to set the optimization at given level
timeOpti: Date.now() // last time an optimisation was done
};
/*
optimize is called by the loop everytime the frame rate
is above the OPTFPS (which means rendering is slow).
It will increment the level of optimization by one,
so rendering will be faster, with worst graphics as
a trade-off
*/
function optimize() {
// Will disable FXAA
if ( params.level == 0 ) {
renderer.setPixelRatio( 1 );
params.level = 1 ;
// set pixel ratio to 1, which has effect mostly on smartphones
} else if ( params.level == 1 ) {
params.level = 2 ;
// Remove the shadow from the dynamic objects,
// and stop rendering shadows dynamically
} else if ( params.level == 2 ) {
assetManager.toggleCharacterShadows( false );
setTimeout( ()=> {
renderer.shadowMap.enabled = false;
}, 0);
params.level = 3 ;
} else if ( params.level == 3 ) {
camera.far = 11.5 ;
camera.updateProjectionMatrix();
params.level = 4 ;
};
};
/*
deOptimize is called by the loop every time the frame rate
is under DEOPTFPS (meaning rendering is fast).
It will decrement the level of optimization by one,
which will make graphics better but frame rate maybe lower
*/
function deOptimize() {
// There is already no optimization occuring
if ( params.level == 0 ) {
return
// enable FXAA
} else if ( params.level == 1 ) {
renderer.setPixelRatio( window.devicePixelRatio );
params.level = 0 ;
// set pixel ratio to the default device pixel ratio
} else if ( params.level == 2 ) {
params.level = 1 ;
// enable shadows on dynamic objects
} else if ( params.level == 3 ) {
renderer.shadowMap.enabled = true;
assetManager.toggleCharacterShadows( true );
params.level = 2 ;
} else if ( params.level == 4 ) {
camera.far = 23.5 ;
camera.updateProjectionMatrix();
params.level = 3 ;
};
};
//////////////////////////////
/// GENERAL FUNCTIONS
//////////////////////////////
/*
update will sample the current frame's delta, then when it's time
to decide if an opti/de-opti is needed, it decides over an average of
the sampled deltas.
*/
function update( delta ) {
// We don't want neither to optimize or to sample the performance
// inside the caves, because it would necessarily be better,
// and lead to uneven randering and opti/deopti
if ( mapManager.params.currentMap != 'mountain' ) return ;
if ( Date.now() > lastOptiTime + optStep ) {
lastOptiTime = Date.now();
if ( optStep < 3200 ) {
optStep *= 2 ;
};
let total = samples.reduce( ( accu, current )=> {
return accu + current ;
}, 0 );
let average = total / ( samples.length - 1 );
samples = [];
if ( average < DEOPTFPS &&
params.level != 0 &&
params.attempts[ params.level - 1 ] <= 2 ) {
deOptimize();
} else if ( average > OPTFPS ) {
params.attempts[ params.level ] ++ ; // record the failure of the current opti level
optimize();
};
} else {
samples.push( delta );
};
};
//
return {
params,
update
};
};