EaselJS and SpriteSheet - sprite-sheet

I'm simply trying to get each frame in a sprite sheet but all I keep getting is the first frame, here's the code:
function handleImageLoaded(e)
{
var c = new Container();
var d = { };
var l = rx * ry;
var lh = canvas.height / ry;
var lw = canvas.width / rx;
var lx = 0;
var ly = 0;
var s;
var t;
d.images = [ e.target ];
d.frames = { width: lw, height: lh, count: l };
s = new SpriteSheet( d );
for ( var i = 0; i < l; i++ )
{
t = new Bitmap( s.getFrame( i ).image );
t.x = lx++ * lw;
t.y = ( lx == rx ? ly++ : ly ) * lh;
lx = lx == rx ? 0 : lx;
c.addChild( t );
}
stage.addChild( c );
stage.update();
}
I would stick this up on a fiddle but there'd be cross domain issues with the image.

try SpriteSheetUtils.exractFrame (see SpriteSheetUtils). It does exactly what you do in your custom code.

The issue in your code is that the frame.image property points to the source bitmap, which is the same for all frames in the spritesheet (unless you have a multi-image spritesheet).
To display a frame from a spritesheet, use Sprite. For example, modifying your code:
for ( var i = 0; i < l; i++ )
{
t = new Sprite(spriteSheet, i);
t.x = lx++ * lw;
t.y = ( lx == rx ? ly++ : ly ) * lh;
lx = lx == rx ? 0 : lx;
c.addChild( t );
}

Well, while I wasn't able to fix the problem with EaselJS, I just worked around it. I created a function that replicated the getFrame function that EaselJS's sprite stuff was meant to do, here it is:
function generateTile(p, i)
{
var cs = document.createElement( 'canvas' );
var c = cs.getContext( '2d' );
cs.height = p[ 3 ];
cs.width = p[ 2 ];
c.drawImage( i, p[ 0 ], p[ 1 ], p[ 2 ], p[ 3 ], 0, 0, p[ 2 ], p[ 3 ] );
return new Bitmap( cs );
}

Related

How do you achieve text scrolling inside a canvas

I have the code below which renders a text on canvas, that refracts to the 3D object, I want to make the text scroll with the mouse wheel either using translate but cannot seem to make it bind, is there a way to achieve that?
I have done word wrap with lineheight and make the font text not blurry on HD Monitors on the different functions but cannot seem to achieve the scrolling only, any help would be much appreciated thank you.
function printAtWordWrap(context, text, x, y, lineHeight, fitWidth) {
fitWidth = fitWidth || 0;
if (fitWidth <= 0) {
context.fillText(text, x, y);
return;
}
var words = text.split(' ');
var currentLine = 0;
var idx = 1;
while (words.length > 0 && idx <= words.length) {
var str = words.slice(0, idx).join(' ');
var w = context.measureText(str).width;
if (w > fitWidth) {
if (idx == 1) {
idx = 2;
}
context.fillText(words.slice(0, idx - 1).join(' '), x, y + (lineHeight * currentLine));
currentLine++;
words = words.splice(idx - 1);
idx = 1;
} else {
idx++;
}
}
if (idx > 0)
context.fillText(words.join(' '), x, y + (lineHeight * currentLine));
}
var PIXEL_RATIO = (function() {
var ctx = document.createElement("canvas").getContext("2d"),
dpr = window.devicePixelRatio || 1,
bsr = ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1;
return dpr / bsr;
})();
let can;
function createHiDPICanvas(w, h, ratio) {
if (!ratio) {
ratio = PIXEL_RATIO;
}
can = document.createElement('canvas');
can.width = w * ratio;
can.height = h * ratio;
can.style.width = w + "px";
can.style.height = h + "px";
can.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
return can;
}
//Create canvas with a custom resolution.
if (window.devicePixelRatio > 1) {
var myCanvas = createHiDPICanvas(window.innerWidth, window.innerHeight, 4);
} else {
var myCanvas = createHiDPICanvas(window.innerWidth, window.innerHeight, 2);
}
var ctx = myCanvas.getContext('2d', {
alpha: false,
antialias: false
});
let x = window.innerWidth / 2;
var y = window.innerHeight / 2;
ctx.translate(0, 200);
const font = new FontFace("MyCanvasFont", "url(https://use.typekit.net/af/2759ad/00000000000000007735a2d2/30/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n3&v=3)");
document.fonts.add(font);
ctx.font = '300 150px "MyCanvasFont"';
ctx.fillStyle = 'white';
ctx.textAlign = 'center';
var txt = 'CONNECTING BRANDS TO HUMANS THROUGH CULTURE, DESIGN AND TECHNOLOGY';
printAtWordWrap(ctx, txt, x, y, 120, window.innerWidth / 2);
The main point is: You need know how the first line to show. You can use a param to control this.
function printAtWordWrap(context, text, x, y, lineHeight, fitWidth, line)
control what line can show:
if(currentLine >= line){
//remove line value of currentline
context.fillText(words.slice(0, idx - 1).join(' '), x, y + (lineHeight * (currentLine - line) )); }
Note that ai remove line value of currentLin to up in canvas position.
Look my project: https://codepen.io/Luis4raujo/pen/xxRrmoE
If you can up lines instead hide, you need remove if statement (line 24)
If this answer help you, vote or check as correnct!

Apply gradient to BufferGeometry vertices

I have an animation that uses a BufferGeometry to create a grid of particles which are then animated using Perlin noise. That all works perfectly but the final thing to do is to apply a gradient across the grid. I have tried everything I have found and nothing is working. I feel like using a ShaderMaterial is the best/easiest solution but the code I've found for gradients just isn't working so I'm asking what the best way to do this is and ideally an example of how to do it.
Here is a link to the codepen so you can see all of the code and the example working.
https://codepen.io/JJGerrish/pen/oNxyJXX?editors=0010
And here is an example of the what I want the grid to look like.
I've left my attempt at creating a gradient shader in so you are welcome to play around with that or come up with a better solution.
Your problem is that you are using uVu.y , but you don't have any uv coordinates so the value will always be 0.
Are you sure you don't want to be using the position x value?
gl_FragColor = vec4(mix(color1, color2, smoothstep(-10.0, 10.0, pos.x)), 1.0);
(demo in code below with a smoothstep, note sending the pos variable from the vertex to fragment shader).
Also, why not do the noise in the shader too rather than in the JS?
//noise library
/*
* A speed-improved perlin and simplex noise algorithms for 2D.
*
* Based on example code by Stefan Gustavson (stegu#itn.liu.se).
* Optimisations by Peter Eastman (peastman#drizzle.stanford.edu).
* Better rank ordering method by Stefan Gustavson in 2012.
* Converted to Javascript by Joseph Gentle.
*
* Version 2012-03-09
*
* This code was placed in the public domain by its original author,
* Stefan Gustavson. You may use it as you see fit, but
* attribution is appreciated.
*
*/
(function(global){
var module = global.noise = {};
function Grad(x, y, z) {
this.x = x; this.y = y; this.z = z;
}
Grad.prototype.dot2 = function(x, y) {
return this.x*x + this.y*y;
};
Grad.prototype.dot3 = function(x, y, z) {
return this.x*x + this.y*y + this.z*z;
};
var grad3 = [new Grad(1,1,0),new Grad(-1,1,0),new Grad(1,-1,0),new Grad(-1,-1,0),
new Grad(1,0,1),new Grad(-1,0,1),new Grad(1,0,-1),new Grad(-1,0,-1),
new Grad(0,1,1),new Grad(0,-1,1),new Grad(0,1,-1),new Grad(0,-1,-1)];
var p = [151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180];
// To remove the need for index wrapping, double the permutation table length
var perm = new Array(512);
var gradP = new Array(512);
// This isn't a very good seeding function, but it works ok. It supports 2^16
// different seed values. Write something better if you need more seeds.
module.seed = function(seed) {
if(seed > 0 && seed < 1) {
// Scale the seed out
seed *= 65536;
}
seed = Math.floor(seed);
if(seed < 256) {
seed |= seed << 8;
}
for(var i = 0; i < 256; i++) {
var v;
if (i & 1) {
v = p[i] ^ (seed & 255);
} else {
v = p[i] ^ ((seed>>8) & 255);
}
perm[i] = perm[i + 256] = v;
gradP[i] = gradP[i + 256] = grad3[v % 12];
}
};
module.seed(0);
/*
for(var i=0; i<256; i++) {
perm[i] = perm[i + 256] = p[i];
gradP[i] = gradP[i + 256] = grad3[perm[i] % 12];
}*/
// Skewing and unskewing factors for 2, 3, and 4 dimensions
var F2 = 0.5*(Math.sqrt(3)-1);
var G2 = (3-Math.sqrt(3))/6;
var F3 = 1/3;
var G3 = 1/6;
// 2D simplex noise
module.simplex2 = function(xin, yin) {
var n0, n1, n2; // Noise contributions from the three corners
// Skew the input space to determine which simplex cell we're in
var s = (xin+yin)*F2; // Hairy factor for 2D
var i = Math.floor(xin+s);
var j = Math.floor(yin+s);
var t = (i+j)*G2;
var x0 = xin-i+t; // The x,y distances from the cell origin, unskewed.
var y0 = yin-j+t;
// For the 2D case, the simplex shape is an equilateral triangle.
// Determine which simplex we are in.
var i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
if(x0>y0) { // lower triangle, XY order: (0,0)->(1,0)->(1,1)
i1=1; j1=0;
} else { // upper triangle, YX order: (0,0)->(0,1)->(1,1)
i1=0; j1=1;
}
// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
// c = (3-sqrt(3))/6
var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
var y1 = y0 - j1 + G2;
var x2 = x0 - 1 + 2 * G2; // Offsets for last corner in (x,y) unskewed coords
var y2 = y0 - 1 + 2 * G2;
// Work out the hashed gradient indices of the three simplex corners
i &= 255;
j &= 255;
var gi0 = gradP[i+perm[j]];
var gi1 = gradP[i+i1+perm[j+j1]];
var gi2 = gradP[i+1+perm[j+1]];
// Calculate the contribution from the three corners
var t0 = 0.5 - x0*x0-y0*y0;
if(t0<0) {
n0 = 0;
} else {
t0 *= t0;
n0 = t0 * t0 * gi0.dot2(x0, y0); // (x,y) of grad3 used for 2D gradient
}
var t1 = 0.5 - x1*x1-y1*y1;
if(t1<0) {
n1 = 0;
} else {
t1 *= t1;
n1 = t1 * t1 * gi1.dot2(x1, y1);
}
var t2 = 0.5 - x2*x2-y2*y2;
if(t2<0) {
n2 = 0;
} else {
t2 *= t2;
n2 = t2 * t2 * gi2.dot2(x2, y2);
}
// Add contributions from each corner to get the final noise value.
// The result is scaled to return values in the interval [-1,1].
return 70 * (n0 + n1 + n2);
};
// 3D simplex noise
module.simplex3 = function(xin, yin, zin) {
var n0, n1, n2, n3; // Noise contributions from the four corners
// Skew the input space to determine which simplex cell we're in
var s = (xin+yin+zin)*F3; // Hairy factor for 2D
var i = Math.floor(xin+s);
var j = Math.floor(yin+s);
var k = Math.floor(zin+s);
var t = (i+j+k)*G3;
var x0 = xin-i+t; // The x,y distances from the cell origin, unskewed.
var y0 = yin-j+t;
var z0 = zin-k+t;
// For the 3D case, the simplex shape is a slightly irregular tetrahedron.
// Determine which simplex we are in.
var i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
var i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
if(x0 >= y0) {
if(y0 >= z0) { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; }
else if(x0 >= z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; }
else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; }
} else {
if(y0 < z0) { i1=0; j1=0; k1=1; i2=0; j2=1; k2=1; }
else if(x0 < z0) { i1=0; j1=1; k1=0; i2=0; j2=1; k2=1; }
else { i1=0; j1=1; k1=0; i2=1; j2=1; k2=0; }
}
// A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
// a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
// a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
// c = 1/6.
var x1 = x0 - i1 + G3; // Offsets for second corner
var y1 = y0 - j1 + G3;
var z1 = z0 - k1 + G3;
var x2 = x0 - i2 + 2 * G3; // Offsets for third corner
var y2 = y0 - j2 + 2 * G3;
var z2 = z0 - k2 + 2 * G3;
var x3 = x0 - 1 + 3 * G3; // Offsets for fourth corner
var y3 = y0 - 1 + 3 * G3;
var z3 = z0 - 1 + 3 * G3;
// Work out the hashed gradient indices of the four simplex corners
i &= 255;
j &= 255;
k &= 255;
var gi0 = gradP[i+ perm[j+ perm[k ]]];
var gi1 = gradP[i+i1+perm[j+j1+perm[k+k1]]];
var gi2 = gradP[i+i2+perm[j+j2+perm[k+k2]]];
var gi3 = gradP[i+ 1+perm[j+ 1+perm[k+ 1]]];
// Calculate the contribution from the four corners
var t0 = 0.6 - x0*x0 - y0*y0 - z0*z0;
if(t0<0) {
n0 = 0;
} else {
t0 *= t0;
n0 = t0 * t0 * gi0.dot3(x0, y0, z0); // (x,y) of grad3 used for 2D gradient
}
var t1 = 0.6 - x1*x1 - y1*y1 - z1*z1;
if(t1<0) {
n1 = 0;
} else {
t1 *= t1;
n1 = t1 * t1 * gi1.dot3(x1, y1, z1);
}
var t2 = 0.6 - x2*x2 - y2*y2 - z2*z2;
if(t2<0) {
n2 = 0;
} else {
t2 *= t2;
n2 = t2 * t2 * gi2.dot3(x2, y2, z2);
}
var t3 = 0.6 - x3*x3 - y3*y3 - z3*z3;
if(t3<0) {
n3 = 0;
} else {
t3 *= t3;
n3 = t3 * t3 * gi3.dot3(x3, y3, z3);
}
// Add contributions from each corner to get the final noise value.
// The result is scaled to return values in the interval [-1,1].
return 32 * (n0 + n1 + n2 + n3);
};
// ##### Perlin noise stuff
function fade(t) {
return t*t*t*(t*(t*6-15)+10);
}
function lerp(a, b, t) {
return (1-t)*a + t*b;
}
// 2D Perlin Noise
module.perlin2 = function(x, y) {
// Find unit grid cell containing point
var X = Math.floor(x), Y = Math.floor(y);
// Get relative xy coordinates of point within that cell
x = x - X; y = y - Y;
// Wrap the integer cells at 255 (smaller integer period can be introduced here)
X = X & 255; Y = Y & 255;
// Calculate noise contributions from each of the four corners
var n00 = gradP[X+perm[Y]].dot2(x, y);
var n01 = gradP[X+perm[Y+1]].dot2(x, y-1);
var n10 = gradP[X+1+perm[Y]].dot2(x-1, y);
var n11 = gradP[X+1+perm[Y+1]].dot2(x-1, y-1);
// Compute the fade curve value for x
var u = fade(x);
// Interpolate the four results
return lerp(
lerp(n00, n10, u),
lerp(n01, n11, u),
fade(y));
};
// 3D Perlin Noise
module.perlin3 = function(x, y, z) {
// Find unit grid cell containing point
var X = Math.floor(x), Y = Math.floor(y), Z = Math.floor(z);
// Get relative xyz coordinates of point within that cell
x = x - X; y = y - Y; z = z - Z;
// Wrap the integer cells at 255 (smaller integer period can be introduced here)
X = X & 255; Y = Y & 255; Z = Z & 255;
// Calculate noise contributions from each of the eight corners
var n000 = gradP[X+ perm[Y+ perm[Z ]]].dot3(x, y, z);
var n001 = gradP[X+ perm[Y+ perm[Z+1]]].dot3(x, y, z-1);
var n010 = gradP[X+ perm[Y+1+perm[Z ]]].dot3(x, y-1, z);
var n011 = gradP[X+ perm[Y+1+perm[Z+1]]].dot3(x, y-1, z-1);
var n100 = gradP[X+1+perm[Y+ perm[Z ]]].dot3(x-1, y, z);
var n101 = gradP[X+1+perm[Y+ perm[Z+1]]].dot3(x-1, y, z-1);
var n110 = gradP[X+1+perm[Y+1+perm[Z ]]].dot3(x-1, y-1, z);
var n111 = gradP[X+1+perm[Y+1+perm[Z+1]]].dot3(x-1, y-1, z-1);
// Compute the fade curve value for x, y, z
var u = fade(x);
var v = fade(y);
var w = fade(z);
// Interpolate
return lerp(
lerp(
lerp(n000, n100, u),
lerp(n001, n101, u), w),
lerp(
lerp(n010, n110, u),
lerp(n011, n111, u), w),
v);
};
})(this);
//effective animation code
var wWidth = window.innerWidth;
var wHeight = window.innerHeight;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, wWidth / wHeight, 0.01, 1000);
camera.position.x = 0;
camera.position.y = 0; // 0
camera.position.z = 50; // 40
camera.lookAt(new THREE.Vector3(0, 0, 0));
var renderer = new THREE.WebGLRenderer({
alpha: true
});
renderer.setClearColor(0x000000, 0);
document.getElementById('sec-graphical-intro').appendChild(renderer.domElement);
//Animation parameters
var rows = 50;
var cols = 100;
var separation = 1;
var perlinScale = 0.025;
var waveSpeed = 0.1;
var waveHeight = 8;
var FPS = 45;
var startTime = new Date().getTime();
var particles = 0;
var count = 0;
noise.seed(Math.random());
function createGeometry() {
var numParticles = cols * rows;
var positions = new Float32Array( numParticles * 3 );
var i = 0
var j = 0;
for ( var ix = 0; ix < cols; ix ++ ) {
for ( var iy = 0; iy < rows; iy ++ ) {
positions[i] = ix * separation - ( ( cols * separation ) / 2 ); // x
positions[i + 1] = 0; // y
positions[i + 2] = iy * separation - ( ( rows * separation ) / 2 ); // z
i += 3;
j ++;
}
}
var geometry = new THREE.BufferGeometry();
geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
// geometry.dynamic = true;
// geometry.translate(-100, 0, -25);
return geometry;
}
var geo = createGeometry();
var material = new THREE.ShaderMaterial( {
uniforms: {
"color1": {
type : "c",
value: new THREE.Color(0x2753c9)
},
"color2": {
type : "c",
value: new THREE.Color(0x1dcdc0)
}
},
vertexShader: `
varying vec2 vUv;
varying vec4 pos;
void main() {
vUv = uv;
gl_PointSize = 4.0;
pos = projectionMatrix * modelViewMatrix * vec4(position,1.0);
gl_Position = pos;
}
`,
fragmentShader: `
uniform vec3 color1;
uniform vec3 color2;
varying vec2 vUv;
varying vec4 pos;
void main() {
if ( length( gl_PointCoord - vec2( 0.5, 0.5 ) ) > 0.475 ) discard;
gl_FragColor = vec4(mix(color1, color2, smoothstep(-10.0, 10.0, pos.x)), 1.0);
}
`
});
particles = new THREE.Points(geo, material);
scene.add(particles);
function perlinAnimate() {
var curTime = new Date().getTime();
var positions = particles.geometry.attributes.position.array;
var i = 0
var j = 0;
for ( var ix = 0; ix < cols; ix ++ ) {
for ( var iy = 0; iy < rows; iy ++ ) {
pX = (ix * perlinScale) + ((curTime - startTime) / 1000) * waveSpeed;
pZ = (iy * perlinScale) + ((curTime - startTime) / 1000) * waveSpeed;
positions[ i + 1 ] = (noise.simplex2(pX, pZ)) * waveHeight;
i += 3;
}
}
particles.geometry.attributes.position.needsUpdate = true;
count += 0.1;
}
function render() {
renderer.render(scene, camera);
}
function animate() {
perlinAnimate();
render();
window.setTimeout(function() {
requestAnimationFrame(animate);
}, 1000 / FPS);
}
function refreshCanvasState() {
wWidth = window.innerWidth;
wHeight = window.innerHeight;
camera.aspect = wWidth / wHeight;
camera.updateProjectionMatrix();
renderer.setSize(wWidth, wHeight);
}
//EVENTS && INTERACTIONS
window.addEventListener('resize', refreshCanvasState, false);
animate();
refreshCanvasState();
addEvent(document, "keypress", function(e) {
e = e || window.event;
// use e.keyCode
console.log(e.keyCode);
});
function addEvent(element, eventName, callback) {
if (element.addEventListener) {
element.addEventListener(eventName, callback, false);
} else if (element.attachEvent) {
element.attachEvent("on" + eventName, callback);
} else {
element["on" + eventName] = callback;
}
}
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js"></script>
</head>
<body>
<section id="sec-graphical-intro"></section>

Applying multiple textures to same geometry

I have planeGeometry and I have some vertices higher than others, so some vertices have different z index to generate terrain-like texture.
I want to add different textures like grass,sand,snow to different planes.
How can I add to material to different planes.
This is how planegeometry is generated.
https://github.com/mrdoob/three.js/blob/master/src/geometries/PlaneGeometry.js
var indices = [];
var vertices = [];
var normals = [];
var uvs = [];
// generate vertices, normals and uvs
for ( iy = 0; iy < gridY1; iy ++ ) {
var y = iy * segment_height - height_half;
for ( ix = 0; ix < gridX1; ix ++ ) {
var x = ix * segment_width - width_half;
vertices.push( x, - y, 0 );
normals.push( 0, 0, 1 );
uvs.push( ix / gridX );
uvs.push( 1 - ( iy / gridY ) );
}
}
// indices
for ( iy = 0; iy < gridY; iy ++ ) {
for ( ix = 0; ix < gridX; ix ++ ) {
var a = ix + gridX1 * iy;
var b = ix + gridX1 * ( iy + 1 );
var c = ( ix + 1 ) + gridX1 * ( iy + 1 );
var d = ( ix + 1 ) + gridX1 * iy;
// faces
indices.push( a, b, d );
indices.push( b, c, d );
}
}
// build geometry
this.setIndex( indices );
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
This is how it should be done:
//Loading in Texture:
var loader = new THREE.TextureLoader();
var texture = loader.load('grass.jpg');
//Creating material:
var material = new THREE.MeshBasicMaterial({
map: texture,
overdraw: true,
wireframe: false
});
var materials = [];
materials.push(material);
mesh = new THREE.Mesh(geometry, materials);
// Applying this one to faces that need certain material:
// https://threejs.org/docs/#api/en/core/BufferGeometry.addGroup
geometry.addGroup();
Basically what I need is even adding texture to the first plane, but it always adds texture to the whole geometry,
then I can create loop myself which does create textures for rest.

three.js: Calculate faceVertexUvs on custom Geometry for texture mapping

I have this example here:
https://jsfiddle.net/NiklasKnaack/L1cqbdr9/82/
function createPlanetFace( radiusX, radiusY, radiusZ, localUp, resolution ) {
const face = {};
face.geometry = new THREE.Geometry();
face.geometry.faceVertexUvs[ 0 ] = [];
face.verticesOriginal = [];
face.verticesNormalized = [];
const axisA = new THREE.Vector3( localUp.y, localUp.z, localUp.x );
const axisB = new THREE.Vector3().crossVectors( localUp, axisA );
for ( let y = 0; y < resolution; y++ ) {
for ( let x = 0; x < resolution; x++ ) {
const index = x + y * resolution;
const percent = new THREE.Vector2( x, y );
percent.x /= ( resolution - 1 );
percent.y /= ( resolution - 1 );
const vertex = new THREE.Vector3();
vertex.x = ( localUp.x + ( percent.x - 0.5 ) * 2 * axisA.x + ( percent.y - 0.5 ) * 2 * axisB.x ) * radiusX;
vertex.y = ( localUp.y + ( percent.x - 0.5 ) * 2 * axisA.y + ( percent.y - 0.5 ) * 2 * axisB.y ) * radiusY;
vertex.z = ( localUp.z + ( percent.x - 0.5 ) * 2 * axisA.z + ( percent.y - 0.5 ) * 2 * axisB.z ) * radiusZ;
face.verticesOriginal[ index ] = new THREE.Vector3( vertex.x, vertex.y, vertex.z );
vertex.normalize();//create a sphere
vertex.x += vertex.x * radiusX / 2;
vertex.y += vertex.y * radiusY / 2;
vertex.z += vertex.z * radiusZ / 2;
face.verticesNormalized[ index ] = new THREE.Vector3( vertex.x, vertex.y, vertex.z );
face.geometry.vertices[ index ] = vertex;
//if ( index % 6 === 0 && index > 0 && x !== resolution - 1 && y !== resolution - 1 ) {
if ( x !== resolution - 1 && y !== resolution - 1 ) {
const triangle1 = new THREE.Face3( index, index + resolution + 1, index + resolution );
const triangle2 = new THREE.Face3( index, index + 1, index + resolution + 1 );
face.geometry.faces.push( triangle1, triangle2 );
}
}
}
//face.geometry.computeBoundingSphere();
//face.geometry.computeVertexNormals();
//face.geometry.computeFaceNormals();
return face;
};
For this I would like to calculate the UVs so that the loaded texture can be displayed correctly.
In principle, the createPlanetFace function creates a plane. From these 6 planes, a cube or sphere is created. (See it in the example)
So far it already works, only the texture is not displayed because the UVs are missing.
After a lot of research and trying, I get either errors in the console, a totally distorted texture, or just no texture at all. That's why I erased my miserable attempts calculating the UVs.
The examples I have found on this topic are all different. At least most of them. I have now reached a point where I can't get any further and need your help.
Thank you in advance.
Here is a box unwrap I wrote a while ago for regular geometries:
function boxUnwrapUVs(geometry) {
for (var i = 0; i < geometry.faces.length; i++) {
var face = geometry.faces[i];
var faceUVs = geometry.faceVertexUvs[0][i]
var va = geometry.vertices[geometry.faces[i].a]
var vb = geometry.vertices[geometry.faces[i].b]
var vc = geometry.vertices[geometry.faces[i].c]
var vab = new THREE.Vector3().copy(vb).sub(va)
var vac = new THREE.Vector3().copy(vc).sub(va)
//now we have 2 vectors to get the cross product of...
var vcross = new THREE.Vector3().copy(vab).cross(vac);
//Find the largest axis of the plane normal...
vcross.set(Math.abs(vcross.x), Math.abs(vcross.y), Math.abs(vcross.z))
var majorAxis = vcross.x > vcross.y ? (vcross.x > vcross.z ? 'x' : vcross.y > vcross.z ? 'y' : vcross.y > vcross.z) : vcross.y > vcross.z ? 'y' : 'z'
//Take the other two axis from the largest axis
var uAxis = majorAxis == 'x' ? 'y' : majorAxis == 'y' ? 'x' : 'x';
var vAxis = majorAxis == 'x' ? 'z' : majorAxis == 'y' ? 'z' : 'y';
faceUVs[0].set(va[uAxis], va[vAxis])
faceUVs[1].set(vb[uAxis], vb[vAxis])
faceUVs[2].set(vc[uAxis], vc[vAxis])
}
geometry.elementsNeedUpdate = geometry.verticesNeedUpdate = true;
}
Is that helpful?
edit: I rewrote your example because it was too complicated for me to understand...
https://jsfiddle.net/manthrax/dL6kxuf2/1/

Dynamically change point color in Three.js PointClouod

I'm trying to render a matrix of points in Three.js but I need to treat each particle in the cloud as an individual "pixel" for which I can change the color of each on the fly. I figured out how to basically render the point cloud, and can set the initial color, but cannot figure out how to change the color of each point once it's set.
I'm generating the point cloud like this:
function generateRegularPointcloud( color, width, length ) {
var geometry = new THREE.Geometry();
var numPoints = width * length;
var colors = [];
var k = 0;
for( var i = 0; i < width; i++ ) {
for( var j = 0; j < length; j++ ) {
var u = i / width;
var v = j / length;
var x = u - 0.5;
var y = 0;
var z = v - 0.5;
var v = new THREE.Vector3( x,y,z );
var intensity = ( y + 0.1 ) * 7;
colors[ 3 * k ] = color.r * intensity;
colors[ 3 * k + 1 ] = color.g * intensity;
colors[ 3 * k + 2 ] = color.b * intensity;
geometry.vertices.push( v );
colors[ k ] = ( color.clone().multiplyScalar( intensity ) );
k++;
}
}
geometry.colors = colors;
geometry.computeBoundingBox();
var material = new THREE.PointCloudMaterial( { size: pointSize, vertexColors: THREE.VertexColors } );
var pointcloud = new THREE.PointCloud( geometry, material );
return pointcloud;
}
My basic code is here: http://jsfiddle.net/dg34sbsk/
Any idea how to change each point color separately and dynamically? (Data for the colors will be coming in from a web service).
You can directly change its's value pointclouds[0].geometry.colors=... and after that pointclouds[0].geometry.colorsNeedUpdate=true.
To set each point's color just set the colors's children's value like pointclouds[0].geometry.colors[22]=new THREE.Color("rgb(255,0,0)");.
see this:http://jsfiddle.net/aboutqx/dg34sbsk/2/ .click and you will see the color of one point changes.

Resources