threejs how to make points have orientation - three.js

I want to realize a points system on globe that points facing on the center of the globe, right now i am using circleGeometry, it is good in visualization. But if I want to generate and remove points in a large scale. All the circleGeometries will be recalculated. The performance is not so good. Before I tried to use bufferGeometry and points to realize. Then all the points always facing camera when for points there is no orientation.
So what can I do now? Is there some other methods I can have a try?Thank you so much for your help.
corresponding code(using circleGeometry):
for (var city in Data) {
var result = returnSphericalCoordinates(
      Data[city].y,
      Data[city].x
);
sizes[city] = 3* Math.pow(Data[city].numPoints,1/2);
var geometry = new THREE.CircleGeometry( sizes[city]/2, 32 );
var texture = new THREE.TextureLoader().load('./disc.png')
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
var material = new THREE.MeshBasicMaterial({
map: texture,
transparent:true,
alphaTest: 0.2,
side: THREE.DoubleSide,
depthWrite: false
// antialias: true
});
this.mesh = new THREE.Mesh(geometry, material);
this.mesh.position.set(result.x, result.y, result.z );
this.mesh.lookAt(new THREE.Vector3(0, 0, 0));
Points system I was trying to use:
var geometry = new THREE.BufferGeometry();
geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
geometry.addAttribute( 'size', new THREE.BufferAttribute( sizes, 1 ) );
geometry.computeBoundingSphere();
  // Make texture
var texture = new THREE.TextureLoader().load('./disc.png')
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
ShaderLoader('./pointshader.vert',
'./pointshader.frag',
function(vertex,fragment){
var material = new THREE.ShaderMaterial( {
uniforms: {
texture: {value : texture},
color: {value : new THREE.Color(0xffffff)}
},
vertexShader: vertex,
fragmentShader: fragment,
side: THREE.DoubleSide,
transparent: true,
alphaTest: 0.05,
// depthWrite: false
} );
this.globeDots = new THREE.(geometry, material);
this.globeDots.matrixAutoUpdate = false;
this.globeDots.lookAt(new THREE.Vector3(0, 0, 0));
props.threeObject.add(this.globeDots);
// })
enter image description here

Related

How can I apply Texture on Cube using Three.js

// Make a cube with Lambert material
// ---------------------------------
// Lower fragments can increase performance
var cubeWidth = cubeSize,
cubeHeight = cubeSize,
cubeDepth = 10,
cubeQuality = 1;
// create the cube's material
var cubeMaterial = new THREE.MeshLambertMaterial(
{
color: 0xb22222
}
);
// create a cube with sphere geometry and the meterial
cube = new THREE.Mesh(
new THREE.BoxGeometry(
cubeWidth,
cubeHeight,
cubeDepth,
cubeQuality,
cubeQuality,
cubeQuality
),
cubeMaterial);
lift the cube to half of the playing space height
cube.position.z = fieldDepth/2;
set the cube x position in the left of the play field
cube.position.x = -fieldWidth/3;
----------add the cube to the scene-------------------------
scene.add(cube);
I have tried ;
var texture = new THREE.TextureLoader();
var texture1 = texture.load('scripts/kan.png');
cube = new THREE.Mesh(
new THREE.BoxGeometry(
cubeWidth,
cubeHeight,
cubeDepth,
cubeQuality,
cubeQuality,
cubeQuality
));
var cubeMaterial = new THREE.MeshBasicMaterial(
{
map: texture1
//color: 0xb22222
}
);
// create a cube with sphere geometry and the meterial
mesh = new THREE.Mesh( cube, cubeMaterial );
And this, but it didn't work
const texture = new THREE.TextureLoader().load( 'kan.png' );
var cubeMaterial = new THREE.MeshLambertMaterial(
{
//color: 0xb22222
map: texture
}
);
I am also getting the following error : THREE.Material: 'map' parameter is undefined

Artifacts on the top and bottom of png textures in THREE.js v76

I'm getting some artifacts on the top and bottom sides on some of my sprites. These are the shaders I am using, if that matters. I'm using v76.
And I'm building these sprites like this:
var object = new THREE.Object3D();
var textureLoader = new THREE.TextureLoader();
textureLoader.load('path/to/image.png', function(texture) {
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.anisotropy = 16;
var geometry = new THREE.PlaneBufferGeometry(15, 15);
var material = new THREE.MeshPhongMaterial({
map: texture,
color: 0xffffff,
transparent: true,
alphaTest: 0.2,
side: DoubleSide,
});
var mesh = new THREE.Mesh(geometry, material);
mesh.castShadow = true;
mesh.receiveShadow = true;
mesh.customDepthMaterial = new ShaderMaterial({
uniforms: { texture: { type: 't', value: this.material.map } },
vertexShader: vertexShader,
fragmentShader: fragmentShader,
});
object.add(mesh);
})
Don't set your textures to wrap with THREE.RepeatWrapping. This can leave artifacts on texture edges meant to be used as sprites.

Repeating texture of the PlaneGeometry

The way of reproduction of the texture, independent of the extent of object is necessary to me. If, for example, to do:
var geometry = new THREE.PlaneGeometry( 400, 400, 10, 10 );
var Texture = THREE.ImageUtils.loadTexture( 'textures/texture.png' );
Texture.wrapS = Texture.wrapT = THREE.RepeatWrapping;
Texture.repeat.set( 2, 1 );
var material = new THREE.MeshBasicMaterial({
map: Texture,
side: THREE.DoubleSide,
});
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set(-400,0,0);
scene.add( mesh );
var mesh = new THREE.Mesh( geometry.clone(), material.clone() );
mesh.scale.x = 2;
mesh.position.set(400,0,0);
scene.add( mesh );
result here
How to redefine texture to receive the following result?
here

Three.JS tiling image used in skybox mesh in WebGL?

Demo Can be seen here
I'm using a rather small image to make the skybox and for some reason it's being stretched instead of tiled. I found this tutorial on how to pattern a texture. I noted these lines
var crateTexture = new THREE.ImageUtils.loadTexture( 'images/crate.gif' );
crateTexture.wrapS = crateTexture.wrapT = THREE.RepeatWrapping;
crateTexture.repeat.set( 5, 5 );
var crateMaterial = new THREE.MeshBasicMaterial( { map: crateTexture } );
var crate = new THREE.Mesh( cubeGeometry.clone(), crateMaterial );
crate.position.set(60, 50, -100);
scene.add( crate );
So I tried using this method for the skybox and it didn't produce any change
var path = "/images/";
var urls = [
path + 'startile.png', path + 'startile.png',
path + 'startile.png', path + 'startile.png',
path + 'startile.png', path + 'startile.png'
];
var textureCube = THREE.ImageUtils.loadTextureCube( urls , new THREE.CubeRefractionMapping() );
textureCube.wrapS = textureCube.wrapT = THREE.RepeatWrapping;
textureCube.repeat.set( 10, 10 );
var material = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap: textureCube, refractionRatio: 0.95 } );
// Skybox
var shader = THREE.ShaderLib[ "cube" ];
shader.uniforms[ "tCube" ].value = textureCube;
var material = new THREE.ShaderMaterial( {
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: shader.uniforms,
side: THREE.BackSide
} ),
mesh = new THREE.Mesh( new THREE.CubeGeometry( 1200, 1200, 1200 ), material );
//mesh.overdraw = false;
// mesh.rotation.x = Math.PI * 0.1;
scene.add( mesh );
Any ideas?
Tiling is not supported for texture cubes. However, in your case, since all faces of your cube are identical, you can do something like this:
var geometry = new THREE.CubeGeometry( 1000, 1000, 1000 );
var texture = THREE.ImageUtils.loadTexture( "startile.png" );
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 10, 10 );
var material = new THREE.MeshBasicMaterial( {
color: 0xffffff,
map: texture,
side: THREE.BackSide
} );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
three.js r.59

Different material on back and frontside of extruded shape

I'm trying to apply different material on front and back sides of extruded shape, but cannot figure out where to put side: THREE.FrontSide and side: THREE.BackSide. Where they should be putted?
My relevant code part is:
var materialFront = new THREE.MeshPhongMaterial({ ambient: 0xffffff, map: frontTexture });
var materialSide = new THREE.MeshPhongMaterial({color: 0xE68A00, ambient: 0xffffff});
var extrusionSettings = {
amount: 10,
bevelEnabled: false,
bevelThickness: 0.2,
bevelSize: 0.2,
bevelSegments: 8,
material: 0,
extrudeMaterial: 1
};
var geometry = new THREE.ExtrudeGeometry(shapes, extrusionSettings);
var materials = [materialFront, materialSide];
var material = new THREE.MeshFaceMaterial(materials);
mesh = new THREE.Mesh(geometry, material);
UPDATE:
According to WestLangley's comment I succeeded in adding the different texture to backfaces:
// ...
var materials = [materialFront, materialSide, materialBack];
// ...
for ( var face in mesh.geometry.faces ) {
if (mesh.geometry.faces[ face ].normal.z == 1) mesh.geometry.faces[ face ].materialIndex = 2;
}
After you create your mesh geometry, and before the first call to render(), you have to change the materialIndex to 2 for the back faces. Then, add a third material in your material array.
You can identify the back faces by their face normals. Face normals for faces on the back of the geometry should all point in the same direction.
three.js r.58
Try using:
var materialFront = new THREE.MeshPhongMaterial({ ambient: 0xffffff, map: frontTexture, side: THREE.FrontSide });
var materialSide = new THREE.MeshPhongMaterial({ color: 0xE68A00, ambient: 0xffffff, side: THREE.BackSide });
even though you should probably lower your ambient contribution and give a color to the FrontSide material.
Then:
var materials = [materialFront, materialSide];
scene.add( THREE.SceneUtils.createMultiMaterialObject( geometry, materials ));

Resources