admin管理员组文章数量:1277896
I have a three.js scene with a textured floor plane that needs a very specific perspective to align with a static 2D overlay
My problem is that the more I increase the camera FOV to get the perspective I need the more the foreground stretches and I don't want that. I seem to need a very high FOV (~ 120 - 150) to make the texture follow the wall and this is so high that the camera is rendering things positioned BEHIND it. I need to move the camera almost to the center of the scene just to show the whole floor and this just feels wrong. How can I adjust this scene so I get the right perspective without the distortion?
Live example: .basic.php
The relevant camera settings are:
var WIDTH = 1024;
var HEIGHT = 683;
var FOV = 140; // Increases perspective as it goes higher but also distortion
camera = new THREE.PerspectiveCamera(FOV, WIDTH/HEIGHT, .1, 3000);
camera.position.x = 0;
camera.position.y = 200;
camera.position.z = 0;
//camera.lookAt(scene.position);
camera.lookAt(new THREE.Vector3( 0, 100, -400 )); // look at the back of the room
camera.updateProjectionMatrix();
I have a three.js scene with a textured floor plane that needs a very specific perspective to align with a static 2D overlay
My problem is that the more I increase the camera FOV to get the perspective I need the more the foreground stretches and I don't want that. I seem to need a very high FOV (~ 120 - 150) to make the texture follow the wall and this is so high that the camera is rendering things positioned BEHIND it. I need to move the camera almost to the center of the scene just to show the whole floor and this just feels wrong. How can I adjust this scene so I get the right perspective without the distortion?
Live example: http://warriorhut/testing/shapes/backend/room/view.basic.php
The relevant camera settings are:
var WIDTH = 1024;
var HEIGHT = 683;
var FOV = 140; // Increases perspective as it goes higher but also distortion
camera = new THREE.PerspectiveCamera(FOV, WIDTH/HEIGHT, .1, 3000);
camera.position.x = 0;
camera.position.y = 200;
camera.position.z = 0;
//camera.lookAt(scene.position);
camera.lookAt(new THREE.Vector3( 0, 100, -400 )); // look at the back of the room
camera.updateProjectionMatrix();
Share
Improve this question
edited Jun 4, 2015 at 0:26
user128511
asked Jun 3, 2015 at 7:58
SpliFFSpliFF
39k16 gold badges93 silver badges121 bronze badges
9
- It is unclear why you need such high perspective – gaitat Commented Jun 3, 2015 at 12:30
- How about modifying the uv's instead? – LJᛃ Commented Jun 3, 2015 at 13:45
- @gaitat Just look at the picture, the carpet should line up with the wall and the whole thing should look like it was viewed from a regular persons viewpoint. I can increase FOV to get the wall to line up BUT it causes that foreground stretching you see. – SpliFF Commented Jun 3, 2015 at 16:26
- @LJ_1102 The carpet texture is dynamically generated, I just want to map it to the floor plane like real carpet, I shouldn't have to distort it. – SpliFF Commented Jun 3, 2015 at 16:29
- 1 maybe you need to highlight in the image where the problem is because I see the carpet line up perfectly with the wall. But maybe we have different definition of 'line up'. Also an image where the FOV is set to 45 might better highlight the issue. – gaitat Commented Jun 3, 2015 at 17:14
3 Answers
Reset to default 9 +150Adding a virtual object to an existing image requires matching the original camera parameters as closely as possible. In this case because the image is synthetic, ideally you would obtain those parameters from whoever generated it. Otherwise we can try to infer some of the parameters by taking measurements on the image.
I'll make the standard assumption of a pinhole camera, and further assume that the optical axis is at the center of the image. Parallel lines in the scene will meet at a vanishing point. In this image we can determine only one vanishing point with any accuracy:
The parallel lines here are also parallel to the ground plane, which means that the vanishing point is on the horizon. The horizon is thus slightly below the center of this image, which means that the camera is pitched slightly upwards.
How much upwards? The vanishing point is about 0.022 image heights (15 pixels) below the center of the image. We can express the indicated camera pitch in terms of the vertical field of view:
pitch = arctan(2 * tan(vfov/2) * 0.022)
We can similarly determine the yaw of the camera with respect to the parallel lines. The vanishing point is about 0.010 image heights right of center so the camera yaws slightly left.
yaw = arctan(2 * tan(vfov/2) * -0.010)
To express this in the three.js application, I modified the camera configuration section of the code like this:
var FOV = 75;
[...]
camera.position.x = 0;
camera.position.y = 200;
camera.position.z = 512;
var lookTarget = new THREE.Vector3().copy(camera.position);
var tanScale = 2 * Math.tan(FOV/2 * Math.PI/180);
lookTarget.x += -0.010 * tanScale;
lookTarget.y += 0.022 * tanScale;
lookTarget.z += -1;
camera.lookAt(lookTarget);
camera.updateProjectionMatrix();
I moved the camera backwards (toward positive Z) a bit to make most of the floor geometry visible (this doesn't change the vanishing point of the rendered geometry). Then I changed FOV
to 75 degrees (still quite a wide angle view), and the texture pattern now automatically converges at the vanishing point with much less perspective distortion:
Note that you can now see the end of the floor geometry because assuming a smaller field of view increases the assumed depth of the image, so you may need to increase the size of the floor. You can modify the field of view to adjust the texture foreshortening and the camera code should keep the vanishing point in the same place. I don't believe there are sufficient features in this particular image to let us estimate its actual focal length, but it it may be possible in other images - in that case we could deduce the field of view as well.
Solved through trial and error. Solution was to increase the camera tilt upwards to increase the distance falloff rather than increasing FOV
var FOV = 100;
camera.position.x = -100;
camera.position.y = 540;
camera.position.z = 3500; // Moved further back
//camera.lookAt(scene.position);
camera.lookAt(new THREE.Vector3( 0, 590, -1000 )); // look at the back of the room AND TILT UPWARDS!
IMHO these fixed number look very bad and some time other your code won't handle (might be handling the situation now, why don't you try the generic lookAt method. Means this is generic problem Open GL has three argument with camera lookAt. eye,center and upside down vector. More over playing with FOV is not good option.
I have game on Webgl and what i do is place the camera behind object http://stemkoski.github.io/Three.js/Chase-Camera.html Might be this link is usefull.
If not then you can make genric solution like:
if(typeof fc == "undefined") fc=0;
var delta =0.02;
var y=object.rotation.y;
var dir=object.rotation.y-fc;
var fc = THREE.Math.clamp( fc + 2 * delta * dir, y-control.followRadius, y+control.followRadius );
var sn = Math.sin( fc);
var cs = Math.cos(fc);
camera.rotation.set(0,0,0);
camera.position.x=object.position.x+(control.positionOffsetZ*sn);
camera.position.y=object.position.y+control.positionOffsetY;
camera.position.z=object.position.z+(control.positionOffsetZ*cs);
camera.lookAt(new THREE.Vector3(
object.position.x+(control.targetOffsetZ*sn)
,object.position.y+control.targetOffsetY
,object.position.z+(control.targetOffsetZ*cs)
));
var control = {"positionOffsetZ":-39,"positionOffsetY":3.2,"targetOffsetZ":5,"targetOffsetY":0,"followRadius":0.35
});
consider the "object" is the dummy invisible cube on which your camera is attached and you are moving the same with the key control. You can directly paste this code snippet into your and things wirk. If any question or doubt feel free to ask.
本文标签: javascriptHow to increase perspective without stretching foreground in threejsStack Overflow
版权声明:本文标题:javascript - How to increase perspective without stretching foreground in three.js - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741230155a2361970.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论