解决方法
three.js实际上是想帮你一个忙.
由于它是开源的,我们可以读取WebGLRenderer.js的源代码,并看到setTexture方法调用(非公共可见)方法uploadTexture.
后者有这个检查:
if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ){ image = makePowerOfTwo( image ); }
这本身就很明确.
您现在可能想知道textureNeedsPowerOfTwo实际检查了什么.让我们来看看.
function textureNeedsPowerOfTwo( texture ) { if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) return true; if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) return true; return false; }
如果使用包装来匹配与夹具不同的纹理,或者如果使用不是最近也不是线性的过滤,则纹理会缩放.
如果您对此代码感到惊讶,我强烈建议您查看MDN page on using textures.
引用
The catch: these textures [Non Power Of Two textures] cannot be used with mipmapping and they must not “repeat” (tile or wrap).
[…]
Without performing the above configuration,WebGL requires all samples of NPOT [Non Power Of Two] textures to fail by returning solid black: rgba(0,1).
因此,使用具有不正确纹理参数的NPOT纹理将为您提供良好的旧实心黑色.
由于three.js是开源的,因此您可以编辑本地副本并删除“违规”检查.
然而,更简单,更简单且更易于维护的方法是简单地缩放UV映射.毕竟它只是针对这个用例.