1

I have a javascript piece which loads an image:

var loader = new THREE.TextureLoader();
loader.load( 'textures/canvas1.png', function ( texture ) {
    var geometry = new THREE.SphereGeometry( 200, 20, 20 );
    var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
    var mesh = new THREE.Mesh( geometry, material );
    group.add( mesh );
} );

and works fine. Now, however, I do not want to load an image but a dynamically created image map, created as follows:

var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var image = context.createImageData(map_width, map_height);
var data = image.data;               
var scale = 5.18;
for (var x = 0; x < map_width; x++) {                  
    for (var y = 0; y < map_height; y++) {
        var nx = x/map_width-0.5;
        var ny = y/map_height-0.5;                    
        var value = Math.abs(noise.perlin2(scale*nx, scale * ny));
        value *= 256;

        var cell = (x + y * map_width) * 4;                    
        data[cell] = data[cell + 1] = data[cell + 2] = Math.pow(1.2, value);                              
        data[cell + 3] = 255; // alpha.                                    
    }
}

I tried the following piece of code (including to create a Uint8Array as suggested in the comments), but all I get is a complete black sphere:

var buffer = new ArrayBuffer(data.length);
var udata = new Uint8Array(buffer);
for (var i=0; i<data.length; i++) {
    udata[i] = data[i];     
}

var geometry = new THREE.SphereGeometry( 200, 20, 20 );
var texture = new THREE.DataTexture(udata, map_width, map_height, THREE.RGBAFormat );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
var mesh = new THREE.Mesh( geometry, material );
group.add( mesh );

Maybe the data must be given in a different format?

8
  • This guy seems to managed to do what you're trying to do. Commented Nov 5, 2015 at 16:04
  • According to this answer, you need to pass an Uint8Array, not an ImageData object. Commented Nov 5, 2015 at 17:54
  • I create an Uint8Array and filled it with my data, and still get a black sphere. Commented Nov 9, 2015 at 12:10
  • I updated my question with the new array. Commented Nov 9, 2015 at 13:46
  • 1
    @Alex (1) Add texture.needsUpdate = true; (2) Why are you setting overdraw? Commented Nov 9, 2015 at 15:56

1 Answer 1

2

Here is the pattern to follow to create a DataTexture and use it as the map for your material:

var data = new Uint8Array( 4 * size );

// initialize data. . .

var texture = new THREE.DataTexture( data, width, height, THREE.RGBAFormat );

texture.type = THREE.UnsignedByteType;

var material = new THREE.MeshBasicMaterial( { map: texture } );

var mesh = new THREE.Mesh( geometry, material );

scene.add( mesh );

three.js r.128

Sign up to request clarification or add additional context in comments.

1 Comment

Where is the reference to the image data? Seems like this would create an empty texture...?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.