demo:
https://dl.dropboxusercontent.com/u/123374/so-pages/20160601/index.html
the alphaTexture is having it's offset altered during each render. as a "map" property it changes, but as an "alphaMap" it does not change. the 2nd mesh's alphaMap
relevant code from demo link:
var colorTexture = new THREE.TextureLoader().load('blue.png')
, alphaTexture = new THREE.TextureLoader().load('alpha.png')
, offset = 0
, colorFill = new THREE.Mesh(
new THREE.Geometry(),
new THREE.MeshPhongMaterial({
map: colorTexture,
alphaMap: alphaTexture,
side: THREE.DoubleSide,
shading: THREE.FlatShading
})
)
function render() {
requestAnimationFrame(render)
offset += .01
alphaTexture.offset.x = Math.sin(offset)
renderer.render(scene, camera)
}
render()
expected:
the transparent part of the object would shift as the offset of the alphaTexture changes.
actual:
transparent part stays fixed on the material. However, if I edit the offset of the texture set to the map property (instead of alphaMap) it * is * able to shift, which seems like inconsistent behavior to me.
What you are seeing is a current "feature" of three.js: only one offset/repeat pair is allowed per mesh. mesh.map has priority.
For more info, see https://stackoverflow.com/a/14372235/1461008
This may be changed in the future to allow separate offset/repeat settings per texture or per material property.
three.js r.84
I tried commenting out the USE_ALPHAMAP with the latest version(82) but it didn't work. However, changing the vUv to vUv2 in the alpha_fragment chunk worked.
Jim
Related
I am working on customizing the transform controls available in three.js for my project.
I have already changed the rotation part and now working on translation part.
if you notice in translation Gizmo, there is a XYZ octahedron in the center. I have removed all other planes and arrows and wrote all functionality only on that center mesh, which is working fine.
Now I am only stuck at one small problem, that is the size and position of that controller. I changed that Octahedron to boxGeometry and writing the code to make the size of that controller to be exact size of the selected object. for that I get the idea to make the size of the controller, same as the boxHelper size, which act as outline of object.
when I tried this logic in sample code, where I created a box, and getting the size of box helper and creating another box of same size, it was working fine. but when I am writing same code in threejs transform controls, result is not the same.
below is the geometry code init
XYZ: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.1, 0.1, 0.1 ), pickerMaterial )]],
then I am getting the size of box3 when attaching to any object
this.addBoxHelper = function () {
this.removeBoxHelper();
if(this.object.box3) {
**this.object.box3.getSize(selectionBoxSize);**
console.log(selectionBoxSize)
this.objectBoxHelper = new THREE.Box3Helper(this.object.box3, 0xffff00);
this.objectBoxHelper.canSelect = function () {
return false;
}
this.object.add(this.objectBoxHelper);
}
}
then below is my update function of transform controls
this.update = function () {
if ( scope.object === undefined ) return;
scope.object.updateMatrixWorld();
worldPosition.setFromMatrixPosition( scope.object.matrixWorld );
worldRotation.setFromRotationMatrix( tempMatrix.extractRotation( scope.object.matrixWorld ) );
scope.object.box3.getSize(selectionBoxSize);
scope.object.getWorldPosition(selectionBoxPos);
camera.updateMatrixWorld();
camPosition.setFromMatrixPosition( camera.matrixWorld );
camRotation.setFromRotationMatrix( tempMatrix.extractRotation( camera.matrixWorld ) );
**scaleT = selectionBoxSize;**
//below three lines are for dynamic size change based on camera position..for
//next level functionality
//scaleT.x = worldPosition.distanceTo( camPosition ) / 6 * selectionBoxSize.x;
//scaleT.y = worldPosition.distanceTo( camPosition ) / 6 * selectionBoxSize.y;
//scaleT.z = worldPosition.distanceTo( camPosition ) / 6 * selectionBoxSize.z;
this.position.copy( selectionBoxPos );
this.scale.set( scaleT.x, scaleT.y, scaleT.z);
this.updateMatrixWorld();
below is the output of console log
TransformControls.js:526 Vector3 {x: 10.020332336425781, y: 2.621583938598633, z: 3.503500819206238}
TransformControls.js:601 Vector3 {x: 10.020332336425781, y: 2.621583938598633, z: 3.503500819206238}
as you can see, the scale is the same, but the result is different. see the result in below images.
as you see in images, that red color box at bottom is translation controller but smaller than selection box.
another issue is that pivot of my objects are at bottom, and I want this controller to come at the center of the selection box, that is also not happening with getCenter method of box3.
Please help!! let me know if I am unclear in explaining the issue
If you are getting the bounding box of the object from its geometry, that will be wrong because it doesn't take the objects transform into account. You have to use box3.setFromObject (yourObject) instead. does that help?
Disclaimer: I am new to three.js and the world of 3D in general. I also didn't want to clutter the question with unnecessary code, so if there is some that would benefit, please let me know.
I have a model with 3 spotlights, two from the sides that render shadow, and one from the front (same position as the camera) that shines light on the object.
When I was messing about with the side spotlights, both had shadowCameraVisible set to true for debugging purposes, and all was well.
As soon as I set shadowCameraVisible to false on both of them, the shadows no longer render correctly.
The object in quesion contains two MeshLambertMaterials defined with side as THREE.DoubleSide, and the broken shadow resembles the object as it would be displayed if side was set to THREE.FrontSide.
Can anyone think of any reason why the shadow would be broken in this way? And why does the value of shadowCameraVisible change things?
Update:
I have now read that the material.side parameter is ignored for shadows and therefore this is what might be causing it. But this does still not explain why material.side appears to be not ignored when shadowCameraVisible=true!
Update 2:
Here's some code which might be relevant.
The 3D model has two faces which are defined as follows:
var material1 = new THREE.MeshLambertMaterial({
color: 0xff0000,
side: THREE.DoubleSide,
shading: THREE.FlatShading,
colors: THREE.FaceColors,
vertexColors: THREE.FaceColors,
blending: THREE.NormalBlending
});
var material2 = new THREE.MeshLambertMaterial({
image: 'miscimage.jpg',
side: THREE.DoubleSide,
shading: THREE.FlatShading,
colors: THREE.FaceColors,
vertexColors: THREE.FaceColors,
blending: THREE.NormalBlending
});
var materials = [materials1, materials2];
The mesh is defined as:
var mesh = new THREE.Mesh(
geometry,
new THREE.MeshFaceMaterial(materials)
);
mesh.receiveShadow = true;
mesh.castShadow = true;
And the two spotlights:
var spotlight1 = new THREE.SpotLight(0xffffff);
spotlight1.position.set(-160, 300, -60);
spotlight1.shadowDarkness = 0.4;
spotlight1.intensity = 2;
spotlight1.castShadow = true;
scene.add(spotlight1);
var spotlight2 = new THREE.SpotLight(0xffffff);
spotlight2.position.set(160, 300, -60);
spotlight2.shadowDarkness = 0.4;
spotlight2.intensity = 2;
spotlight2.castShadow = true;
scene.add(spotlight2);
As mentioned, when one of the spotlights has shadowCameraVisible=true, then the shadows look like the first image, and when it is not set (i.e. to the default of false) you get the shadows in the second image. This makes it look as though shadowCameraVisible=true causes the shadow to honour the object's side setting of THREE.DoubleSide whereas having shadowCameraVisible=false, does not.
Update 3:
In fact, if I leave one of the cameras with shadowCameraVisible=true, and then go into three.js itself, and within the THREE.CameraHelper function and commented out all calls to addLine, the shadows work fine and you can't see the camera (of course). Further investigation is needed to find out just what within THREE.CameraHelper is allowing the shadows to work.
this is the link of my work : maison.whiteplay.fr
What i am trying to do is a 3D PacMan, but look at th code, i'm using mesh to build my level, except for bubbles (yellow circle), that you need to eat to win.
They are all different objects, but because they are a lot, it's lagging, can i use the same technologie (mesh i think) to the bubbles ? If yes, how ?
code:
var geometrySphere = new THREE.SphereGeometry( 5, 32, 32 );
var bille = function(x,z){
this.bille = new THREE.Mesh(
geometrySphere,
new THREE.MeshBasicMaterial( {color: 0xffff00} )
);
this.bille.position.x = (x-15.5)*100; this.bille.position.y = 100;
this.bille.position.z = (z-15.5)*100; scene.add(this.bille);
}
Thank your for reading, and if you have any suggestions about my code, don't hesistate :D
You can also reuse your material instead of making a new instance all the time:
var geometrySphere = new THREE.SphereGeometry( 5, 32, 32 );
var billeMaterial = new THREE.MeshBasicMaterial( {color: 0xffff00} );
var bille = function(x,z){
this.bille = new THREE.Mesh(
geometrySphere,
billeMaterial
);
this.bille.position.x = (x-15.5)*100; this.bille.position.y = 100;
this.bille.position.z = (z-15.5)*100; scene.add(this.bille);
}
Reusing materials has good influence on performance.
How do you duplicate your meshes/objects?
You're code is almost right.
In your specific case, with N equal balls, you must have N mesh but just one material.
In this way, if you want to colorize (just for example) only one ball, you have to apply it one new material, otherwise you will apply new color to all the balls.
In your case lagging may be due to the sphere construction.
You clearly copy and paste from the documentation without read it before.
var geometrySphere = new THREE.SphereGeometry( 5, 32, 32 );
Where, as explained in the documentation:
radius — sphere radius. Default is 50.
widthSegments — number of horizontal segments. Minimum value is 3, and the default is 8.
heightSegments — number of vertical segments. Minimum value is 2, and the default is 6.
32 * 32 is too much for your small-monocolor bubbles, doesn't have sense.
The higher are this values, the higher is the complexity for draw it for each frame.
I suggest you to create sphere with a minor number of vertical/horizontal segments (8*8 may be ok).
Take a look at this demo.
I have a system of tubes. More precisely, I create a tubes from this code
tube_color - obviously, color of tube,
spline_points - huge number of THREE.Vector3 objects,
segments, radiusSegments are just numbers
var material = new THREE.MeshLambertMaterial( { color: tube_color, shading: THREE.SmoothShading } );
var spline = new THREE.SplineCurve3(spline_points);
var tube = new THREE.TubeGeometry(spline, segments, 10, radiusSegments, false, false);
var tubeMesh = new THREE.Mesh(tube, material);
scene.add(tubeMesh);
This code creates one particular mesh object in space. For each mesh I can have an array of Vector3's by using myMesh.geometry.vertices.
The problem is: I have the point in 3d space. Around this point I create Cube, which does intersect with tubes. For example, this cube can be created like this
var cube = new THREE.CubeGeometry(xSize,ySize,zSize, 5, 5, 5);
var material = new THREE.MeshBasicMaterial({
color: 0xff0000,
opacity: 1,
wireframe: true,
transparent: false
});
var selectionMesh = new THREE.Mesh(cube, material);
scene.add(selectionMesh);
Is it possible at least to find objects(meshes) that have intersection with by cubic area? I know that in scene object I have all meshes, and I can iterate over them, get vertices, iterate over them with a condition if there is at least one its point is in cubic area. But I believe... I hope there is a method/algorithm/magic much more simple then this...
As #WestLangley recommended the solution of this problem was to build octree.
octree=new THREE.Octree({
undeferred:false,
depthMax:Infinity,
objectsThreshold:8,
overlapPct:0.15
} );
and search it
var meshesSearch=octree.search( rayCaster.ray.origin, radiusSphere, true, rayCaster.ray.direction );
However, to have specific intersection we need to provide the recursive flag
raycaster.intersectOctreeObjects( objects, true )
I ended up with more complicated processing of my specific case however this was enough to solve the problem at that moment.
I've made a circle as follows:
material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
arcShape = new THREE.Shape();
arcShape.absarc( 0, 0, 20, 0, -Math.PI*2, true );
geometry = arcShape.makeGeometry();
circle = new THREE.Mesh(geometry, material);
scene.add(circle);
Like that, it is visible. But rotate it, and it disappears.
shadow.rotation.x = Math.PI / 2;
I've seen several other posts where this problem has not been solved. (So unless someone has a solution, I'll resort to making a flat cylinder instead. It's just a niggling problem).
I've set mesh.doubleSided = true and mesh.flipSided = false. I've also tried all 4 combinations of toggling the renderer's depthTest and the material's depthWrite properties.
Is there anything else I could try? If not, I'm guessing the code is sensitive to the order of some of my calls, in which case, I've had a long day so I'll stick with the cylinder!!
material.side = THREE.DoubleSide;