Skip to content

Commit 2e53873

Browse files
authored
Merge pull request #14025 from Mugen87/dev4
WebGLUniforms: Added caching for SingleUniform
2 parents ef11a16 + 46ac01b commit 2e53873

File tree

1 file changed

+126
-29
lines changed

1 file changed

+126
-29
lines changed

src/renderers/webgl/WebGLUniforms.js

Lines changed: 126 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,6 @@ function UniformContainer() {
6969
var arrayCacheF32 = [];
7070
var 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

7974
function 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

116135
function allocTexUnits( renderer, n ) {
@@ -140,27 +159,44 @@ function allocTexUnits( renderer, n ) {
140159

141160
function 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

147170
function 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

155182
function 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

187243
function 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

203273
function 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

209285
function 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

224297
function 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 ) {
241311
function 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

249326
function 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

259343
function 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

265353
function 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

271363
function 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

Comments
 (0)