Objects distort if near the canvas sides - three.js - camera

I have a three.js scene with spheres, but when I zoom in a sphere and I move with orbit controls so it is in the side of the canvas (on in the center and deep in) it looses its round shape (do not care about the lines) :
What can I do ?

There will always be some distortion, but it is worse with a large camera field-of-view (fov).
A reasonable value for camera.fov is 40-45 degrees. A smaller value would produce less distortion.
camera = new THREE.PerspectiveCamera( fov, aspect, near, far );
And for reference, camera.fov is the field-of-view in the vertical direction.
three.js r.70

This is expected behaviour of a THREE.PerspectiveCamera. Try it yourself with a digital camera at home.
The only real way to fix it is to use an THREE.OrthographicCamera, but this likely has other issues you do not want to have, such as objects not becoming smaller when they are further away.

Related

Large (in meters) landscape mesh has artifacts on peaks only at certain scale

I made a mesh from a Digital Elevation Map that spanned 1x1 degree box of geography, but when I scale the mesh up to 11139m in blender I get these visible jagged shadows on the peaks of the mesh. I'd prefer to not scale everything down but I suppose I can, it just seems like a strange issue I want to better understand.
My goal is to use the landscape in a WebVR application, but when I put this mesh into an Aframe scene it also has this issue. Thanks for any tips!
Quick answer:
I think this may be caused by the clipping start/end values. Also called near/far clipping planes. Adjusting them may fix the issue but also limit the rendering distance.
Longer explanation:
Take a look at this:
It's a simple grayscale, but imagine it is scaled across your entire scene depth (Z depth buffer). The range of this buffer is set by the start/stop clipping (near/far) camera setting.
By default Blender has its start/stop (near/far) clipping set to 0.01 - 1000.
While A-Frame has it like 0.005 - 10000. You may find more information here: A-Frame camera #properties
That means the renderer has to somehow fit every single point in that range somewhere on the grayscale. That may cause overlapping or Z-fighting because it is simply lacking precision to distinguish the details. And that is mainly visible at edges/peaks because the polygons are connected there at acute angles and the program has to round up the Z-values. That causes overlapping visible as darker shadows (most likely the backside of the polygon behind).
You may also want to read more about Z-fighting because it is somewhat related.
Example

Parallax effect jitter in libGDX

Basically I'm using this ParallaxCamera class to create the effect in my game, but upon movement, the layers "wiggle". This is especially noticeable when the camera is moving slowly.
I have fixed the timestep and use interpolated smoothing. I use scaled up pixel art. Camera centered on player, updated after movement. Disabling the effect makes moving the camera smooth.
What I guess the issues might be:
the layers move at different paces which means they move at different
times
rounding to display makes the layers assume slightly different positions each frame when moving the camera
Thanks for any help
For low-resolution pixel art, this is the strategy I've used. I draw to a small FrameBuffer at 1:1 resolution and then draw that to the screen. That should take care of jittering.
If your Stage is also at the same resolution, then you have to use a bit of a hack to get input to be processed properly. The one I've used it to use a StretchViewport, but I manually calculate the world width and height to not stretch the world, so I'm basically doing the same calculation that ExtendViewport does behind the scenes. You also have to round to an integer for the width and height. You should do this in resize and apply the width and height using viewport.setWorldWidth() and setWorldHeight(). So in this case it doesn't matter what world size you give to the constructor since it will be changed in update().
When you call update on the viewport in resize, you need to do it within the context of the FrameBuffer you are drawing to. Otherwise it will mess up the screen's frame buffer dimensions.
public void resize(int width, int height) {
int worldWidth = Math.round((float)WORLD_HEIGHT / (float)height * (float)width);
viewport.setWorldWidth(worldWidth);
viewport.setWorldHeight(worldHeight);
frameBuffer.begin();
viewport.update(width, height, true); // the actual screen dimensions
frameBuffer.end();
}
You can look up examples of using FrameBuffer in LibGDX. You should do all your game drawing in between frameBuffer.begin() and end(), and then draw the frameBuffer's color buffer to the screen like this:
stage.act();
frameBuffer.begin();
//Draw game
stage.draw();
frameBuffer.end();
spriteBatch.setProjectionMatrix(spriteBatch.getProjectionMatrix().idt());
spriteBatch.begin();
spriteBatch.draw(frameBuffer.getColorBufferTexture(), -1, 1, 2, -2);
spriteBatch.end();
In my case, I do a more complicated calculation of world width and world height such that they are a whole number factor of the actual screen dimensions. This prevents the big pixels from being different sizes on the screen, which might look bad. Alternatively, you can change the filtering of the FrameBuffer's texture to linear and use an upscaling shader when drawing it.

Three.js camera rotation is weird

I've just started with Three.js. Like really just now.
After playing with it for an hour or so and building a tool that helps me understand how the different elements work together (Camera, Light, Objects), I found something strange.
The tool: http://hotblocks.nl/tests/three/cubes.html
This is the current default set up:
the Camera is positioned 210 upwards and
500 backwards and
246 to the right
the Camera is rotated slightly to the left
the light is directly above and shines in all directions
As you can see, the objects are at the very bottom of the viewport. So I want to turn the Camera downward, so I can see more of them.
Try that: turn camera.rotation.x down.
That works, but the angle of rotation is wrong! Instead of the Camera rotating, it's the World rotating around its Z axis.
That's not right, is it?
The Y axis is also wrong. It rotates the World around its Y axis.
Rotating the Camera around its Z axis, works perfectly: the Camera rotates, not the World.
Am I doing it wrong? Or understanding it wrong?
PS Since the Camera rotation is only around its Y axis, the objects' vertical edges should be vertical in the result as well. In the default set up, they are. Rotating the camera around its X axis, shouldn't change that, but it does. Only rotating around its Z axis should change that (and it does). Am I wrong?
PPS I know about Camera.lookAt( THREE.Vector3 target ), but that changes the rotation of the camera, including its Z axis, and that shouldn't be necessary, logically.
Answer received on Github: https://github.com/mrdoob/three.js/issues/1163

How to warp an UIImage using Open GL or any other method...?

I am trying to develop an iOS app to make any given image (UIImage) warp on selected locations.
So for this task to be accomplished what should be the rightmost way going forward, for now i'm doing some research on doing this on OpenGL (frankly any heads up on the framework would be nice too).
So finally the requirement is to get the UIImage warp on some given locations. (If x, y coordinates are there)
If you're sufficiently familiar with (or willing to learn) OpenGL, then you could do this:
Create a flat, rectangular grid of points to be a mesh that will be displayed with OpenGL.
Apply the image to the mesh as a texture.
When distorting the image at a particular location, you can just decide which points on the mesh will be affected by the distortion, and move them.
You can push points out from the center, or in toward a center, or shift them all in the same direction. If the distortion affects a large area, then you change a lot of points (possibly changing those in the center by more than those near the edges of the affected area).
Not sure what you mean by 'warp'. Do you mean skew it in 3 dimensions? If so you can adjust the CGAffineTransform for the UIImageView you are displaying it in to get that effect.
If you mean some kind of image processing warp, and you are using iOS 5, you can use Core Image for that.

regarding rotating the map in iOS

I am facing this problem while trying to rotate the map in my iPhone app
The view gets clipped and rotation also happens. I want to avoid the clipping. Any tips ?
heres the code:
viewToRotate.layer.transform = CATransform3DMakeRotation(0.8, 0., 0., 1.);
You need your map rotated in 3D ? If not (which is what I think you need), then just use CGAffineTransformMakeRotation (be careful, as it requires the angle in radians).
Also, if you don't want your map to be clipped, you need to make your map bigger, like in the image below (open in new tab to see it bigger)
http://img593.imageshack.us/img593/4498/calculatemapboundswhenr.png
First, you need to calculate the diagonal of the rectangle (your visible map) as instructed in the image above (which I call "radius" because that would be the radius of the smallest circle bigger than your rectangle).
Second, using the radius, you need to calculate the (smallest) square that will allow your map to be seen without clipping. This square will be used to set the bounds of your map (caution: NOT the frame - Apple specifies that, when using rotation, you should not use frame - just bounds and / or center).
Make sure this square is centered on the center of your visible map rectangle (i.e. the square should have X pixels above AND below the small rectangle ... and Y pixels left AND right of the small rectangle).
Hope it helps !
Did you ever figure out the solution?
The only way I could do it was to make the MapView in Interface Builder much bigger than the actual size of the screen area its supposed to cover, then I centered the MapView such that its center was in the center of the narrower viewable area.
Rotation seemed to work similarly to how it works in the built-in Maps app.
My guess is that you have to do this so that the image tiles streaming in from Google cover a wide enough area to "fill in the blanks" so to speak, even if they're not always visable.
If you apply a little math, you could probably programmatically size and position the MapView such that you void clipping, but don't require more tiles than is absolutely necessary.