@@ -6847,6 +6847,12 @@ THREE.Math = {
6847
6847
6848
6848
},
6849
6849
6850
+ nearestPowerOfTwo: function ( value ) {
6851
+
6852
+ return Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );
6853
+
6854
+ },
6855
+
6850
6856
nextPowerOfTwo: function ( value ) {
6851
6857
6852
6858
value --;
@@ -22341,7 +22347,7 @@ THREE.WebGLRenderer = function ( parameters ) {
22341
22347
if ( renderTarget ) {
22342
22348
22343
22349
var texture = renderTarget.texture;
22344
- var isTargetPowerOfTwo = THREE.Math. isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height );
22350
+ var isTargetPowerOfTwo = isPowerOfTwo( renderTarget );
22345
22351
if ( texture.generateMipmaps && isTargetPowerOfTwo && texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) {
22346
22352
22347
22353
updateRenderTargetMipmap( renderTarget );
@@ -23897,8 +23903,14 @@ THREE.WebGLRenderer = function ( parameters ) {
23897
23903
23898
23904
texture.image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
23899
23905
23906
+ if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false ) {
23907
+
23908
+ texture.image = makePowerOfTwo( texture.image );
23909
+
23910
+ }
23911
+
23900
23912
var image = texture.image,
23901
- isImagePowerOfTwo = THREE.Math. isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
23913
+ isImagePowerOfTwo = isPowerOfTwo( image ), // TODO: Always true at this step?
23902
23914
glFormat = paramThreeToGL( texture.format ),
23903
23915
glType = paramThreeToGL( texture.type );
23904
23916
@@ -24048,6 +24060,36 @@ THREE.WebGLRenderer = function ( parameters ) {
24048
24060
24049
24061
}
24050
24062
24063
+ function isPowerOfTwo( image ) {
24064
+
24065
+ return THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height );
24066
+
24067
+ }
24068
+
24069
+ function textureNeedsPowerOfTwo( texture ) {
24070
+
24071
+ if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) return true;
24072
+ if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) return true;
24073
+
24074
+ return false;
24075
+
24076
+ }
24077
+
24078
+ function makePowerOfTwo( image ) {
24079
+
24080
+ var canvas = document.createElement( 'canvas' );
24081
+ canvas.width = THREE.Math.nearestPowerOfTwo( image.width );
24082
+ canvas.height = THREE.Math.nearestPowerOfTwo( image.height );
24083
+
24084
+ var context = canvas.getContext( '2d' );
24085
+ context.drawImage( image, 0, 0, canvas.width, canvas.height );
24086
+
24087
+ console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
24088
+
24089
+ return canvas;
24090
+
24091
+ }
24092
+
24051
24093
function setCubeTexture ( texture, slot ) {
24052
24094
24053
24095
var textureProperties = properties.get( texture );
@@ -24091,7 +24133,7 @@ THREE.WebGLRenderer = function ( parameters ) {
24091
24133
}
24092
24134
24093
24135
var image = cubeImage[ 0 ],
24094
- isImagePowerOfTwo = THREE.Math. isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
24136
+ isImagePowerOfTwo = isPowerOfTwo( image ),
24095
24137
glFormat = paramThreeToGL( texture.format ),
24096
24138
glType = paramThreeToGL( texture.type );
24097
24139
@@ -24229,7 +24271,7 @@ THREE.WebGLRenderer = function ( parameters ) {
24229
24271
24230
24272
// Setup texture, create render and frame buffers
24231
24273
24232
- var isTargetPowerOfTwo = THREE.Math. isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height ),
24274
+ var isTargetPowerOfTwo = isPowerOfTwo( renderTarget ),
24233
24275
glFormat = paramThreeToGL( renderTarget.texture.format ),
24234
24276
glType = paramThreeToGL( renderTarget.texture.type );
24235
24277
0 commit comments