Shader Crash with Collada File

So, I had originally posted this as a bug on Three.JS’ github. I was told to use the forum, and if this turned out to be a bug the issue could be re-opened. That’s fine, I guess, though I am pretty confident that this is a bug.

I am loading a large amount of collada models. When I load one of them (I don’t know which, though I could find it), the entire page reloads and the giant blob of text at the bottom of this post appears in dev tools as an error.

I can infer that the problem here is that ColladaLoader isn’t properly detecting if a collada document is invalid. The expected behavior is for the collada document to be rejected and colladaOnError called.

THREE.WebGlProgram: shader error: 0 35715 false gl.getProgramInfoLog   THREE.WebGLShader: gl.getShaderInfoLog() vertex
1: #version 300 es
2: #define attribute in
3: #define varying out
4: #define texture2D texture
5: precision highp float;
6: precision highp int;
7: #define HIGH_PRECISION
8: #define SHADER_NAME MeshStandardMaterial
9: #define STANDARD 
10: #define USE_INSTANCING
11: #define VERTEX_TEXTURES
12: #define GAMMA_FACTOR 2
13: #define MAX_BONES 0
14: #define USE_EMISSIVEMAP
15: #define USE_UV
16: #define BONE_TEXTURE
17: #define DOUBLE_SIDED
18: uniform mat4 modelMatrix;
19: uniform mat4 modelViewMatrix;
20: uniform mat4 projectionMatrix;
21: uniform mat4 viewMatrix;
22: uniform mat3 normalMatrix;
23: uniform vec3 cameraPosition;
24: uniform bool isOrthographic;
25: #ifdef USE_INSTANCING
26: 	attribute mat4 instanceMatrix;
27: #endif
28: #ifdef USE_INSTANCING_COLOR
29: 	attribute vec3 instanceColor;
30: #endif
31: attribute vec3 position;
32: attribute vec3 normal;
33: attribute vec2 uv;
34: #ifdef USE_TANGENT
35: 	attribute vec4 tangent;
36: #endif
37: #if defined( USE_COLOR_ALPHA )
38: 	attribute vec4 color;
39: #elif defined( USE_COLOR )
40: 	attribute vec3 color;
41: #endif
42: #ifdef USE_MORPHTARGETS
43: 	attribute vec3 morphTarget0;
44: 	attribute vec3 morphTarget1;
45: 	attribute vec3 morphTarget2;
46: 	attribute vec3 morphTarget3;
47: 	#ifdef USE_MORPHNORMALS
48: 		attribute vec3 morphNormal0;
49: 		attribute vec3 morphNormal1;
50: 		attribute vec3 morphNormal2;
51: 		attribute vec3 morphNormal3;
52: 	#else
53: 		attribute vec3 morphTarget4;
54: 		attribute vec3 morphTarget5;
55: 		attribute vec3 morphTarget6;
56: 		attribute vec3 morphTarget7;
57: 	#endif
58: #endif
59: #ifdef USE_SKINNING
60: 	attribute vec4 skinIndex;
61: 	attribute vec4 skinWeight;
62: #endif
63: 
64: #define STANDARD
65: varying vec3 vViewPosition;
66: #ifndef FLAT_SHADED
67: 	varying vec3 vNormal;
68: 	#ifdef USE_TANGENT
69: 		varying vec3 vTangent;
70: 		varying vec3 vBitangent;
71: 	#endif
72: #endif
73: #define PI 3.141592653589793
74: #define PI2 6.283185307179586
75: #define PI_HALF 1.5707963267948966
76: #define RECIPROCAL_PI 0.3183098861837907
77: #define RECIPROCAL_PI2 0.15915494309189535
78: #define EPSILON 1e-6
79: #ifndef saturate
80: #define saturate(a) clamp( a, 0.0, 1.0 )
81: #endif
82: #define whiteComplement(a) ( 1.0 - saturate( a ) )
83: float pow2( const in float x ) { return x*x; }
84: float pow3( const in float x ) { return x*x*x; }
85: float pow4( const in float x ) { float x2 = x*x; return x2*x2; }
86: float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }
87: highp float rand( const in vec2 uv ) {
88: 	const highp float a = 12.9898, b = 78.233, c = 43758.5453;
89: 	highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );
90: 	return fract(sin(sn) * c);
91: }
92: #ifdef HIGH_PRECISION
93: 	float precisionSafeLength( vec3 v ) { return length( v ); }
94: #else
95: 	float max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }
96: 	float precisionSafeLength( vec3 v ) {
97: 		float maxComponent = max3( abs( v ) );
98: 		return length( v / maxComponent ) * maxComponent;
99: 	}
100: #endif
101: struct IncidentLight {
102: 	vec3 color;
103: 	vec3 direction;
104: 	bool visible;
105: };
106: struct ReflectedLight {
107: 	vec3 directDiffuse;
108: 	vec3 directSpecular;
109: 	vec3 indirectDiffuse;
110: 	vec3 indirectSpecular;
111: };
112: struct GeometricContext {
113: 	vec3 position;
114: 	vec3 normal;
115: 	vec3 viewDir;
116: #ifdef CLEARCOAT
117: 	vec3 clearcoatNormal;
118: #endif
119: };
120: vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
121: 	return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
122: }
123: vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {
124: 	return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );
125: }
126: vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
127: 	float distance = dot( planeNormal, point - pointOnPlane );
128: 	return - distance * planeNormal + point;
129: }
130: float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
131: 	return sign( dot( point - pointOnPlane, planeNormal ) );
132: }
133: vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {
134: 	return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;
135: }
136: mat3 transposeMat3( const in mat3 m ) {
137: 	mat3 tmp;
138: 	tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );
139: 	tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );
140: 	tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );
141: 	return tmp;
142: }
143: float linearToRelativeLuminance( const in vec3 color ) {
144: 	vec3 weights = vec3( 0.2126, 0.7152, 0.0722 );
145: 	return dot( weights, color.rgb );
146: }
147: bool isPerspectiveMatrix( mat4 m ) {
148: 	return m[ 2 ][ 3 ] == - 1.0;
149: }
150: vec2 equirectUv( in vec3 dir ) {
151: 	float u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;
152: 	float v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;
153: 	return vec2( u, v );
154: }
155: #ifdef USE_UV
156: 	#ifdef UVS_VERTEX_ONLY
157: 		vec2 vUv;
158: 	#else
159: 		varying vec2 vUv;
160: 	#endif
161: 	uniform mat3 uvTransform;
162: #endif
163: #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )
164: 	attribute vec2 uv2;
165: 	varying vec2 vUv2;
166: 	uniform mat3 uv2Transform;
167: #endif
168: #ifdef USE_DISPLACEMENTMAP
169: 	uniform sampler2D displacementMap;
170: 	uniform float displacementScale;
171: 	uniform float displacementBias;
172: #endif
173: #if defined( USE_COLOR_ALPHA )
174: 	varying vec4 vColor;
175: #elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )
176: 	varying vec3 vColor;
177: #endif
178: #ifdef USE_FOG
179: 	varying float fogDepth;
180: #endif
181: #ifdef USE_MORPHTARGETS
182: 	uniform float morphTargetBaseInfluence;
183: 	#ifndef USE_MORPHNORMALS
184: 		uniform float morphTargetInfluences[ 8 ];
185: 	#else
186: 		uniform float morphTargetInfluences[ 4 ];
187: 	#endif
188: #endif
189: #ifdef USE_SKINNING
190: 	uniform mat4 bindMatrix;
191: 	uniform mat4 bindMatrixInverse;
192: 	#ifdef BONE_TEXTURE
193: 		uniform highp sampler2D boneTexture;
194: 		uniform int boneTextureSize;
195: 		mat4 getBoneMatrix( const in float i ) {
196: 			float j = i * 4.0;
197: 			float x = mod( j, float( boneTextureSize ) );
198: 			float y = floor( j / float( boneTextureSize ) );
199: 			float dx = 1.0 / float( boneTextureSize );
200: 			float dy = 1.0 / float( boneTextureSize );
201: 			y = dy * ( y + 0.5 );
202: 			vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );
203: 			vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );
204: 			vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );
205: 			vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );
206: 			mat4 bone = mat4( v1, v2, v3, v4 );
207: 			return bone;
208: 		}
209: 	#else
210: 		uniform mat4 boneMatrices[ MAX_BONES ];
211: 		mat4 getBoneMatrix( const in float i ) {
212: 			mat4 bone = boneMatrices[ int(i) ];
213: 			return bone;
214: 		}
215: 	#endif
216: #endif
217: #ifdef USE_SHADOWMAP
218: 	#if 0 > 0
219: 		uniform mat4 directionalShadowMatrix[ 0 ];
220: 		varying vec4 vDirectionalShadowCoord[ 0 ];
221: 		struct DirectionalLightShadow {
222: 			float shadowBias;
223: 			float shadowNormalBias;
224: 			float shadowRadius;
225: 			vec2 shadowMapSize;
226: 		};
227: 		uniform DirectionalLightShadow directionalLightShadows[ 0 ];
228: 	#endif
229: 	#if 0 > 0
230: 		uniform mat4 spotShadowMatrix[ 0 ];
231: 		varying vec4 vSpotShadowCoord[ 0 ];
232: 		struct SpotLightShadow {
233: 			float shadowBias;
234: 			float shadowNormalBias;
235: 			float shadowRadius;
236: 			vec2 shadowMapSize;
237: 		};
238: 		uniform SpotLightShadow spotLightShadows[ 0 ];
239: 	#endif
240: 	#if 0 > 0
241: 		uniform mat4 pointShadowMatrix[ 0 ];
242: 		varying vec4 vPointShadowCoord[ 0 ];
243: 		struct PointLightShadow {
244: 			float shadowBias;
245: 			float shadowNormalBias;
246: 			float shadowRadius;
247: 			vec2 shadowMapSize;
248: 			float shadowCameraNear;
249: 			float shadowCameraFar;
250: 		};
251: 		uniform PointLightShadow pointLightShadows[ 0 ];
252: 	#endif
253: #endif
254: #ifdef USE_LOGDEPTHBUF
255: 	#ifdef USE_LOGDEPTHBUF_EXT
256: 		varying float vFragDepth;
257: 		varying float vIsPerspective;
258: 	#else
259: 		uniform float logDepthBufFC;
260: 	#endif
261: #endif
262: #if 0 > 0
263: 	varying vec3 vClipPosition;
264: #endif
265: void main() {
266: #ifdef USE_UV
267: 	vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
268: #endif
269: #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )
270: 	vUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;
271: #endif
272: #if defined( USE_COLOR_ALPHA )
273: 	vColor = vec4( 1.0 );
274: #elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )
275: 	vColor = vec3( 1.0 );
276: #endif
277: #ifdef USE_COLOR
278: 	vColor *= color;
279: #endif
280: #ifdef USE_INSTANCING_COLOR
281: 	vColor.xyz *= instanceColor.xyz;
282: #endif
283: vec3 objectNormal = vec3( normal );
284: #ifdef USE_TANGENT
285: 	vec3 objectTangent = vec3( tangent.xyz );
286: #endif
287: #ifdef USE_MORPHNORMALS
288: 	objectNormal *= morphTargetBaseInfluence;
289: 	objectNormal += morphNormal0 * morphTargetInfluences[ 0 ];
290: 	objectNormal += morphNormal1 * morphTargetInfluences[ 1 ];
291: 	objectNormal += morphNormal2 * morphTargetInfluences[ 2 ];
292: 	objectNormal += morphNormal3 * morphTargetInfluences[ 3 ];
293: #endif
294: #ifdef USE_SKINNING
295: 	mat4 boneMatX = getBoneMatrix( skinIndex.x );
296: 	mat4 boneMatY = getBoneMatrix( skinIndex.y );
297: 	mat4 boneMatZ = getBoneMatrix( skinIndex.z );
298: 	mat4 boneMatW = getBoneMatrix( skinIndex.w );
299: #endif
300: #ifdef USE_SKINNING
301: 	mat4 skinMatrix = mat4( 0.0 );
302: 	skinMatrix += skinWeight.x * boneMatX;
303: 	skinMatrix += skinWeight.y * boneMatY;
304: 	skinMatrix += skinWeight.z * boneMatZ;
305: 	skinMatrix += skinWeight.w * boneMatW;
306: 	skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;
307: 	objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;
308: 	#ifdef USE_TANGENT
309: 		objectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;
310: 	#endif
311: #endif
312: vec3 transformedNormal = objectNormal;
313: #ifdef USE_INSTANCING
314: 	mat3 m = mat3( instanceMatrix );
315: 	transformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );
316: 	transformedNormal = m * transformedNormal;
317: #endif
318: transformedNormal = normalMatrix * transformedNormal;
319: #ifdef FLIP_SIDED
320: 	transformedNormal = - transformedNormal;
321: #endif
322: #ifdef USE_TANGENT
323: 	vec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;
324: 	#ifdef FLIP_SIDED
325: 		transformedTangent = - transformedTangent;
326: 	#endif
327: #endif
328: #ifndef FLAT_SHADED
329: 	vNormal = normalize( transformedNormal );
330: 	#ifdef USE_TANGENT
331: 		vTangent = normalize( transformedTangent );
332: 		vBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );
333: 	#endif
334: #endif
335: vec3 transformed = vec3( position );
336: #ifdef USE_MORPHTARGETS
337: 	transformed *= morphTargetBaseInfluence;
338: 	transformed += morphTarget0 * morphTargetInfluences[ 0 ];
339: 	transformed += morphTarget1 * morphTargetInfluences[ 1 ];
340: 	transformed += morphTarget2 * morphTargetInfluences[ 2 ];
341: 	transformed += morphTarget3 * morphTargetInfluences[ 3 ];
342: 	#ifndef USE_MORPHNORMALS
343: 		transformed += morphTarget4 * morphTargetInfluences[ 4 ];
344: 		transformed += morphTarget5 * morphTargetInfluences[ 5 ];
345: 		transformed += morphTarget6 * morphTargetInfluences[ 6 ];
346: 		transformed += morphTarget7 * morphTargetInfluences[ 7 ];
347: 	#endif
348: #endif
349: #ifdef USE_SKINNING
350: 	vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
351: 	vec4 skinned = vec4( 0.0 );
352: 	skinned += boneMatX * skinVertex * skinWeight.x;
353: 	skinned += boneMatY * skinVertex * skinWeight.y;
354: 	skinned += boneMatZ * skinVertex * skinWeight.z;
355: 	skinned += boneMatW * skinVertex * skinWeight.w;
356: 	transformed = ( bindMatrixInverse * skinned ).xyz;
357: #endif
358: #ifdef USE_DISPLACEMENTMAP
359: 	transformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );
360: #endif
361: vec4 mvPosition = vec4( transformed, 1.0 );
362: #ifdef USE_INSTANCING
363: 	mvPosition = instanceMatrix * mvPosition;
364: #endif
365: mvPosition = modelViewMatrix * mvPosition;
366: gl_Position = projectionMatrix * mvPosition;
367: #ifdef USE_LOGDEPTHBUF
368: 	#ifdef USE_LOGDEPTHBUF_EXT
369: 		vFragDepth = 1.0 + gl_Position.w;
370: 		vIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );
371: 	#else
372: 		if ( isPerspectiveMatrix( projectionMatrix ) ) {
373: 			gl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;
374: 			gl_Position.z *= gl_Position.w;
375: 		}
376: 	#endif
377: #endif
378: #if 0 > 0
379: 	vClipPosition = - mvPosition.xyz;
380: #endif
381: 	vViewPosition = - mvPosition.xyz;
382: #if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )
383: 	vec4 worldPosition = vec4( transformed, 1.0 );
384: 	#ifdef USE_INSTANCING
385: 		worldPosition = instanceMatrix * worldPosition;
386: 	#endif
387: 	worldPosition = modelMatrix * worldPosition;
388: #endif
389: #ifdef USE_SHADOWMAP
390: 	#if 0 > 0 || 0 > 0 || 0 > 0
391: 		vec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );
392: 		vec4 shadowWorldPosition;
393: 	#endif
394: 	#if 0 > 0
395: 	
396: 	#endif
397: 	#if 0 > 0
398: 	
399: 	#endif
400: 	#if 0 > 0
401: 	
402: 	#endif
403: #endif
404: #ifdef USE_FOG
405: 	fogDepth = - mvPosition.z;
406: #endif
407: }

Is it possible for you to share a live example that demonstrates the issue?

If not, can you at least share a Collada file that produces the shader error when added to the scene?

Actually, I have now concluded that it isn’t an issue with any one collada file, but with either VRAM or RAM getting a bit full. Upon disabling all textures, the issue goes away. But this obviously creates a new issue.

I would like to note that the issue is avoided simply by setting the material.map property of all loaded objects to null, even without disposing of the map as well.

Indeed. As a first step, consider to lower the resolution of your textures. Another option is to set the minFilter texture property to THREE.LinearFilter which disables the generation of mipmaps (which can allocate a lot of memory). It’s sometimes also possible to merge multiple textures of the same type into a single texture. This requires however a change during the design phase.

Another (slightly advanced) approach is the usage of texture compression. Consider to use glTF instead of Collada which makes it easier to compress textures of assets via dev tools (e.g. via gltfpack). glTF is in general the preferred format for the web.

1 Like