I am using three.js 131. I am loading a GLTF file using GLTFLoader.js.
When loading the scene, I iterate through the scene nodes and check to see whether a mesh’s material name contains the string “shadowmat”. If so I replace this with a new instance of THREE.ShadowMaterial. This naming convention scheme is part of our export and loading pipeline. This code looks like this:
if (node.isMesh) {
if (node.material.name.includes("shadowmat")) {
node.material = new THREE.ShadowMaterial();
node.castShadow = false;
node.receiveShadow = true;
}
I find that this scheme works well, unless the mesh is skinned geometry. Then I get this runtime error in the browser when the mesh is rendered:
THREE.WebGLProgram: shader error: 0 35715 false gl.getProgramInfoLog Vertex shader is not compiled.
ERROR: 0:211: 'getBoneMatrix' : no matching overloaded function found
ERROR: 0:211: '=' : dimension mismatch
ERROR: 0:211: '=' : cannot convert from 'const mediump float' to 'highp 4X4 matrix of float'
The error refer to this shader chunk (included from skinbase_vertex.glsl.js)
210: #ifdef USE_SKINNING
211: mat4 boneMatX = getBoneMatrix( skinIndex.x );
212: mat4 boneMatY = getBoneMatrix( skinIndex.y );
213: mat4 boneMatZ = getBoneMatrix( skinIndex.z );
214: mat4 boneMatW = getBoneMatrix( skinIndex.w );
215: #endif
When I look at the full listing of the vertex shader in the Chrome browser console log, both USE_SKINNING and BONE_TEXTURE are defined. However, I don’t see a definition for getBoneMatrix. I believe this should have been included from skinning_pars_vertex.glsl.js.
I suppose this might be a bug in ShadowMaterial.js, in that somehow skinning_pars_vertex.glsl.js is not getting included, or maybe I am not understanding how to set up ShadowMaterial to work properly with skinned geometry.
Below is the vertex shader output from the console log.
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 ShadowMaterial
9: #define USE_SKINNING true
10: #define VERTEX_TEXTURES
11: #define GAMMA_FACTOR 2
12: #define MAX_BONES 1024
13: #define USE_SKINNING
14: #define BONE_TEXTURE
15: #define USE_SHADOWMAP
16: #define SHADOWMAP_TYPE_PCF_SOFT
17: uniform mat4 modelMatrix;
18: uniform mat4 modelViewMatrix;
19: uniform mat4 projectionMatrix;
20: uniform mat4 viewMatrix;
21: uniform mat3 normalMatrix;
22: uniform vec3 cameraPosition;
23: uniform bool isOrthographic;
24: #ifdef USE_INSTANCING
25: attribute mat4 instanceMatrix;
26: #endif
27: #ifdef USE_INSTANCING_COLOR
28: attribute vec3 instanceColor;
29: #endif
30: attribute vec3 position;
31: attribute vec3 normal;
32: attribute vec2 uv;
33: #ifdef USE_TANGENT
34: attribute vec4 tangent;
35: #endif
36: #if defined( USE_COLOR_ALPHA )
37: attribute vec4 color;
38: #elif defined( USE_COLOR )
39: attribute vec3 color;
40: #endif
41: #ifdef USE_MORPHTARGETS
42: attribute vec3 morphTarget0;
43: attribute vec3 morphTarget1;
44: attribute vec3 morphTarget2;
45: attribute vec3 morphTarget3;
46: #ifdef USE_MORPHNORMALS
47: attribute vec3 morphNormal0;
48: attribute vec3 morphNormal1;
49: attribute vec3 morphNormal2;
50: attribute vec3 morphNormal3;
51: #else
52: attribute vec3 morphTarget4;
53: attribute vec3 morphTarget5;
54: attribute vec3 morphTarget6;
55: attribute vec3 morphTarget7;
56: #endif
57: #endif
58: #ifdef USE_SKINNING
59: attribute vec4 skinIndex;
60: attribute vec4 skinWeight;
61: #endif
62:
63: #define PI 3.141592653589793
64: #define PI2 6.283185307179586
65: #define PI_HALF 1.5707963267948966
66: #define RECIPROCAL_PI 0.3183098861837907
67: #define RECIPROCAL_PI2 0.15915494309189535
68: #define EPSILON 1e-6
69: #ifndef saturate
70: #define saturate(a) clamp( a, 0.0, 1.0 )
71: #endif
72: #define whiteComplement(a) ( 1.0 - saturate( a ) )
73: float pow2( const in float x ) { return x*x; }
74: float pow3( const in float x ) { return x*x*x; }
75: float pow4( const in float x ) { float x2 = x*x; return x2*x2; }
76: float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }
77: highp float rand( const in vec2 uv ) {
78: const highp float a = 12.9898, b = 78.233, c = 43758.5453;
79: highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );
80: return fract(sin(sn) * c);
81: }
82: #ifdef HIGH_PRECISION
83: float precisionSafeLength( vec3 v ) { return length( v ); }
84: #else
85: float max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }
86: float precisionSafeLength( vec3 v ) {
87: float maxComponent = max3( abs( v ) );
88: return length( v / maxComponent ) * maxComponent;
89: }
90: #endif
91: struct IncidentLight {
92: vec3 color;
93: vec3 direction;
94: bool visible;
95: };
96: struct ReflectedLight {
97: vec3 directDiffuse;
98: vec3 directSpecular;
99: vec3 indirectDiffuse;
100: vec3 indirectSpecular;
101: };
102: struct GeometricContext {
103: vec3 position;
104: vec3 normal;
105: vec3 viewDir;
106: #ifdef CLEARCOAT
107: vec3 clearcoatNormal;
108: #endif
109: };
110: vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
111: return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
112: }
113: vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {
114: return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );
115: }
116: vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
117: float distance = dot( planeNormal, point - pointOnPlane );
118: return - distance * planeNormal + point;
119: }
120: float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
121: return sign( dot( point - pointOnPlane, planeNormal ) );
122: }
123: vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {
124: return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;
125: }
126: mat3 transposeMat3( const in mat3 m ) {
127: mat3 tmp;
128: tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );
129: tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );
130: tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );
131: return tmp;
132: }
133: float linearToRelativeLuminance( const in vec3 color ) {
134: vec3 weights = vec3( 0.2126, 0.7152, 0.0722 );
135: return dot( weights, color.rgb );
136: }
137: bool isPerspectiveMatrix( mat4 m ) {
138: return m[ 2 ][ 3 ] == - 1.0;
139: }
140: vec2 equirectUv( in vec3 dir ) {
141: float u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;
142: float v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;
143: return vec2( u, v );
144: }
145: #ifdef USE_FOG
146: varying float fogDepth;
147: #endif
148: #ifdef USE_SHADOWMAP
149: #if 1 > 0
150: uniform mat4 directionalShadowMatrix[ 1 ];
151: varying vec4 vDirectionalShadowCoord[ 1 ];
152: struct DirectionalLightShadow {
153: float shadowBias;
154: float shadowNormalBias;
155: float shadowRadius;
156: vec2 shadowMapSize;
157: };
158: uniform DirectionalLightShadow directionalLightShadows[ 1 ];
159: #endif
160: #if 0 > 0
161: uniform mat4 spotShadowMatrix[ 0 ];
162: varying vec4 vSpotShadowCoord[ 0 ];
163: struct SpotLightShadow {
164: float shadowBias;
165: float shadowNormalBias;
166: float shadowRadius;
167: vec2 shadowMapSize;
168: };
169: uniform SpotLightShadow spotLightShadows[ 0 ];
170: #endif
171: #if 0 > 0
172: uniform mat4 pointShadowMatrix[ 0 ];
173: varying vec4 vPointShadowCoord[ 0 ];
174: struct PointLightShadow {
175: float shadowBias;
176: float shadowNormalBias;
177: float shadowRadius;
178: vec2 shadowMapSize;
179: float shadowCameraNear;
180: float shadowCameraFar;
181: };
182: uniform PointLightShadow pointLightShadows[ 0 ];
183: #endif
184: #endif
185: void main() {
186: vec3 transformed = vec3( position );
187: vec4 mvPosition = vec4( transformed, 1.0 );
188: #ifdef USE_INSTANCING
189: mvPosition = instanceMatrix * mvPosition;
190: #endif
191: mvPosition = modelViewMatrix * mvPosition;
192: gl_Position = projectionMatrix * mvPosition;
193: #if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION )
194: vec4 worldPosition = vec4( transformed, 1.0 );
195: #ifdef USE_INSTANCING
196: worldPosition = instanceMatrix * worldPosition;
197: #endif
198: worldPosition = modelMatrix * worldPosition;
199: #endif
200: vec3 objectNormal = vec3( normal );
201: #ifdef USE_TANGENT
202: vec3 objectTangent = vec3( tangent.xyz );
203: #endif
204: #ifdef USE_MORPHNORMALS
205: objectNormal *= morphTargetBaseInfluence;
206: objectNormal += morphNormal0 * morphTargetInfluences[ 0 ];
207: objectNormal += morphNormal1 * morphTargetInfluences[ 1 ];
208: objectNormal += morphNormal2 * morphTargetInfluences[ 2 ];
209: objectNormal += morphNormal3 * morphTargetInfluences[ 3 ];
210: #endif
211: #ifdef USE_SKINNING
212: mat4 boneMatX = getBoneMatrix( skinIndex.x );
213: mat4 boneMatY = getBoneMatrix( skinIndex.y );
214: mat4 boneMatZ = getBoneMatrix( skinIndex.z );
215: mat4 boneMatW = getBoneMatrix( skinIndex.w );
216: #endif
217: #ifdef USE_SKINNING
218: mat4 skinMatrix = mat4( 0.0 );
219: skinMatrix += skinWeight.x * boneMatX;
220: skinMatrix += skinWeight.y * boneMatY;
221: skinMatrix += skinWeight.z * boneMatZ;
222: skinMatrix += skinWeight.w * boneMatW;
223: skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;
224: objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;
225: #ifdef USE_TANGENT
226: objectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;
227: #endif
228: #endif
229: vec3 transformedNormal = objectNormal;
230: #ifdef USE_INSTANCING
231: mat3 m = mat3( instanceMatrix );
232: transformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );
233: transformedNormal = m * transformedNormal;
234: #endif
235: transformedNormal = normalMatrix * transformedNormal;
236: #ifdef FLIP_SIDED
237: transformedNormal = - transformedNormal;
238: #endif
239: #ifdef USE_TANGENT
240: vec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;
241: #ifdef FLIP_SIDED
242: transformedTangent = - transformedTangent;
243: #endif
244: #endif
245: #ifdef USE_SHADOWMAP
246: #if 1 > 0 || 0 > 0 || 0 > 0
247: vec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );
248: vec4 shadowWorldPosition;
249: #endif
250: #if 1 > 0
251:
252: shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ 0 ].shadowNormalBias, 0 );
253: vDirectionalShadowCoord[ 0 ] = directionalShadowMatrix[ 0 ] * shadowWorldPosition;
254:
255: #endif
256: #if 0 > 0
257:
258: #endif
259: #if 0 > 0
260:
261: #endif
262: #endif
263: #ifdef USE_FOG
264: fogDepth = - mvPosition.z;
265: #endif
266: }