Three.js - keyframe interpolation - animation

I get some glitches when disabling objects trough setting their scale to 0.
Setup:
I got a cube with scale 1 in frame 50 & scale 0 in frame 51.
I basically use this, to disable objects in my animation (using gltf or fbx). When I'm playing the animation in three.js it seems that the keyframe is somehow interpolated. So there is a little glitch between Scale 1 & Scale 0.
Have a look here
What I tried so far:
Setting the framerate of the animation to 60fps
Setting a fixed framerate of 50fps in three.js & setting the animation to 50fps
Exporting from different programs (cinema 4d & blender)
Exporting in diffrent formats (gltf & fbx)
I have the feeling that three.js is still doing some interpolations on the animations.
Does someone know a workaround for this?

I found a solutions for my problem, but forgot to post it here ;)
So your animation has to be exported in 50 fps.
Then set your animate function to 50 fps:
function animate() {
setTimeout( function() {
requestAnimationFrame( animate );
}, 1000 / 50 );
//stats.update();
controls.update();
render();
}
Now you have to "turn off" the keyframe interpolation for every track using THREE.InterpolateDiscrete
gltf.animations.forEach(( clip ) => {
for ( track in gltf.animations[ 0 ].tracks) {
gltf.animations[ 0 ].tracks[track].setInterpolation (THREE.InterpolateDiscrete);
}
gltf.animations[ 0 ].tracks[0]
const animation = mixer.clipAction(clip);
mixer.clipAction( gltf.animations[ 0 ] ).play();
animation.play();
});

Related

Disabling WebGL gl.BLEND doesn't Work

I use THREE.js and enable alpha canvas: (because I need to build my WebGL on top of something else)
this.renderer = new THREE.WebGLRenderer({ canvas: this.canvas, antialias: false, alpha: true });
I set the clear color like this:
this.renderer.setClearColor(0xffffff, 0.0);
In each frame:
_render () {
renderer.clear();
gl.disable(gl.BLEND);
// ... something else doesn't need to be blended, whose alpha value is not 1.0
}
I'm curious why something else still gets blended with the white background even if I disable gl.BLEND.
three.js controls the blending. When you call renderer.render it will set the blending calling gl.enable(gl.BLEND) for each material depending on whether or not that material needs blending.
On top of that, even with blending off you can draw with a non 1.0 alpha which will end up giving use a canvas that can see through to the background.

aframe/threejs camera manual rotation

I am trying to manually tween camera rotation to 0,0:
camera.object3D.matrixAutoUpdate=false;
var orgrot = { x : camera.object3D.rotation.x, y: camera.object3D.rotation.y };
var target = { x : 0, y: 0 };
var tween = new TWEEN.Tween(orgrot).to(target, 500);
tween.onUpdate(function(){
camera.object3D.rotation.x= this.x;
camera.object3D.rotation.y= this.y;
camera.object3D.updateMatrix();
});
The tween works as expected, but I am loosing mouse control over camera.
To get it back I am setting matrixAutoUpdate to true
tween.onComplete(function(){
document.querySelector('#camera').object3D.matrixAutoUpdate=true
});
But after that, the camera rotation changes back to original position (before tween ) and I would like to keep 0,0. What I am missing ? thanks
UPDATE Below is a version using aframe only without going into threejs objects
I think the problem is camera look-control component
When enabled - I can not animate camera rotation or even setAttribute.
I have to disable it first - than fire animation and than enable it again.
But the problem is, when I enable it again:
camera.setAttribute ('look-controls-enabled',"true")
camera goes back to original rotation ( state before reset animation ).
Similar problem when using matrixAutoUpdate=false/true
Here is my pen http://codepen.io/anon/pen/dMjrWd
If you rotate left 30deg, it will fire resetCamera animation - it works as intended.
But only when look component is disabled. If I enable it again in "animationend" event - the rotation will go back to original state and trigger resetCamera again and again
You really should not have to mess with matrixAutoUpdate.
But given that you are, try the following to force the position, quaternion, and scale to match the matrix:
object.matrix.decompose( object.position, object.quaternion, object.scale );
three.js r.76
I see several problems. If you are using aframe you should not access the object3D directly. You should do
cameraEl.setAttribute('position', {x: 0, y: 0; z;0 })
You can apply a tween to any entity using the declarative API
If you want to modify the camera independently of the running tween you can wrap your camera in another entity
<a-entity rotation="0 360 0"><a-entity id="camera" camera><a-animation ...></a-animation></a-entity></a-entity>
try this codeblock, it works for me on aframe 0.8.2
static faceCameraToCoords(camera, coords){
camera.setAttribute("look-controls",{enabled:false})
camera.setAttribute("rotation", coords);
var newX = camera.object3D.rotation.x
var newY = camera.object3D.rotation.y
camera.components['look-controls'].pitchObject.rotation.x = newX
camera.components['look-controls'].yawObject.rotation.y = newY
camera.setAttribute("look-controls",{enabled:true})
}
You can no longer set a-camera rotation after version 0.8.0.
Updated solution for Aframe 0.9.2:
Given the following camera setup:
<a-entity
id="rig"
position="0 1.6 0">
<a-camera position="0 0 0"></a-camera>
</a-entity>
You can directly alter the camera rotation thus:
const cameraEl = document.querySelector('a-camera');
cameraEl.components['look-controls'].pitchObject.rotation.x = newRotation.x;
cameraEl.components['look-controls'].yawObject.rotation.y = newRotation.y;
Make sure the newRotation values are in radians. For example, use THREE.Math.degToRad(newRotation.x).

Three.js webgl renderer for high DPI displays bug?

I have the following logic to create a Three.js R69 WebGL renderer that is supposed to handle high DPI displays. It did for quite a while, but about a week ago one and only one three.js page started rendering like the high DPI was correctly set, but my 3D coordinate origin became the upper left corner of the rendering canvas rather than the expected center of the canvas. (No changes to my environment that I can tell, maybe the browsers auto-updated. I'm testing with Chrome, FF and Safari on OSX 10.10.1)
// create our renderer:
gCex3.renderer = new THREE.WebGLRenderer({ antialias:true, alpha:true,
devicePixelRatio: window.devicePixelRatio || 1
});
// Three.js R69: I started needing to explicitly set this so clear alpha is 1:
gCex3.renderer.setClearColor( new THREE.Color( 0x000000 ), 1 );
gCex3.rendererDOM = $('#A3DH_Three_wrapper');
gCex3.rendererDOM.append( gCex3.renderer.domElement );
// fbWidth & fbHeight are w,h of a div located within the page:
gCex3.renderer.setSize( gs.fbWidth, gs.fbHeight, true ); // 'true' means update the canvas style
Checking the latest R69 examples, they don't seem to do anything special for high dpi displays. Checking the WebGLRenderer source, it looks like the devicePixelRatio logic is now embedded within the WebGLRenderer() function.
I've tried that minimal logic in the examples, specifically this:
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setClearColor( new THREE.Color( 0x000000 ), 1 );
renderer.setSize( gs.fbWidth, gs.fbHeight, true );
And I see the same behavior: my coordinate system origin is the upper left of the rendering canvas.
Note that in Chrome, when running the javascript debugger, I see a "webgl context lost" event during the exiting of the previous page, but before this logic is being executed. Could the WebGLRenderer be getting created during the period when there is no WebGL context?

music visualization with webgl and three.js

Can you help me? I try to make music visualization http://webmaster9.ru/freelance/mysicusa/ it based on http://iacopoapps.appspot.com/hopalongwebgl/
I have signal (level of music) but cant change visual effects according music. It use
var materials = new THREE.ParticleBasicMaterial( { size: (3 ), map: sprite1, blending: THREE.AdditiveBlending, depthTest: false, transparent : true } );
materials.color.setHSV(hueValues[s], DEF_SATURATION, DEF_BRIGHTNESS);
var particles = new THREE.ParticleSystem( geometry, materials );
particles.myMaterial = materials;
1 Can I change opacity or brightness according music? Probably using controls? can you show me examples?
2 Can I change texture according music?
2 Can I add light and change light according music?
Thank you
For sure you can get the generated audio data from DOM and use in WebGL javascript part to handle values or even use THREE.js to handle those values.
Just take a look how web-audio works

Using CreateJS to apply an alpha tween to a drawn line

I'm trying to take a users mouse/touch drawn line and then have it alpha fade out the result using a tween. The problem is when cap and joint style are set to rounded then joint point fades behind the rest of the line. It looks fine when set to miter or bevel.
What I want is a smooth solid fade of the shape. Any ideas?
Fiddle: http://jsfiddle.net/mcfarljw/ZNGK2/
Function for drawing the line based on user input:
function handleMouseMove(event) {
var midPt = new createjs.Point(oldPt.x + stage.mouseX >> 1, oldPt.y + stage.mouseY >> 1);
drawingCanvas.graphics.setStrokeStyle(stroke, 'round', 'round').beginStroke(color).moveTo(midPt.x, midPt.y).curveTo(oldPt.x, oldPt.y, oldMidPt.x, oldMidPt.y);
oldPt.x = stage.mouseX;
oldPt.y = stage.mouseY;
oldMidPt.x = midPt.x;
oldMidPt.y = midPt.y;
stage.update();
}
Tween applied to the shape after line is finished:
createjs.Tween.get(drawingCanvas).to({
alpha: 0
}, 2000).call(function() {
drawingCanvas.alpha = 1;
drawingCanvas.graphics.clear();
});
You'll want to cache the whole shape before fading it out. See the updates I have made to the fiddle. Mainly, take a look at line 52 on the handleMouseUp event.
drawingCanvas.cache(0, 0, 800, 800);
Then, when your fade is complete. Make sure to uncache before showing the object again. Otherwise your graphics.clear() won't work.
drawingCanvas.uncache();

Resources