Skip to content

Commit 07b6413

Browse files
committed
Skeleton: Moved useVertexTexture logic to WebGLRenderer. See #10754.
1 parent 2f99f54 commit 07b6413

File tree

8 files changed

+79
-70
lines changed

8 files changed

+79
-70
lines changed

src/Three.Legacy.js

+16
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import { LineSegments } from './objects/LineSegments.js';
6060
import { LOD } from './objects/LOD.js';
6161
import { Points } from './objects/Points.js';
6262
import { Sprite } from './objects/Sprite.js';
63+
import { Skeleton } from './objects/Skeleton.js';
6364
import { WebGLRenderer } from './renderers/WebGLRenderer.js';
6465
import { WebGLRenderTarget } from './renderers/WebGLRenderTarget.js';
6566
import { WebGLShadowMap } from './renderers/webgl/WebGLShadowMap.js';
@@ -760,6 +761,21 @@ Object.defineProperties( LOD.prototype, {
760761

761762
} );
762763

764+
Object.defineProperty( Skeleton.prototype, 'useVertexTexture', {
765+
766+
get: function () {
767+
768+
console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' );
769+
770+
},
771+
set: function () {
772+
773+
console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' );
774+
775+
}
776+
777+
} );
778+
763779
//
764780

765781
PerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {

src/objects/Skeleton.js

+14-41
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
import { Matrix4 } from '../math/Matrix4';
2-
import { FloatType, RGBAFormat } from '../constants';
3-
import { DataTexture } from '../textures/DataTexture';
4-
import { _Math } from '../math/Math';
52

63
/**
74
* @author mikael emtinger / http://gomo.se/
@@ -10,9 +7,7 @@ import { _Math } from '../math/Math';
107
* @author ikerr / http://verold.com
118
*/
129

13-
function Skeleton( bones, boneInverses, useVertexTexture ) {
14-
15-
this.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;
10+
function Skeleton( bones, boneInverses ) {
1611

1712
this.identityMatrix = new Matrix4();
1813

@@ -21,34 +16,7 @@ function Skeleton( bones, boneInverses, useVertexTexture ) {
2116
bones = bones || [];
2217

2318
this.bones = bones.slice( 0 );
24-
25-
// create a bone texture or an array of floats
26-
27-
if ( this.useVertexTexture ) {
28-
29-
// layout (1 matrix = 4 pixels)
30-
// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
31-
// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)
32-
// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)
33-
// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)
34-
// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)
35-
36-
37-
var size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix
38-
size = _Math.nextPowerOfTwo( Math.ceil( size ) );
39-
size = Math.max( size, 4 );
40-
41-
this.boneTextureWidth = size;
42-
this.boneTextureHeight = size;
43-
44-
this.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel
45-
this.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );
46-
47-
} else {
48-
49-
this.boneMatrices = new Float32Array( 16 * this.bones.length );
50-
51-
}
19+
this.boneMatrices = new Float32Array( this.bones.length * 16 );
5220

5321
// use the supplied bone inverses or calculate the inverses
5422

@@ -153,22 +121,27 @@ Object.assign( Skeleton.prototype, {
153121

154122
return function update() {
155123

124+
var bones = this.bones;
125+
var boneInverses = this.boneInverses;
126+
var boneMatrices = this.boneMatrices;
127+
var boneTexture = this.boneTexture;
128+
156129
// flatten bone matrices to array
157130

158-
for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
131+
for ( var b = 0, bl = bones.length; b < bl; b ++ ) {
159132

160133
// compute the offset between the current and the original transform
161134

162-
var matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;
135+
var matrix = bones[ b ] ? bones[ b ].matrixWorld : this.identityMatrix;
163136

164-
offsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );
165-
offsetMatrix.toArray( this.boneMatrices, b * 16 );
137+
offsetMatrix.multiplyMatrices( matrix, boneInverses[ b ] );
138+
offsetMatrix.toArray( boneMatrices, b * 16 );
166139

167140
}
168141

169-
if ( this.useVertexTexture ) {
142+
if ( boneTexture !== undefined ) {
170143

171-
this.boneTexture.needsUpdate = true;
144+
boneTexture.needsUpdate = true;
172145

173146
}
174147

@@ -178,7 +151,7 @@ Object.assign( Skeleton.prototype, {
178151

179152
clone: function () {
180153

181-
return new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );
154+
return new Skeleton( this.bones, this.boneInverses );
182155

183156
}
184157

src/objects/SkinnedMesh.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { Matrix4 } from '../math/Matrix4';
1010
* @author ikerr / http://verold.com
1111
*/
1212

13-
function SkinnedMesh( geometry, material, useVertexTexture ) {
13+
function SkinnedMesh( geometry, material ) {
1414

1515
Mesh.call( this, geometry, material );
1616

@@ -67,7 +67,7 @@ function SkinnedMesh( geometry, material, useVertexTexture ) {
6767
this.normalizeSkinWeights();
6868

6969
this.updateMatrixWorld( true );
70-
this.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );
70+
this.bind( new Skeleton( bones ), this.matrixWorld );
7171

7272
}
7373

@@ -179,7 +179,7 @@ SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
179179

180180
clone: function () {
181181

182-
return new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );
182+
return new this.constructor( this.geometry, this.material ).copy( this );
183183

184184
}
185185

src/renderers/WebGLRenderer.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -1832,11 +1832,10 @@ function WebGLRenderer( parameters ) {
18321832

18331833
if ( skeleton ) {
18341834

1835-
if ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {
1835+
if ( capabilities.floatVertexTextures ) {
18361836

18371837
p_uniforms.set( _gl, skeleton, 'boneTexture' );
1838-
p_uniforms.set( _gl, skeleton, 'boneTextureWidth' );
1839-
p_uniforms.set( _gl, skeleton, 'boneTextureHeight' );
1838+
p_uniforms.set( _gl, skeleton, 'boneTextureSize' );
18401839

18411840
} else {
18421841

src/renderers/shaders/ShaderChunk/skinning_pars_vertex.glsl

+5-6
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,16 @@
66
#ifdef BONE_TEXTURE
77

88
uniform sampler2D boneTexture;
9-
uniform int boneTextureWidth;
10-
uniform int boneTextureHeight;
9+
uniform int boneTextureSize;
1110

1211
mat4 getBoneMatrix( const in float i ) {
1312

1413
float j = i * 4.0;
15-
float x = mod( j, float( boneTextureWidth ) );
16-
float y = floor( j / float( boneTextureWidth ) );
14+
float x = mod( j, float( boneTextureSize ) );
15+
float y = floor( j / float( boneTextureSize ) );
1716

18-
float dx = 1.0 / float( boneTextureWidth );
19-
float dy = 1.0 / float( boneTextureHeight );
17+
float dx = 1.0 / float( boneTextureSize );
18+
float dy = 1.0 / float( boneTextureSize );
2019

2120
y = dy * ( y + 0.5 );
2221

src/renderers/webgl/WebGLProgram.js

-2
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,6 @@ function WebGLProgram( renderer, code, material, parameters ) {
311311

312312
prefixVertex = [
313313

314-
315314
'precision ' + parameters.precision + ' float;',
316315
'precision ' + parameters.precision + ' int;',
317316

@@ -327,7 +326,6 @@ function WebGLProgram( renderer, code, material, parameters ) {
327326
( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
328327
( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',
329328

330-
331329
parameters.map ? '#define USE_MAP' : '',
332330
parameters.envMap ? '#define USE_ENVMAP' : '',
333331
parameters.envMap ? '#define ' + envMapModeDefine : '',

src/renderers/webgl/WebGLPrograms.js

+38-14
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
* @author mrdoob / http://mrdoob.com/
33
*/
44

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';
58
import { WebGLProgram } from './WebGLProgram';
6-
import { BackSide, DoubleSide, FlatShading, CubeUVRefractionMapping, CubeUVReflectionMapping, GammaEncoding, LinearEncoding } from '../../constants';
79

810
function WebGLPrograms( renderer, capabilities ) {
911

@@ -39,7 +41,35 @@ function WebGLPrograms( renderer, capabilities ) {
3941

4042
function allocateBones( object ) {
4143

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+
}
4373

4474
return 1024;
4575

@@ -55,18 +85,12 @@ function WebGLPrograms( renderer, capabilities ) {
5585
var nVertexUniforms = capabilities.maxVertexUniforms;
5686
var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
5787

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 );
6589

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 ) {
6891

69-
}
92+
console.warn( 'THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.' );
93+
return 0;
7094

7195
}
7296

@@ -113,7 +137,7 @@ function WebGLPrograms( renderer, capabilities ) {
113137
// heuristics to create shader parameters according to lights in the scene
114138
// (not to blow over maxLights budget)
115139

116-
var maxBones = allocateBones( object );
140+
var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0;
117141
var precision = renderer.getPrecision();
118142

119143
if ( material.precision !== null ) {
@@ -172,7 +196,7 @@ function WebGLPrograms( renderer, capabilities ) {
172196

173197
skinning: ( object && object.isSkinnedMesh ) && maxBones > 0,
174198
maxBones: maxBones,
175-
useVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,
199+
useVertexTexture: capabilities.floatVertexTextures,
176200

177201
morphTargets: material.morphTargets,
178202
morphNormals: material.morphNormals,

src/textures/DataTexture.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT,
1414
this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
1515
this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
1616

17-
this.generateMipmaps = false;
17+
this.generateMipmaps = false;
1818
this.flipY = false;
1919
this.unpackAlignment = 1;
2020

0 commit comments

Comments
 (0)