Skip to content

Commit ff3465c

Browse files
committed
WebGLRenderer: Convert to power of two textures that require it instead of giving wrap/minFilter warnings.
1 parent 36f4f45 commit ff3465c

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

src/math/Math.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ THREE.Math = {
152152

153153
},
154154

155+
nearestPowerOfTwo: function ( value ) {
156+
157+
return Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );
158+
159+
},
160+
155161
nextPowerOfTwo: function ( value ) {
156162

157163
value --;

src/renderers/WebGLRenderer.js

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,7 +1168,7 @@ THREE.WebGLRenderer = function ( parameters ) {
11681168
if ( renderTarget ) {
11691169

11701170
var texture = renderTarget.texture;
1171-
var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height );
1171+
var isTargetPowerOfTwo = isPowerOfTwo( renderTarget );
11721172
if ( texture.generateMipmaps && isTargetPowerOfTwo && texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) {
11731173

11741174
updateRenderTargetMipmap( renderTarget );
@@ -2724,8 +2724,14 @@ THREE.WebGLRenderer = function ( parameters ) {
27242724

27252725
texture.image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
27262726

2727+
if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false ) {
2728+
2729+
texture.image = makePowerOfTwo( texture.image );
2730+
2731+
}
2732+
27272733
var image = texture.image,
2728-
isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
2734+
isImagePowerOfTwo = isPowerOfTwo( image ), // TODO: Always true at this step?
27292735
glFormat = paramThreeToGL( texture.format ),
27302736
glType = paramThreeToGL( texture.type );
27312737

@@ -2875,6 +2881,36 @@ THREE.WebGLRenderer = function ( parameters ) {
28752881

28762882
}
28772883

2884+
function isPowerOfTwo( image ) {
2885+
2886+
return THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height );
2887+
2888+
}
2889+
2890+
function textureNeedsPowerOfTwo( texture ) {
2891+
2892+
if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) return true;
2893+
if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) return true;
2894+
2895+
return false;
2896+
2897+
}
2898+
2899+
function makePowerOfTwo( image ) {
2900+
2901+
var canvas = document.createElement( 'canvas' );
2902+
canvas.width = THREE.Math.nearestPowerOfTwo( image.width );
2903+
canvas.height = THREE.Math.nearestPowerOfTwo( image.height );
2904+
2905+
var context = canvas.getContext( '2d' );
2906+
context.drawImage( image, 0, 0, canvas.width, canvas.height );
2907+
2908+
console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
2909+
2910+
return canvas;
2911+
2912+
}
2913+
28782914
function setCubeTexture ( texture, slot ) {
28792915

28802916
var textureProperties = properties.get( texture );
@@ -2918,7 +2954,7 @@ THREE.WebGLRenderer = function ( parameters ) {
29182954
}
29192955

29202956
var image = cubeImage[ 0 ],
2921-
isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
2957+
isImagePowerOfTwo = isPowerOfTwo( image ),
29222958
glFormat = paramThreeToGL( texture.format ),
29232959
glType = paramThreeToGL( texture.type );
29242960

@@ -3056,7 +3092,7 @@ THREE.WebGLRenderer = function ( parameters ) {
30563092

30573093
// Setup texture, create render and frame buffers
30583094

3059-
var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height ),
3095+
var isTargetPowerOfTwo = isPowerOfTwo( renderTarget ),
30603096
glFormat = paramThreeToGL( renderTarget.texture.format ),
30613097
glType = paramThreeToGL( renderTarget.texture.type );
30623098

0 commit comments

Comments
 (0)