最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - "THREE.NearestFilter" or "THREE.LinearFilter" Causes the Black Plane - Stack Ov

programmeradmin2浏览0评论

While I was working with THREE.js library, I got that kind of notification:

THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.

So, I tried to fix it. It works, when I put the filter:

var groundGeometry = new THREE.PlaneBufferGeometry( 5000, 5000, 96, 96 );
var grassTexture = THREE.ImageUtils.loadTexture("images/grass.jpg");
grassTexture.minFilter = THREE.LinearFilter;//here is the filter
var groundMaterial = new THREE.MeshBasicMaterial( {map: grassTexture, side: THREE.DoubleSide} );
var groundPlane = new THREE.Mesh(groundGeometry, groundMaterial);
scene.add( groundPlane );

However, I tried another way, but at the end I got just the black plane:

var groundGeometry = new THREE.PlaneBufferGeometry( 5000, 5000, 96, 96 );
var groundMaterial = new THREE.MeshBasicMaterial( {map: THREE.ImageUtils.loadTexture({image: "images/grass.jpg", minFilter: THREE.LinearFilter}), side: THREE.DoubleSide} );
var groundPlane = new THREE.Mesh(groundGeometry, groundMaterial);
scene.add( groundPlane );

While I was working with THREE.js library, I got that kind of notification:

THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.

So, I tried to fix it. It works, when I put the filter:

var groundGeometry = new THREE.PlaneBufferGeometry( 5000, 5000, 96, 96 );
var grassTexture = THREE.ImageUtils.loadTexture("images/grass.jpg");
grassTexture.minFilter = THREE.LinearFilter;//here is the filter
var groundMaterial = new THREE.MeshBasicMaterial( {map: grassTexture, side: THREE.DoubleSide} );
var groundPlane = new THREE.Mesh(groundGeometry, groundMaterial);
scene.add( groundPlane );

However, I tried another way, but at the end I got just the black plane:

var groundGeometry = new THREE.PlaneBufferGeometry( 5000, 5000, 96, 96 );
var groundMaterial = new THREE.MeshBasicMaterial( {map: THREE.ImageUtils.loadTexture({image: "images/grass.jpg", minFilter: THREE.LinearFilter}), side: THREE.DoubleSide} );
var groundPlane = new THREE.Mesh(groundGeometry, groundMaterial);
scene.add( groundPlane );
Share Improve this question edited Jun 29, 2015 at 23:56 Darius Miliauskas asked Jun 29, 2015 at 23:45 Darius MiliauskasDarius Miliauskas 3,5344 gold badges39 silver badges54 bronze badges 1
  • Sorry, I edited the title and the question itself, since I got that my mistake was due to a small type error "grassTexture.minFilter = THREE.linearFilter;" instead of "grassTexture.minFilter = THREE.LinearFilter;". But the second case is still not clear, so, I modified the question to make sense for the reader. – Darius Miliauskas Commented Jun 29, 2015 at 23:56
Add a ment  | 

2 Answers 2

Reset to default 3

You are getting a black plane in the second case because you are not passing the proper arguments to THREE.ImageUtils.loadTexture(). You are passing an object {}. You would have to do something like this:

var groundMaterial = new THREE.MeshBasicMaterial( { 
    map: THREE.ImageUtils.loadTexture( "images/grass.jpg" ),
    side: THREE.DoubleSide
} );
groundMaterial.map.minFilter = THREE.LinearFilter;

It is true that the texture loading is asynchronous, but without knowing the rest of your code, it cannot be determined if that is an issue here.

BTW, you likely do not need 18,000 faces in your PlaneBufferGeometry. Try

groundGeometry = new THREE.PlaneBufferGeometry( 5000, 5000, 1, 1 );

three.js r.71

The texture is not downloaded and ready for use when you think it is.

In the first case the second statement requests an asynchronous loading of the texture. Two statements later the texture is assigned to a variable. It works just by luck.

In the second case you download and assign a texture all in one statement. Hardly enough time for the texture to be downloaded.

The proper way: (taken from http://threejs/docs/#Reference/Loaders/ImageLoader)

var groundMaterial;
...
// instantiate a loader
var loader = new THREE.ImageLoader();

// load a image resource
loader.load(
    // resource URL
    'images/grass.jpg',

    // Function when resource is loaded
    function ( image ) {
        // here you are guaranteed that the texture has downloaded so you can do something with it.
        groundMaterial = new THREE.MeshBasicMaterial( {map: image, side: THREE.DoubleSide} );
} );
发布评论

评论列表(0)

  1. 暂无评论