See http://www.xpos.nl/clock/ for problem at hand.
The page also has links to video's of an animation and real clock of what I'm trying to achive with three.js.
It's a clock with 2 leds rotating around a pin in the center. The shadows make the hands of the clock.
I'm a complete novice when it comes to three.js/webgl, but with some help of 'experts' on three.js I/we got this far:
http://www.xpos.nl/clock/
(the clock ticks with one minute per second to speed up the animation)
The one thing is missing: the hands of the clock. The center pin does not show the shadows the spotlights should cast.
Why does the center pin does not have any shadows?
To cast shadows in three.js, you must add:
renderer.shadowMap.enabled = true;
light.castShadow = true;
three.js r.73
Related
I want to render a room with a floor + roof that is open to one side. The room contains a point light and the "outside" it lit by an ambient light (the sun). There is one additional requirement: The user should be able to look inside the room to see whats going on. But I cannot simply remove the roof because then the room is fully lit by the ambient light.
I think my problem could be solved by having 3d objects that are transparent by still are blocking the light.
To give you an idea about my current scene, this is how it looks like:
The grey thing is the wall of my room. The black thing is the floor of the room. The green thing is the ground of the scene. The room contains a point light.
I am currently using two scenes (see Exclude Area from Directional/Ambient Lighting) because I wanted the inside of the room to be unaffected by the ambient light. But now my lights can only affect either the inside of my room (the point light) OR the outside (the ambient light) but not both.
A runnable sample of my scene can be found here:
https://codesandbox.io/s/confident-worker-64kg7m?file=/src/index.js
Again: I think that my problem could be solved by having transparent objects that still block the light. If I had that I would simply have a 3d plane on top of my room (as the roof) and make it transparent... It would block the light that is inside of the (but still let it go outside if the room is open) and it would also block the ambient light (partially - if the room is open)...
Maybe there is also another solution that I am not seeing.
Just use one scene instead of two, then enable shadows across the relevant meshes so a light doesn't cross from inside to outside. Once you're using only one scene, the steps to take in your demo are:
Disable AmbientLight, and use DirectionalLight only, since AmbientLight illuminates everything indiscriminately, and that's not what you want.
Place the directional light above your structure, so it shines from the top-down.
Enable shadow-casting on the walls
Add a ceiling mesh with the material's side set to side: THREE.BackSide. This will only render the back side of the Mesh, which means it won't be visible from above, but it will still cast shadows.
const roomCeilMat = new MeshStandardMaterial({
side: BackSide
});
const roomCeiling = new Mesh(roomFloorGeo, roomCeilMat);
roomCeiling.position.set(0, 0, 1);
roomCeiling.castShadow = true;
scene1.add(roomCeiling);
See here for a working copy of your demo:
https://codesandbox.io/s/stupefied-williams-qd7jmi?file=/src/index.js
I would assign a flat, emissive material to the room. Or a depth gradient if it becomes terrain. Since ambient light doesn't cast shadow. It saves a light and extra geometry or groups. Plus web model viewer(s) would probably render it better. If you're doing a reveal transition, use a clip plane or texture alpha mask.
It depends on the presentation versus the output format. Also it depends on the complexity of the final floorplan. If your process is simple it will run Sims Lite on a Raspberry Voxel.
I'm using THREE.OrbitControls to dolly a THREE.OrthographicCamera. But, even thought the ortho camera renders correctly as repositioned, all that is updating on the orthographic camera is the 'zoom' property. Even after calling camera.updateProjectionMatrix(). Do I need to manually update the 'position' property of the camera based on the updated 'zoom' property? I want to display its position in my UI after dollying it.
(Note, this is a rewrite of my other question,THREE.js Orthographic camera position not updating after zoom with OrbitControl, in which I thought I was zooming with the OrbitControl but was actually dollying. Sorry about this).
Dollying in/out with an ortho cam would have an unnoticeable effect. With ortho cams there is no perception of proximity because it has no perspective. All objects appear the same in size regardless of distance from the lens because the projection rays are all parallel. The only difference you'd notice is when the objects get clipped because they're past the near or far plane.
So, the decision was made that scrolling with OrbitControls would change the zoom of the camera, narrowing in/out of the center.
If you want to force the camera to move further/closer of its focus point, you could just translate it back/forth in the z-axis with:
camera.translateZ(distance); A (-) distance would move it closer, and a (+) distance would move it further from its focus point.
Is it possible to have a custom geometry emit light in Three.js?
There is a similar question from 5 years ago here.
In my particular case, I have created a TorusGeometry. I would like this torus to also give off light. Is that possible?
The only true way to do this is raytracing, in which case your torus becomes an "emitter" of photons and its geometry is used to calculate the initial directions of said photons.
Otherwise, light technically doesn't exist. Only (mathematical) descriptions of lights exist. (Remember, lights aren't visible/aren't rendered unless you're using a LightHelper.) These descriptions are used by material shaders, which use the light descriptions (and other objects in the scene, in the case of shadows) to determine the color the current fragment should contribute to a pixel.
With this in mind, if you could write a shader to handle a torus-shaped light, then all you need to do is provide that light's information to the shader. You can do this by extending a THREE.js light class to make your own TorusLight to add to the scene, then give the objects in your scene your custom shader.
THAT SAID, if you'd be satisfied with simulating the torus light, and want a visible torus, you can always add a PointLight at the position of your torus (or several throughout the body of the torus), and give your torus some kind of glow effect.
I've been struggling with an application where I'm trying to set the camera rotation initially so when the scene is loaded, you'll be looking where we want you to look.
The backstory, I'm creating a panorama viewer where the panorama is applied to a mesh with a sphere geometry.
The problem I'm having is I don't seem to be able to set the camera rotation. I've tried multiple attempts, but none have been working. I attempted setting the camera rotation after creating the camera, and I tried applying the target of my orbitcontrols and setting the object rotation in the orbit controls. I haven't had any luck yet with just setting an initial camera rotation.
I'm really hoping at this point that this is due to something minor that I'm over looking.
Here's a source: http://www.freeptools.com/mapster/testing-360s2.php
It shows the camera itself AND the orbit controls object. It also shows what their target is I'm setting, and what they really are. So far I haven't been able to get this to accept anything I give it.
THREE.js OrbitControls take over the camera completely, so you should not use that in conjunction with updating camera rotations.
Instead, OrbitControls has methods that help you do this: https://github.com/mrdoob/three.js/blob/master/examples/js/controls/OrbitControls.js
orbitControls.rotateLeft( angle );
orbitControls.rotateUp( angle );
In addition, you can move orbitControls.target around (it's a THREE.Vector3) and the camera will just look to that direction.
I'm playing around with Three.js, and I'm trying to figure out how to keep a box I have always facing away from the camera.
As of right now, the camera rotates around the box as you drag around. However, the box itself does not rotate. I want to make it so that as you rotate the camera, the box's yaw changes to face away from the camera.
How would I accomplish something like this? At first, I tried to set the .rotation.y of the box to the .rotation.y of the camera, however that didn't work
What you are describing should work. I have made a fiddle you can check out and compare your code to: fiddle
Here is a snippet from the animate function:
//quick and dirty way to spin the camera around the world center
camera.position.set(0, 0, 0); //move to world center
camera.rotation.y += 0.01; //rotate camera around world center
camera.translateZ(300); //move backwards
//match
cube1.rotation.y = camera.rotation.y;
If you post your code here or on JSFiddle I might be able to help figure out what in your code is misbehaving