2
2
* @author mrdoob / http://mrdoob.com/
3
3
*/
4
4
5
+ import { BackSide , DoubleSide , FlatShading , CubeUVRefractionMapping , CubeUVReflectionMapping , GammaEncoding , LinearEncoding , FloatType , RGBAFormat } from '../../constants' ;
6
+ import { _Math } from '../../math/Math' ;
7
+ import { DataTexture } from '../../textures/DataTexture' ;
5
8
import { WebGLProgram } from './WebGLProgram' ;
6
- import { BackSide , DoubleSide , FlatShading , CubeUVRefractionMapping , CubeUVReflectionMapping , GammaEncoding , LinearEncoding } from '../../constants' ;
7
9
8
10
function WebGLPrograms ( renderer , capabilities ) {
9
11
@@ -39,7 +41,35 @@ function WebGLPrograms( renderer, capabilities ) {
39
41
40
42
function allocateBones ( object ) {
41
43
42
- if ( capabilities . floatVertexTextures && object && object . skeleton && object . skeleton . useVertexTexture ) {
44
+ var skeleton = object . skeleton ;
45
+ var bones = skeleton . bones ;
46
+
47
+ if ( capabilities . floatVertexTextures ) {
48
+
49
+ if ( skeleton . boneTexture === undefined ) {
50
+
51
+ // layout (1 matrix = 4 pixels)
52
+ // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
53
+ // with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)
54
+ // 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)
55
+ // 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)
56
+ // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)
57
+
58
+
59
+ var size = Math . sqrt ( bones . length * 4 ) ; // 4 pixels needed for 1 matrix
60
+ size = _Math . nextPowerOfTwo ( Math . ceil ( size ) ) ;
61
+ size = Math . max ( size , 4 ) ;
62
+
63
+ var boneMatrices = new Float32Array ( size * size * 4 ) ; // 4 floats per RGBA pixel
64
+ boneMatrices . set ( skeleton . boneMatrices ) ; // copy current values
65
+
66
+ var boneTexture = new DataTexture ( boneMatrices , size , size , RGBAFormat , FloatType ) ;
67
+
68
+ skeleton . boneMatrices = boneMatrices ;
69
+ skeleton . boneTexture = boneTexture ;
70
+ skeleton . boneTextureSize = size ;
71
+
72
+ }
43
73
44
74
return 1024 ;
45
75
@@ -55,18 +85,12 @@ function WebGLPrograms( renderer, capabilities ) {
55
85
var nVertexUniforms = capabilities . maxVertexUniforms ;
56
86
var nVertexMatrices = Math . floor ( ( nVertexUniforms - 20 ) / 4 ) ;
57
87
58
- var maxBones = nVertexMatrices ;
59
-
60
- if ( object && object . isSkinnedMesh ) {
61
-
62
- maxBones = Math . min ( object . skeleton . bones . length , maxBones ) ;
63
-
64
- if ( maxBones < object . skeleton . bones . length ) {
88
+ var maxBones = Math . min ( nVertexMatrices , bones . length ) ;
65
89
66
- console . warn ( 'WebGLRenderer: too many bones - ' + object . skeleton . bones . length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' ) ;
67
- return 0 ;
90
+ if ( maxBones < bones . length ) {
68
91
69
- }
92
+ console . warn ( 'THREE.WebGLRenderer: Skeleton has ' + bones . length + ' bones. This GPU supports ' + maxBones + '.' ) ;
93
+ return 0 ;
70
94
71
95
}
72
96
@@ -113,7 +137,7 @@ function WebGLPrograms( renderer, capabilities ) {
113
137
// heuristics to create shader parameters according to lights in the scene
114
138
// (not to blow over maxLights budget)
115
139
116
- var maxBones = allocateBones ( object ) ;
140
+ var maxBones = object . isSkinnedMesh ? allocateBones ( object ) : 0 ;
117
141
var precision = renderer . getPrecision ( ) ;
118
142
119
143
if ( material . precision !== null ) {
@@ -172,7 +196,7 @@ function WebGLPrograms( renderer, capabilities ) {
172
196
173
197
skinning : ( object && object . isSkinnedMesh ) && maxBones > 0 ,
174
198
maxBones : maxBones ,
175
- useVertexTexture : capabilities . floatVertexTextures && object && object . skeleton && object . skeleton . useVertexTexture ,
199
+ useVertexTexture : capabilities . floatVertexTextures ,
176
200
177
201
morphTargets : material . morphTargets ,
178
202
morphNormals : material . morphNormals ,
0 commit comments