mapbox customlayer autoclearcolor - three.js

I have a question about mapbox autoclearcolor setup when it uses three.js custom layer.
I managed to make a cube within a mapspace using the customlayer setup in mapbox and
I wanted to make the map layer visible at the beginning and turned it visible in a certain moment.By doing things as below.
In onAdd method,
this.map = map;
this.canvas = map.getCanvas()
this.renderer = new THREE.WebGLRenderer({
canvas: map.getCanvas(),
context: gl,
antialias: true
});
this.renderer.autoClear = false;
In render Method,
if(frameCount>10 && frameCount<11){
this.renderer.autoClear = true;
}
I by accident made it happened but I don't know why it happened.
frameCount += 0.1
if(frameCount>10 && frameCount<11){
this.renderer.autoClear = true;
}
In three.js document it says
.autoClear : Boolean
Defines whether the renderer should automatically clear its output before rendering a frame.
I don't get how it works.
To me it sounds like,
if I set autoClear true, it should clear things in the scene and if it's true,
I shouldn't see anything but by setting this, only the map tile is gone and my mesh and map labels are still alive like the screen shot below.
after autoclear is set true
Before autoclear becomes true, currently it's false which is default value

Related

Is it possible to render a shadow in three.js without it having to be cast from an object

I am making a horror game and want to make a shadow move on a wall but I want it to appear as if it originated from no particular object. Is this possible and if so how do I implement this?
I have the feeling that dynamic textures will probably be the way to go but I am hoping there is some way using the three.js shadow map
You want a scene object to cast a shadow but be invisible.
First make sure your object will cast a proper shadow, then make the object invisible by adding:
object.material.colorWrite = false;
object.material.depthWrite = false;
The depthWrite setting is required if there are other objects in the scene. That property is not considered by the shadow mapping code.
Alternatively, you can try this, instead:
object.material.colorWrite = false;
object.material.transparent = true; // only needed if there are other transparent objects
object.renderOrder = Infinity;
three.js r.92
There's two ways to achieve this. One of them is by going "under the hood" of THREE.js and rendering the ShadowMap separately, with the object visibility = true, then setting visibility to false, then rendering the scene.
A much easier way is by assigning your object's opacity to something really low. Try 0.0001. It'll cast shadows, but be virtually invisible:
var ghostGeom = new THREE.BoxBufferGeometry(1, 1, 1);
var ghostMat = new THREE.MeshBasicMaterial({
color: 0x000000,
transparent: true,
opacity: 0.0001
});
var ghostMesh = new THREE.Mesh(ghostGeom, ghostMat);
ghostMesh.castShadow = true;
Alternatively, you can use AdditiveBlending on the material, with the color set to pitch black. This will add 0 color to the final render, while still casting shadows:
var ghostMat = new THREE.MeshBasicMaterial({
color: 0x000000,
transparent: true,
blending: THREE.AdditiveBlending
});
I think what you need is a Projector which will cast a quad texture onto the ground or the wall.

r71: texture.needsUpdate = true doesn't update texture in firefox40

I need update the mesh's texture in my project, by changing the image's source in the texture. The code is below:
mesh.material.map.image.src= "path/to/image";
mesh.material.map.texture.needsUpdate = true;
The image has completely loaded. It works well in chrome, but not in firefox, the browser doesn't render new texture immediately, and i fixed it by:
setTimeout( function(){ mesh.material.map.texture.needsUpdate = true; }, 100);
I don't know why it can't update immediately in firefox, has anyone encountered this problem?
since timeout fixes the issue, the needsUpdate flag is set back to false before the texture loads
you should probably use a loader for getting the texture
var texture = THREE.ImageUtils.loadTexture("path/to/image");
it also has a callback for what happens when texture is loaded
var texture = THREE.ImageUtils.loadTexture("path/to/image", THREE.UVMapping, onLoadCallback);
the callback gets loaded texture as parameter so you can add it to the material after load but the loader sets the textures needsUpdate flag to true itself so simple
var texture = THREE.ImageUtils.loadTexture("path/to/image");
mesh.material.map = texture;
should suffice

Transparant spritesheet animation for webgl

I'm just getting started with webgl and was trying to make an animation based on a spritesheet. I've found an example and changed the spritesheet to my own. However even though I removed the white background, saved it as a transparant png, the animation still shows up with a white background.
This is the example I used:
http://stemkoski.github.io/Three.js/Texture-Animation.html
Is there any way how I can get rid off the white background?
Thanks in advance.
EDIT:
var runnerTexture = new THREE.ImageUtils.loadTexture( 'images/run.png' );
annie = new TextureAnimator( runnerTexture, 10, 1, 10, 75 ); // texture, #horiz, #vert, #total, duration.
var runnerMaterial = new THREE.MeshBasicMaterial( { map: runnerTexture, side:THREE.DoubleSide } );
var runnerGeometry = new THREE.PlaneGeometry(50, 50, 1, 1);
var runner = new THREE.Mesh(runnerGeometry, runnerMaterial);
runner.position.set(-150,25,0);
scene.add(runner);
To support PNGs with an alpha-channel, you have to modify the MeshBasicMaterial accordingly: There is an attribute 'transparent' which you could set to 'true'.
Try using the following line instead:
var runnerMaterial = new THREE.MeshBasicMaterial( { map: runnerTexture, side:THREE.DoubleSide, transparent: true } );
See also the reference from Material:
.transparent
Defines whether this material is transparent. This has an effect on
rendering as transparent objects need special treatment and are
rendered after non-transparent objects. For a working example of this
behaviour, check the WebGLRenderer code. When set to true, the extent
to which the material is transparent is controlled by setting opacity.

text in three.js: transparency lost when rotating

I'm trying the second approach to use Text in three.js, drawing on a canvas and using the result as a texture. It basically works, except for the following problem -don't know if it's a bug:
I create two texts, with transparent background, and overlap then. They show ok, but when I rotate one of them, the transparency is messed up.
I create the text objects with following (excerpt) function
function createText(text, ...){
var textHolder = document.createElement( 'canvas' );
var ctext = textHolder.getContext('2d');
...
var tex = new THREE.Texture(textHolder);
var mat = new THREE.MeshBasicMaterial( { map: tex, overdraw: true});
mat.transparent = true;
mat.map.needsUpdate = true;
var textBoard = new THREE.Mesh(new THREE.PlaneGeometry(textHolder.width, textHolder.height),mat);
textBoard.dynamic = true;
textBoard.doubleSided = true;
return textBoard;
}
and add them to the scene.
See demonstration with full code in jsfiddle
Transparency is tricky in webGL.
The best solution in your case is to do the following for your transparent text material:
mat.depthTest = false;
updated fiddle: http://jsfiddle.net/SXA8n/4/
three.js r.55

Animation not working properly when three.js mixer clampwhenfinished method set true

I am trying to disassemble the gun using three.js. To do this I used an object modeled and I animized in 3dsmax. I have output them in Json 3D Loader format using cgdev json exporter.
My problem; I want to animate the charger, back and forward. I prepare an animation at 3ds max to insert the magazine and I played it, but I could not use a negative timescale because I used looponce to play back this animation. So I made the back animation in 3ds max as well, but when I use the clampwhenfinished = true code, the animation is not playing back exactly.
var step;
next ? step = animAssemble[iTween] : step = animDissamble[iTween];
var tween = new TWEEN.Tween(camera.position).to(step.camera, step.tCam);
tween.onUpdate(function () { camera.position = step.camera });
tween.start();
tween.onComplete(function () {
var mesh = meshes[step.gun], mixer = mixers[step.gun];
animation = mixer.clipAction(mesh.geometry.animations[step.i]);
animation.setLoop(THREE.LoopOnce);
animation.clampWhenFinished = true;
animation.play();
anim = true;
});
Thanks.

Resources