I was very excited when I first saw this example (webgl_geometry_minecraft_oculusrift) in mrdoob/three.js ยท GitHub website. Undoubtedly, it's pretty awesome!
But I'm curious, how to apply this effect on other examples? So I try to implement this effect in the "webgl_interactive_cubes". However, the experimental result is worse than expected.
My problem is that I can't accurately align the cursor to a particular cube to make it change color, seems to be a problem with the projection function? Then I adjusted the screen width coefficient, like this
window.innerWidth * 2
in the whole program. But still can not improve this problem.
Summary my issue :
If I want to apply Oculus Rift Effect on any example, how should I do? by th way, I only added the following code
effect = new THREE.OculusRiftEffect( renderer );
effect.setSize( window.innerWidth, window.innerHeight );
// Right Oculus Parameters are yet to be determined
effect.separation = 20;
effect.distortion = 0.1;
effect.fov = 110;
in initialize block init(); and final added effect.render( scene, camera ); in render();
I am very curious to know how
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
works. Why do need to pass parameter 1? what if I change mouse.x to mouse.x * 2
Need to use dual monitors can only be fully present this effect?
Note: My English is not very good, if I have described is unclear, please ask your doubts, I will respond as soon as possible.
This is my DEMO link:
http://goo.gl/VCKyP
http://goo.gl/xuIhr
http://goo.gl/WjqC0
My Folder : https://googledrive.com/host/0B7yrjtQvNRwoYVQtMUc4M1ZZakk/
The third one is your example right?
This can help you to use the OR-Effect in a easier way:
https://github.com/carstenschwede/RiftThree
And your examples work all, just the third one have to Problem with the Controls. If I drag the move from the Stats-DIV (FPS) It works.
Related
I am trying to make use of Raycaster in a ThreeJS scene to create a sort of VR interaction.
Everything works fine in normal mode, but not when I enable stereo effect.
I am using the following snippet of code.
// "camera" is a ThreeJS camera, "objectContainer" contains objects (Object3D) that I want to interact with
var raycaster = new THREE.Raycaster(),
origin = new THREE.Vector2();
origin.x = 0; origin.y = 0;
raycaster.setFromCamera(origin, camera);
var intersects = raycaster.intersectObjects(objectContainer.children, true);
if (intersects.length > 0 && intersects[0].object.visible === true) {
// trigger some function myFunc()
}
So basically when I try the above snippet of code in normal mode, myFunc gets triggered whenever I am looking at any of the concerned 3d objects.
However as soon as I switch to stereo mode, it stops working; i.e., myFunc never gets triggered.
I tried updating the value of origin.x to -0.5. I did that because in VR mode, the screen gets split into two halves. However that didn't work either.
What should I do to make the raycaster intersect the 3D objects in VR mode (when stereo effect is turned on)?
Could you please provide a jsfiddle with the code?
Basically, if you are using stereo in your app, it means you are using 2 cameras, therefore you need to check your intersects on both cameras views, this could become an expensive process.
var cameras =
{ 'camera1': new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000),
'camera2': new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000)
};
for (var cam in cameras) {
raycaster.setFromCamera(origin, cameras[cam]);
//continue your logic
}
You could use a vector object that simulates the camera intersection to avoid checking twice, but this depends on what you are trying to achieve.
I encountered a similar problem, I eventually found the reason. Actually in StereoEffect THREE.js displays the meshes on the two eyes, but in reality is actually adds only one mesh to the scene, exactly in the middle of the line left-eye-mesh <-> right-eye-mesh, hidden to the viewer.
So when you use the raycaster, you need to use it on the real mesh on the middle, not the illusion displayed on each eye !
I detailled here how to do it
Three.js StereoEffect displays meshes across 2 eyes
Hopes it solves your problem !
You can use my StereoEffect.js file in your project for resolving problem. See example of using. See my Raycaster stereo pull request also.
I have a Box Mesh where I subtract another Box with Three.CSG to create a wall with a window.
After doing so, there are tiny holes in the Mesh alongside the cut. They are not visible alle the time, but show up when moving around.
How to close these holes?
This is part of the code how I am creating the Mesh:
var wallBsp = new ThreeBSP( myWallMesh );
var subMesh = new THREE.Mesh( mygeo );
var subBsp = new ThreeBSP( subMesh );
var subtract_bsp = wall_bsp.subtract( subBsp );
var result = subtract_bsp.toMesh();
result.material.shading = THREE.FlatShading;
result.geometry.computeVertexNormals();
Update
I have created a jsfiddle, but it is difficult to reproduce the error, I couldnt make it visible there: http://jsfiddle.net/L0rdzbej/23/
However, you can see the full application here.
Like #gaitat suggested, geometry.mergeVertices() does not look like it changes anything for me. Chandler Prall hinted at the source where precisionPoints, which is a variable inside the mergeVertices function, could solve this. Depending on the scale of the scene its value should be lower or negative, but I had no success so far.
I'm currently working on my first three js project, and getting quite an education. But, I've hit a wall, and am seeking a generalized outline of what to do.
I have three images that I want to use as background images. I want them to crossfade at a specified interval... let's say every 5 seconds, the background crossfades to the next one. After the last background is displayed, crossfade into the first one, and so forth in a loop.
I've found a few examples where there's crossfading between two objects, like this fiddle, but that seems to depend on having two cameras. I've taken other examples I've found as far as I could, nothing worthy of posting.
I don't understand enough about three, which is why I'm seeking help. If someone could help me define my approach, that would be fantastic. Should I be altering the opacity of my meshes? Doing something with shaders? Something else?
Here, at least, is how I'm adding one background:
camera = new THREE.PerspectiveCamera( 75, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
camera.position.z = 450;
scene = new THREE.Scene();
// Load the background texture
var summerTexture = THREE.ImageUtils.loadTexture( 'tree-animation/images/summer.png' );
summerMesh = new THREE.Mesh(
new THREE.PlaneGeometry(2, 2, 0),
new THREE.MeshBasicMaterial({
map: summerTexture,
}));
summerMesh.material.depthTest = false;
summerMesh.material.depthWrite = false;
backgroundCamera = new THREE.Camera();
summerScene = new THREE.Scene();
summerScene.add(backgroundCamera);
summerScene.add(summerMesh);
Any direction would be most appreciated!
This can be achieved by writing a custom shader and using the mix() or smooth-step() function between the images and add a clock to your render loop to update the shader uniforms to manipulate the transition in your shader over time.
Here is an example of a static blend of textures but can easily intergrated into your own project:
http://stemkoski.github.io/Three.js/Shader-Heightmap-Textures.html
check the frag shader
I would like somebody to explain me how I can achieve the blue semi-transparent intermittent sphere of this example: (the one next to the intermittent red sphere)
http://threejs.org/examples/webgl_materials.html
I believe in first place that this is a matter of using the right material with the right settings (specially because the example is about materials) but not sure anyway.
Hopefully you do not feel my question does not deserve to be made here. I was trying to analyze it but definitely it is written in a non-friendly way for newbies, and I've not been able to separate this part from the rest, not I find an explanation anywhere else.
To create, for example, a partially transparent blue sphere, you could try:
var sphereGeom = new THREE.SphereGeometry( 40, 32, 16 );
var blueMaterial = new THREE.MeshBasicMaterial( { color: 0x0000ff, transparent: true, opacity: 0.5 } );
var sphere = new THREE.Mesh( sphereGeom, blueMaterial );
For more examples of creating semi-transparent materials, check out
http://stemkoski.github.io/Three.js/Translucence.html
If you want the sphere to fade in and out, you can change the transparency in your update or render function -- make the sphere a global object, also create a (global) clock object to keep track of the time in your initialization, for example, with
clock = new THREE.Clock();
and then in your update, you could, for example, write
sphere.material.opacity = 0.5 * (1 + Math.sin( clock.getElapsedTime() ) );
Is there is any way to manage Mesh size and position accordingly to display size.
What i am doing is a simple animated presentation which will have camera Zooming and changes in scene/camera position.
If the screen size is differs Mesh positioning and mesh size all are going wrong..
I have no idea how to take control on this?
How to find if a mesh position on screen?
My hunch is that someone smart is going to come along and give you the solution that you really want (something like how to move the camera so object stay the right position/size), but here are some direct answers to your questions that might help.
You could manage the mesh size by making the proportions some function of window.innerWidth and window.innerHeight.
To determine if a mesh is on screen, you can use the following code. It projects a mesh position in 3D space to 2D space in the browser. Also, be sure to call camera.updateMatrixWorld() after you move the camera or change what you are looking at--elsewise you will get wonky results (thanks to WestLangley for that tip). If vector.x > window.innerWidth or vector.x > window.innerHeight, then the object is outside of the viewable area of the screen.
function toXYCoord (object) {
var vector = projector.projectVector(object.position.clone(), camera);
vector.x = (vector.x + 1)/2 * window.innerWidth;
vector.y = -(vector.y - 1)/2 * window.innerHeight;
return vector;
}
what you want to do is check for resize on either the screen, or as in the example below, a 'bucket' div that i use as a container...when i resize the div (programmatic-ally or otherwise) i just make sure to call onBucketResize()
function onBucketResize() {
camera.aspect = bucket.clientWidth / bucket.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize( bucket.clientWidth, bucket.clientHeight );
}
to setup, you could use something like:
bucket.addEventListener( 'resize', onBucketResize, false );
or maybe
document.addEventListener( 'resize', onBucketResize, false );
whatever is appropriate :)
let me know if this helps!