Skip to content

Commit f9557c4

Browse files
authored
UniformUtils: Fix deep-copy with array of uniforms. (#33384)
1 parent 86bd3d5 commit f9557c4

2 files changed

Lines changed: 50 additions & 5 deletions

File tree

src/renderers/shaders/UniformsUtils.js

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@ export function cloneUniforms( src ) {
2727

2828
const property = src[ u ][ p ];
2929

30-
if ( property && ( property.isColor ||
31-
property.isMatrix3 || property.isMatrix4 ||
32-
property.isVector2 || property.isVector3 || property.isVector4 ||
33-
property.isTexture || property.isQuaternion ) ) {
30+
if ( isThreeObject( property ) ) {
3431

3532
if ( property.isRenderTargetTexture ) {
3633

@@ -45,7 +42,23 @@ export function cloneUniforms( src ) {
4542

4643
} else if ( Array.isArray( property ) ) {
4744

48-
dst[ u ][ p ] = property.slice();
45+
if ( isThreeObject( property[ 0 ] ) ) {
46+
47+
const clonedProperty = [];
48+
49+
for ( let i = 0, l = property.length; i < l; i ++ ) {
50+
51+
clonedProperty[ i ] = property[ i ].clone();
52+
53+
}
54+
55+
dst[ u ][ p ] = clonedProperty;
56+
57+
} else {
58+
59+
dst[ u ][ p ] = property.slice();
60+
61+
}
4962

5063
} else {
5164

@@ -89,6 +102,15 @@ export function mergeUniforms( uniforms ) {
89102

90103
}
91104

105+
function isThreeObject( property ) {
106+
107+
return ( property && ( property.isColor ||
108+
property.isMatrix3 || property.isMatrix4 ||
109+
property.isVector2 || property.isVector3 || property.isVector4 ||
110+
property.isTexture || property.isQuaternion ) );
111+
112+
}
113+
92114
export function cloneUniformsGroups( src ) {
93115

94116
const dst = [];

test/unit/src/renderers/shaders/UniformsUtils.tests.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,29 @@ export default QUnit.module( 'Renderers', () => {
114114

115115
} );
116116

117+
QUnit.test( 'cloneUniforms clones arrays of objects', ( assert ) => {
118+
119+
const uniforms = {
120+
vector3Array: { value: [ new Vector3( 1, 2, 3 ), new Vector3( 4, 5, 6 ) ] },
121+
};
122+
123+
const uniformClones = UniformsUtils.clone( uniforms );
124+
125+
// Cloned array is a different reference and contains different object references
126+
assert.ok( uniforms.vector3Array.value !== uniformClones.vector3Array.value );
127+
assert.ok( uniforms.vector3Array.value[ 0 ] !== uniformClones.vector3Array.value[ 0 ] );
128+
assert.ok( uniforms.vector3Array.value[ 1 ] !== uniformClones.vector3Array.value[ 1 ] );
129+
130+
// Values are equal after cloning
131+
assert.ok( uniforms.vector3Array.value[ 0 ].equals( uniformClones.vector3Array.value[ 0 ] ) );
132+
assert.ok( uniforms.vector3Array.value[ 1 ].equals( uniformClones.vector3Array.value[ 1 ] ) );
133+
134+
// Mutating the original does not affect the clone
135+
uniforms.vector3Array.value[ 0 ].x = 123.0;
136+
assert.ok( ! uniforms.vector3Array.value[ 0 ].equals( uniformClones.vector3Array.value[ 0 ] ) );
137+
138+
} );
139+
117140
QUnit.test( 'cloneUniforms skips render target textures', ( assert ) => {
118141

119142
const uniforms = {

0 commit comments

Comments
 (0)