I have a simple THREE.js scene where I want a point light to move dynamically with the camera. The movement works well but the lighting in the scene is not updated immediately. When I change camera position (and thus light position) it takes some time (approx. 2-3 seconds) till the lighting in the scene renders correctly in respect of the new light position. I have already updated the matrix/matrixWorld of the lights in every frame. Is a further update needed? How to tell Three.js that light position has changed?
There is no specific way needed to tell THREE.js lightsources have changed their positions. Here it is important how to make the update of transformation matrices. I have a lightGroup (instance of Object3D) which is the parent node for all lightsources in my scene. Updating the lightGroup transformation according to the camera works with this setup:
if (camera !== undefined)
{
lightGroup.position.x = camera.position.x;
lightGroup.position.y = camera.position.y;
lightGroup.position.z = camera.position.z;
lightGroup.lookAt(camera.target);
lightGroup.updateMatrix();
lightGroup.updateMatrixWorld();
}
The update of the transformation matrix is the point here. Another approach is to hang the camera into the THREE.js scenegraph and attach lights as its children, if you want to avoid a seperate lightGroup node.
By the way: Specific update of THREE.js scene is only needed if you change the number of lightsources in a scene. See https://github.com/mrdoob/three.js/wiki/Updates at Materials.
I know it is old post, however maybe someone will need other solutions.
To move lights dynamicly with camera You can just attach them to camera.
directionalLight = new THREE.DirectionalLight(0xffffff,0.6);
directionalLight.position.set(0,20,0);
directionalLight.rotation.set(+20/180*Math.PI,0,0);
directionalLight.castShadow = true;
camera.add(directionalLight);
scene.add(camera);
Related
I'm using Blender 2.8 and I just have 2 objects: hand and gun and I want to create animations for them. So, for instance, I want to create a simple firing animation. What I do:
1. I create animation for gun
2. I create animation for hand
But if I switch somehow incorrectly I "lose" the first animation I've created. I tried creating fake users and stuff. I just don't get why I select the armature for which I've just created the animation, it plays, but there are no keyframes.
Here's the vid, here's the file.
Ask me questions if you have any.
The movement may be cached in Blender, you may need to reset the movement cache.
Alternatively, you should look at both the Track Controller and Dopesheet(action editor) - the animation may be stored in both.
The movement could be related to parenting ( to an object that is moving )
The movement could also be caused by physics simulation of a rigid body.
Hopefully with the help of the above, you find the problem.
I had the same problem. In the Animation mode (horizontal tabs across the top of the window), click on the object to animate.
The keyframes will appear.
If the object is not selected, the keyframes disappear.
Just leaving this here so that nobody spends 30 minutes trying to work this out, like i just did.
I am trying to replicate a view from a phone (using DeviceOrientationControls) to a desktop (using TrackballControls). I am passing the view state (camera position & direction) through an intermediary server, and have that part mostly working.
I'm having trouble setting the camera rotation on the desktop. The cameras are sync'd to look at the same point, but the view on the desktop (receiving the view state from the phone) rotates around the view angle.
I definitely don't fully understand quaternions or rotation order. I've tried applying those, but clearly I'm out of my element. I guess I'm just looking for some hints on how to sync the camera rotation on the desktop.
Looks like I had a (trackball) controls.update() in my animate() that was blowing away the rotation that I was setting. Camera position and direction are not changed by this, but the rotation (or the "roll" of the camera) was.
In TrackballControls, it would be nice to have a setting for programmatically updating the camera's rotation that wouldn't get squashed by a call to rotateCamera(). I'll have to think about that, because it doesnt seem like it would be easy to implement.
I may be making this harder than what it really is, but I am also pretty new to developing games. Currently I am making a practice scene to get back used to the unity engine as I have not had time to use it since last summer. My issue is that I can not figure out how to lift the camera in game mode. Notice my photo below, and how much of the "underground" is showing. I want to raise the camera to keep it at the very least a specific y axis value, so that I can make less of the ground visible, and more of the background visible. If I am over complicating this, please also let me know. Thank you
If main camera is still then just lift the camera in scene view you can see changes in game view.
Or if camera moves with respect to player then you have to use a script and attach it to camera and get a reference of player transform in the script and according to the player position change position of the camera. Add an offset value in y component of the camera.
I would like to know how Blender's border render works internally. How can Blender compute lights if it has not information about the lights in the tiles he won't render? I have not found any reference (source code excluded) on how this feature of blender works. Can somebody explain it (or give me some reference)?
The render border setting only alters what part of the image is rendered, it does not alter what data is sent to the render engine to generate the image.
You can test this by placing an object with a reflective surface in front of the camera and another object behind the camera, the object behind the camera will show in the reflection. The border setting doesn't change the reflection in the object, it only changes what part of the image is rendered.
Rendering an image starts at the pixel that will be visible in the final image and sends a "ray" into the scene to determine what colour the specific pixel will be. Each ray will bounce around in the scene from object to object to light source based on render settings to calculate the final result. While the render border will reduce the pixels used as the starting point for each ray, it does not reduce the objects or lights in the scene that each ray may come into contact with. Each ray going through the scene will see every visible object and light in the scene that can influence the final result for each pixel.
This conference video explains ray types and might give you a better grasp of how a ray goes through a scene to get the final image.
Does a particular method get called when an SCNNode is removed from the scene?
-(void)removeFromParentNode;
Does not get called on the SCNNode object.
To set the scene
I am using gravity to pull down an object. When an object goes too far down, it automatically disappears and the draw calls and polygon counts decrease. So the SCNNode is definitely being destroyed, but is there a way I could hook into the destruction?
Other answers covered this pretty well already, but to go a bit further:
First, your node isn't being removed from the scene — its content is passing outside the camera's viewing frustum, which means SceneKit knows it doesn't need to issue draw calls to the GPU to render it. If you enumerate the child nodes of the scene (or of whatever parent contains the nodes you're talking about), you'll see that they're still there. You lose some of the rendering performance cost because SceneKit doesn't need to issue draw calls for stuff that it knows won't be visible in the frame.
(As noted in Tanguy's answer, this may be because of your zFar setting. Or it may not — it depends which direction the nodes are falling out of camera in.)
But if you keep adding nodes and letting physics drop them off the screen, you'll accumulate a pre-render performance cost, as SceneKit has to walk the scene graph every frame and figure out which nodes it'll need to issue draw calls for. This cost is pretty small for each node, but it could eventually add up to something you don't want to deal with.
And since you want to have something happen when the node falls out of frame anyway, you just need to find a good opportunity to both deal with that and clean up the disappearing node.
So where to do that? Well, you have a few options. As has been noted, you could put something into the render loop to check the visibility of every node on every frame:
- (void)renderer:(id<SCNSceneRenderer>)renderer didSimulatePhysicsAtTime:(NSTimeInterval)time {
if (![renderer isNodeInsideFrustum:myNode withPointOfView:renderer.pointOfView]) {
// it's gone, remove it from scene
}
}
But that's a somewhat expensive check to be running on every frame (remember, you're targeting 30 or 60 fps here). A better way might be to let the physics system help you:
Create a node with an SCNBox geometry that's big enough to "catch" everything that falls off the screen.
Give that node a static physics body, and set up the category and collision bit masks so that your falling nodes will collide with it.
Position that node just outside of the viewing frustum so that your falling objects hit it soon after they fall out of view.
Implement a contact delegate method to destroy the falling nodes:
- (void)physicsWorld:(SCNPhysicsWorld *)world didBeginContact:(SCNPhysicsContact *)contact {
if (/* sort out which node is which */) {
[fallingNode removeFromParentNode];
// ... and do whatever else you want to do when it falls offscreen.
}
}
Your object will disappear if it goes further than the ZFar property of your active camera. (default value is 100.0)
As said by David Rönnqvist in comments, your Node is not destroyed and you can still modify its property.
If you want to hook-up to your Node's geometry disappearance, you can calculate the distance between your active camera and your Node and check it every frame in your rendering loop to trigger an action if it gets higher than 100.
If you want to render your Node at a greater distance, you can just modify the ZFar property of your camera.