@@ -69,11 +69,6 @@ function UniformContainer() {
6969var arrayCacheF32 = [ ] ;
7070var arrayCacheI32 = [ ] ;
7171
72- // Float32Array caches used for uploading Matrix uniforms
73-
74- var mat4array = new Float32Array ( 16 ) ;
75- var mat3array = new Float32Array ( 9 ) ;
76-
7772// Flattening for arrays of vectors and matrices
7873
7974function flatten ( array , nBlocks , blockSize ) {
@@ -111,6 +106,30 @@ function flatten( array, nBlocks, blockSize ) {
111106
112107}
113108
109+ function arraysEqual ( a , b ) {
110+
111+ if ( a . length !== b . length ) return false ;
112+
113+ for ( var i = 0 ; i < a . length ; i ++ ) {
114+
115+ if ( a [ i ] !== b [ i ] ) return false ;
116+
117+ }
118+
119+ return true ;
120+
121+ }
122+
123+ function copyArray ( a , b ) {
124+
125+ for ( var i = 0 ; i < b . length ; i ++ ) {
126+
127+ a [ i ] = b [ i ] ;
128+
129+ }
130+
131+ }
132+
114133// Texture unit allocation
115134
116135function allocTexUnits ( renderer , n ) {
@@ -140,27 +159,44 @@ function allocTexUnits( renderer, n ) {
140159
141160function setValue1f ( gl , v ) {
142161
162+ if ( this . cache [ 0 ] === v ) return ;
163+
143164 gl . uniform1f ( this . addr , v ) ;
144165
166+ this . cache [ 0 ] = v ;
167+
145168}
146169
147170function setValue1i ( gl , v ) {
148171
172+ if ( this . cache [ 0 ] === v ) return ;
173+
149174 gl . uniform1i ( this . addr , v ) ;
150175
176+ this . cache [ 0 ] = v ;
177+
151178}
152179
153180// Single float vector (from flat array or THREE.VectorN)
154181
155182function setValue2fv ( gl , v ) {
156183
157- if ( v . x = == undefined ) {
184+ if ( v . x ! == undefined ) {
158185
159- gl . uniform2fv ( this . addr , v ) ;
186+ if ( this . cache [ 0 ] === v . x && this . cache [ 1 ] === v . y ) return ;
187+
188+ gl . uniform2f ( this . addr , v . x , v . y ) ;
189+
190+ this . cache [ 0 ] = v . x ;
191+ this . cache [ 1 ] = v . y ;
160192
161193 } else {
162194
163- gl . uniform2f ( this . addr , v . x , v . y ) ;
195+ if ( arraysEqual ( this . cache , v ) ) return ;
196+
197+ gl . uniform2fv ( this . addr , v ) ;
198+
199+ copyArray ( this . cache , v ) ;
164200
165201 }
166202
@@ -170,29 +206,63 @@ function setValue3fv( gl, v ) {
170206
171207 if ( v . x !== undefined ) {
172208
209+ if ( this . cache [ 0 ] === v . x &&
210+ this . cache [ 1 ] === v . y &&
211+ this . cache [ 2 ] === v . z ) return ;
212+
173213 gl . uniform3f ( this . addr , v . x , v . y , v . z ) ;
174214
215+ this . cache [ 0 ] = v . x ;
216+ this . cache [ 1 ] = v . y ;
217+ this . cache [ 2 ] = v . z ;
218+
175219 } else if ( v . r !== undefined ) {
176220
221+ if ( this . cache [ 0 ] === v . r &&
222+ this . cache [ 1 ] === v . g &&
223+ this . cache [ 2 ] === v . b ) return ;
224+
177225 gl . uniform3f ( this . addr , v . r , v . g , v . b ) ;
178226
227+ this . cache [ 0 ] = v . r ;
228+ this . cache [ 1 ] = v . g ;
229+ this . cache [ 2 ] = v . b ;
230+
179231 } else {
180232
233+ if ( arraysEqual ( this . cache , v ) ) return ;
234+
181235 gl . uniform3fv ( this . addr , v ) ;
182236
237+ copyArray ( this . cache , v ) ;
238+
183239 }
184240
185241}
186242
187243function setValue4fv ( gl , v ) {
188244
189- if ( v . x = == undefined ) {
245+ if ( v . x ! == undefined ) {
190246
191- gl . uniform4fv ( this . addr , v ) ;
247+ if ( this . cache [ 0 ] === v . x &&
248+ this . cache [ 1 ] === v . y &&
249+ this . cache [ 2 ] === v . z &&
250+ this . cache [ 3 ] === v . w ) return ;
251+
252+ gl . uniform4f ( this . addr , v . x , v . y , v . z , v . w ) ;
253+
254+ this . cache [ 0 ] = v . x ;
255+ this . cache [ 1 ] = v . y ;
256+ this . cache [ 2 ] = v . z ;
257+ this . cache [ 3 ] = v . w ;
192258
193259 } else {
194260
195- gl . uniform4f ( this . addr , v . x , v . y , v . z , v . w ) ;
261+ if ( arraysEqual ( this . cache , v ) ) return ;
262+
263+ gl . uniform4fv ( this . addr , v ) ;
264+
265+ copyArray ( this . cache , v ) ;
196266
197267 }
198268
@@ -202,37 +272,37 @@ function setValue4fv( gl, v ) {
202272
203273function setValue2fm ( gl , v ) {
204274
205- gl . uniformMatrix2fv ( this . addr , false , v . elements || v ) ;
275+ var data = v . elements || v ;
276+
277+ if ( arraysEqual ( this . cache , data ) ) return ;
278+
279+ gl . uniformMatrix2fv ( this . addr , false , data ) ;
280+
281+ copyArray ( this . cache , data ) ;
206282
207283}
208284
209285function setValue3fm ( gl , v ) {
210286
211- if ( v . elements === undefined ) {
287+ var data = v . elements || v ;
212288
213- gl . uniformMatrix3fv ( this . addr , false , v ) ;
289+ if ( arraysEqual ( this . cache , data ) ) return ;
214290
215- } else {
291+ gl . uniformMatrix3fv ( this . addr , false , data ) ;
216292
217- mat3array . set ( v . elements ) ;
218- gl . uniformMatrix3fv ( this . addr , false , mat3array ) ;
219-
220- }
293+ copyArray ( this . cache , data ) ;
221294
222295}
223296
224297function setValue4fm ( gl , v ) {
225298
226- if ( v . elements === undefined ) {
299+ var data = v . elements || v ;
227300
228- gl . uniformMatrix4fv ( this . addr , false , v ) ;
301+ if ( arraysEqual ( this . cache , data ) ) return ;
229302
230- } else {
303+ gl . uniformMatrix4fv ( this . addr , false , data ) ;
231304
232- mat4array . set ( v . elements ) ;
233- gl . uniformMatrix4fv ( this . addr , false , mat4array ) ;
234-
235- }
305+ copyArray ( this . cache , data ) ;
236306
237307}
238308
@@ -241,15 +311,29 @@ function setValue4fm( gl, v ) {
241311function setValueT1 ( gl , v , renderer ) {
242312
243313 var unit = renderer . allocTextureUnit ( ) ;
244- gl . uniform1i ( this . addr , unit ) ;
314+
315+ if ( this . cache [ 0 ] !== unit ) {
316+
317+ gl . uniform1i ( this . addr , unit ) ;
318+ this . cache [ 0 ] = unit ;
319+
320+ }
321+
245322 renderer . setTexture2D ( v || emptyTexture , unit ) ;
246323
247324}
248325
249326function setValueT6 ( gl , v , renderer ) {
250327
251328 var unit = renderer . allocTextureUnit ( ) ;
252- gl . uniform1i ( this . addr , unit ) ;
329+
330+ if ( this . cache [ 0 ] !== unit ) {
331+
332+ gl . uniform1i ( this . addr , unit ) ;
333+ this . cache [ 0 ] = unit ;
334+
335+ }
336+
253337 renderer . setTextureCube ( v || emptyCubeTexture , unit ) ;
254338
255339}
@@ -258,20 +342,32 @@ function setValueT6( gl, v, renderer ) {
258342
259343function setValue2iv ( gl , v ) {
260344
345+ if ( arraysEqual ( this . cache , v ) ) return ;
346+
261347 gl . uniform2iv ( this . addr , v ) ;
262348
349+ copyArray ( this . cache , v ) ;
350+
263351}
264352
265353function setValue3iv ( gl , v ) {
266354
355+ if ( arraysEqual ( this . cache , v ) ) return ;
356+
267357 gl . uniform3iv ( this . addr , v ) ;
268358
359+ copyArray ( this . cache , v ) ;
360+
269361}
270362
271363function setValue4iv ( gl , v ) {
272364
365+ if ( arraysEqual ( this . cache , v ) ) return ;
366+
273367 gl . uniform4iv ( this . addr , v ) ;
274368
369+ copyArray ( this . cache , v ) ;
370+
275371}
276372
277373// Helper to pick the right setter for the singular case
@@ -419,6 +515,7 @@ function SingleUniform( id, activeInfo, addr ) {
419515
420516 this . id = id ;
421517 this . addr = addr ;
518+ this . cache = [ ] ;
422519 this . setValue = getSingularSetter ( activeInfo . type ) ;
423520
424521 // this.path = activeInfo.name; // DEBUG
@@ -490,7 +587,7 @@ function parseUniform( activeInfo, addr, container ) {
490587 // reset RegExp object, because of the early exit of a previous run
491588 RePathPart . lastIndex = 0 ;
492589
493- for ( ; ; ) {
590+ while ( true ) {
494591
495592 var match = RePathPart . exec ( path ) ,
496593 matchEnd = RePathPart . lastIndex ,
0 commit comments