How to auto focus camera on a point in three.js? - javascript

I want to know is there any built-in feature for auto focus a camera into a point in three.js so that the rest of the environment became relatively blur like something we have in these examples ?
http://alteredqualia.com/xg/examples/animation_physics_level.html
http://alteredqualia.com/xg/examples/animation_physics_ammo.html
The code in XG library that enabled auto focus, is something like this:
renderer.dofEnabled = false;
renderer.dofAutofocus = true;
renderer.dofAutofocusPoint.set( 0.5, 0.35 );
renderer.dofFocusDistance = 10;
renderer.dofFocusMaxBlur = 0.2;
I don't know about the XG library history but It seems that XG library in above links, is based on three.js but we don't have any camera auto focus or dofEnabled in three.js.
If there is some easy way to do it in three.js, please let me know, if not, any suggestions to know how to implement it is so much appreciated.
I don't know, but It seems that XG library is something private and the code is obfuscated so I can't find out how the focus feature implemented.

I just find out that, this effect is called "depth of field" (dof) and already implemented by using MeshDepthMaterial and there is an example in threejs website:
http://threejs.org/examples/webgl_postprocessing_dof.html

Related

Reposition camera to object & lookAt() (React three fiber)

I am trying to transition camera.position and camera.lookAt smoothly between "zoomed out" and "zoomed in" views of individual, randomly placed objects.
The positioning works great. Lerping the lookAt(), however, doesn't seem to be playing nicely with other solutions for traditional ThreeJS ( see #bovesan's answer here) nor addressed by the relevant example on the react-three-fiber docs (link).
Zooming in past the z axis flips the camera around, and at the corners it's wildly distored.
You can see my progress here : https://codesandbox.io/s/three-fiber-zoom-to-object-rlme0?file=/src/App.js
With the relevant bit of code being in App.js on line 63 :
useFrame((state) => {
const step = 0.05;
// `focus` is a state variable that sends a Vec3 of the objects position
zoom ? vec.set(focus.x, focus.y, focus.z + 0.2) : vec.set(0, 0, 5);
// HERE, looking for a way to lerp camera lookAt in a way that can toggle.
state.camera.lookAt(0, 0, 0);
state.camera.position.lerp(vec, step);
state.camera.updateProjectionMatrix();
});
I've spent hours looking for relevant examples/tutorials, but haven't come up with much. I'm afraid I don't have enough ThreeJs experience to be looking in the right direction, though, so any help in any direction would be most welcome.
To anyone who happens upon this later, the solution was figured out over at by #drcmda.
You can find a working example here :
https://codesandbox.io/s/three-fiber-zoom-to-object-camera-controls-solution-final-sbgx0?file=/src/App.js
This is just a slight change on #drcmda 's implementation of camera-controls with normal lerping to move the camera. It’s not perfect (for one, the transition time in camera controls doesn’t seem to be editable, so there’s a weird swing-around thing that happens, when you’re zooming back out) but it definitely solves the problem. (Many thanks to #looeee and #forerunrun for additional help.)
If you'd rather not use another library, #forerunrun's answer in the original thread also works well, but I wasn't able to debug it enough to have it be reliable. (See convo.)

ThreeJS/Panolens: direction of the camera when panorama entered?

I'm trying to throw an equirectangular image into Panolens and simply 1st get the same panorama viewer as can be visible below:
https://threejs.org/examples/webgl_panorama_equirectangular.html
https://www.chiefarchitect.com/products/360-panorama-viewer/
Since Panolens.js is a wrapper of Three.js I expected the same result as when I throw my image into the 1st link above. (drag & drop it) - camera looks into the center of the image.
What I get instead is : camera looks into the left most area of the panorama image.
I solve this using
panorama.addEventListener( 'enter-fade-start', function() {
viewer.getControl().target.set(10, -2, 0);
viewer.getControl().update();
//viewer.tweenControlCenter( new THREE.Vector3(2, -1, 1), 2000 );
});
But when I move to another panorama and come back, this code does not seem to have any effect (althought event is properly triggered).
How can I make the camera look into the same direction each time I come back to my panorama? (I'm switching between multiple panoramas).
Basically I don't seem to understand vectors properly and where 0,0,0 is each time I come back to panorama, since It seems to be working differently based on where the camera is facing.
Any tips/links/explanations very much welcome.
I over complicated things it seems. The solution is to only use:
viewer.tweenControlCenter( new THREE.Vector3(10, -2, 0), 0 );
inside "enter-fade-start". And that's it.
Much of docs is a bit misleading with saying you have to call .update() on control and setting .target properly etc, but that does not seem to work as I expected.
Relevant example also here: https://codepen.io/pchen66/pen/LLgxME

Three.js matcap material being washed out

I'm trying to implement a matcap shader on a 3D scene based on this: https://threejs.org/examples/webgl_materials_matcap.html
But when I do, it becomes washed out: http://snow3.co.uk/bigger-picture/goo/index.html
See my original map-cap for comparison:
(source: snow3.co.uk)
I'm not sure if i'm importing the image wrong or I'm blind to some kind of colour transform.
Turns out I had gammaOutput (renderer.gammaOutput = true;) enabled in the renderer which was causing it! All fixed.

Vis.js - Only show finished network diagram, no animation, no interaction

I am a little bit struggling on how to use Vis.js to only show the final result of a stabilized graph, without any stabilization animation or interaction possibilities.
Is there someone that could push me to the correct direction?
If I disable physics completely, the graph shows all nodes one overlaying the other naturally.
Thank you already!
EDIT
Here is the code that I have for the options:
Stabilization stabilization = new Stabilization();
stabilization.setFit(true);
BarnesHut barnesHut = new BarnesHut();
barnesHut.setGravitationalConstant(-23000);
barnesHut.setCentralGravity(0);
barnesHut.setSpringLength(0);
barnesHut.setSpringConstant(0.5f);
barnesHut.setDamping(1);
barnesHut.setAvoidOverlap(1);
Physics physics = new Physics();
physics.setEnabled(true);
physics.setBarnesHut(barnesHut);
physics.setSolver(Physics.Solver.barnesHut);
Smooth smooth = new Smooth();
smooth.setEnabled(false);
smooth.setType(Smooth.Type.continuous);
smooth.setRoundness(0);
Edges edges = new Edges();
edges.setSmooth(smooth);
Interaction interaction = new Interaction();
interaction.setDragNodes(false);
Options options = new Options();
options.setPhysics(physics);
options.setEdges(edges);
options.setInteraction(interaction);
Please be aware that this code is used for a wrapper around vis.js, although the options should reflect the vis.js options.
So it is ok if the answer does not contain any Java code but the actual vis.js hints, I will map it to the wrapper implementation myself.
Seems like the animation is disabled by default, by having the stabilize option set to true.
If you still see an animation, then try to increase the iterations option, which is by default set to 1000.
options.setStabilizationIterations(2000);
I have created a simple demo using the latest version of Vis.js (4.19). Bear in mind that the VisJs-Addon uses an older verion of Vis.js (3.11).

A roulette wheel in javascript

I am trying to build a roulette wheel in javascript.
I found this example: http://www.switchonthecode.com/tutorials/creating-a-roulette-wheel-using-html5-canvas but I find the look & feel not very terrible.
Since my roulette will have a limited number of option, I was thinking of using an image and then place text above with the proper angle. When spinning the wheel, I would just make the image and the text turn.
Is it a good approach? Are there some better approaches?
You can also do that with css3 rotation but it will work only on newer browsers
You can do even better. Make hole roulette wheel in SVG, it support animation and it can be programmed in javascript
Well I think the best approach in terms of creating something quickly and easily is to use an existing Javascript library for creating spinning prize/winning wheels.
I am the creator of a Javascript library called Winwheel.js which is specifically for this purpose. See http://www.dougtesting.net
One great feature about my Winwheel.js is that you can mix a graphically rich image for the face of the wheel with code-drawn text for the segment labels, so if you want the wheel to look really nice but have the flexibility of configurable text, you can.
Here is an example of the code needed to do this using Winwheel.js...
var myWheel = new Winwheel({
'drawMode' : 'image',
'drawText' : true, // Set this to true for text to be rendered on image.
'numSegments' : 4,
'textOrientation' : 'curved', // Set text properties.
'textAlignment' : 'outer',
'textMargin' : 5,
'textFontFamily' : 'courier',
'segments' : // Set segment text
[
{'text' : 'Television'},
{'text' : 'Mobile Phone'},
{'text' : 'Old Radio'},
{'text' : 'Computer'}
]
});
var wheelImg = new Image();
wheelImg.onload = function()
{
myWheel.wheelImage = wheelImg;
myWheel.draw();
}
wheelImg.src = "wheel_image.png";
There is a full set of tutorials on my site explaining how to use Winwheel.js, but the particular one about Image wheels can be found here http://dougtesting.net/winwheel/docs/tut9_creating_with_an_image
Thanks,
DouG
jQuery is not necessary. The example was done using the HTML5 Canvas element, which is probably the only (clean) way you could do it without Flash or Silverlight. You can customize the colors using the first array in the code, or any other nuance of it with a little tinkering.
You could use an SVG (Scalable vector graphics format) image and rotate it.
I wrote http://roulette.dabase.com/ as an exercise which works on mobile browsers I've tried.
I actually implemented a similar mini-game on my site not too long ago. No canvas, no SVG, no jQuery.
I used a simple image for the board (more specifically as a background-image), then placed a <div> on it to be the ball.
<div id="board"><div></div></div>
CSS:
#board {
width:256px;
height:256px;
background-image:url('gameboard.png');
position:relative;
transform-origin:50% 50%;
}
#board>div {
position:absolute;
margin-left:-7px;
margin-top:-7px;
border:7px outset #ccc;
width:1px; height:1px;
left:248px;
top:128px;
}
Then this JavaScript is used to position the ball when spinning:
function placeBall(angle) {
var board = document.getElementById("board"), ball = board.children[0];
ball.style.left = (128+Math.cos(angle)*120)+"px";
ball.style.top = (128-Math.sin(angle)*120)+"px";
board.style.transform = "rotate(-"+angle+"rad)";
}
This will result in the ball spinning around the wheel in older browsers. In newer browsers, the ball will stay in place (but the border shading will spin) while the entire board rotates. You can of course use a combination of the two if you do something different on the transformation (for example, "rotate(-"+(angle/2)+"rad)")

Categories