setNearValue() to a value lesser than 1
setNearValue() to a value lesser than 1
Hello everybody,
I searched Irrlicht Forum and the Internet to solve my problem, but I didn't find any solution. I hope someone can help me...
What I'm trying to do is to set the near plane of the camera to anything lesser than 1. The problem is, then what you see on screen looks kinda distorted like if you set a wrong FOV. I don't think, this is a bug, I rather think changing the FOV should solve that problem. I read somewhere that you can use trigonometry to calculate a new FOV for a camera with near plane like 0.01 or something.
So, my questions are:
1. Is it a good way to use a near value lesser than 1 in order to allow smaller scales of objects? Are there pitfalls like inaccurateness which produce errors or bad looking artifacts or something?
2. How can I compute a new FOV to get a non distorted picture on screen with a near value of lesser than one?
I really hope you understood what I am talking about (english not my mother language) and I really appreciate any help or links or ideas or anything...
If it is not clear to you what I mean, just ask and I will try to explain it furthermore.
Have a nice day,
Ronin
I searched Irrlicht Forum and the Internet to solve my problem, but I didn't find any solution. I hope someone can help me...
What I'm trying to do is to set the near plane of the camera to anything lesser than 1. The problem is, then what you see on screen looks kinda distorted like if you set a wrong FOV. I don't think, this is a bug, I rather think changing the FOV should solve that problem. I read somewhere that you can use trigonometry to calculate a new FOV for a camera with near plane like 0.01 or something.
So, my questions are:
1. Is it a good way to use a near value lesser than 1 in order to allow smaller scales of objects? Are there pitfalls like inaccurateness which produce errors or bad looking artifacts or something?
2. How can I compute a new FOV to get a non distorted picture on screen with a near value of lesser than one?
I really hope you understood what I am talking about (english not my mother language) and I really appreciate any help or links or ideas or anything...
If it is not clear to you what I mean, just ask and I will try to explain it furthermore.
Have a nice day,
Ronin
I don't think distortion would be the result of using a nearvalue of less than 1.
The FOV does not have anything to do with the near and far clipping planes.
Maybe your depth buffer precision is too low.
Say you have a far clipping plane of 2000 (irr default according to the docu), and a near clipping plane of 0.01.
This means the hardware needs to be able to represent a maximum depth of 200000 * the minimum depth in the depth buffer.
Let's assume a linear, integer depth buffer, and that the minimum depth is represented by 1 (these are some major simplifications by the way).
That means the depth buffer has to be able to fit the number 200000 into a single entry. That requires more than 16 bits (16 bits can represent a maximum value of 65535).
It would fit into a 24 bit buffer, or a floating point buffer.
Bottom line: it depends on the card what you can use.
By the way, there is another, simpler way of achieving higher precision: just scale up everything (provided you don't have a problem with things being cut off at a distance).
The FOV does not have anything to do with the near and far clipping planes.
Maybe your depth buffer precision is too low.
Say you have a far clipping plane of 2000 (irr default according to the docu), and a near clipping plane of 0.01.
This means the hardware needs to be able to represent a maximum depth of 200000 * the minimum depth in the depth buffer.
Let's assume a linear, integer depth buffer, and that the minimum depth is represented by 1 (these are some major simplifications by the way).
That means the depth buffer has to be able to fit the number 200000 into a single entry. That requires more than 16 bits (16 bits can represent a maximum value of 65535).
It would fit into a 24 bit buffer, or a floating point buffer.
Bottom line: it depends on the card what you can use.
By the way, there is another, simpler way of achieving higher precision: just scale up everything (provided you don't have a problem with things being cut off at a distance).
Thanks for your reply,
I thought the near value has something to do with the FOV because setting near value to 2 also results in distorted picture on screen. Changing the near value distorts the picture, changing far value does not...
I tried scaling everything up, but I want to simulate huge distances like 384.000 km (distance between earth and moon), and by now 1 Irrlicht unit is 10 km. Because of that a spaceship is very small in irrlicht units.
I also tried 1 Irrlicht unit to represent 1 km, but then when you are far away from Irrlicht's coordinate origin, movement begins to flicker, the more the farer you are away. I don't know why, but I think it also has something to do with the values a vector can handle.
Maybe the engine simply can not handle this, but I would love to see earth, moon and spaceship in proper relations.
Has anyone made tests in this direction? What distances/scales is Irrlicht able to handle?
I thought the near value has something to do with the FOV because setting near value to 2 also results in distorted picture on screen. Changing the near value distorts the picture, changing far value does not...
I tried scaling everything up, but I want to simulate huge distances like 384.000 km (distance between earth and moon), and by now 1 Irrlicht unit is 10 km. Because of that a spaceship is very small in irrlicht units.
I also tried 1 Irrlicht unit to represent 1 km, but then when you are far away from Irrlicht's coordinate origin, movement begins to flicker, the more the farer you are away. I don't know why, but I think it also has something to do with the values a vector can handle.
Maybe the engine simply can not handle this, but I would love to see earth, moon and spaceship in proper relations.
Has anyone made tests in this direction? What distances/scales is Irrlicht able to handle?
@bal: Could you explain to me, how Mipmapping could cause that flickering of movement? I don't know about Mipmapping, I read a few article to understand, but I don't see, how it could be responsible.
It's just the spaceship flickering, the skybox is drawed just like normal. If you fly around earth, everything is smooth, but when you fly into space, the farer you get from earth, the more begins the ship to shiver, if you then stop, the ship stops shivering. When you move on, or just rotating, it shivers again with same strength.
What could be responsible for that(besides mipmapping)?
What happens, if you change the NearValue() of your camera? Is the picture then distorted? If so, is it right?
It's just the spaceship flickering, the skybox is drawed just like normal. If you fly around earth, everything is smooth, but when you fly into space, the farer you get from earth, the more begins the ship to shiver, if you then stop, the ship stops shivering. When you move on, or just rotating, it shivers again with same strength.
What could be responsible for that(besides mipmapping)?
What happens, if you change the NearValue() of your camera? Is the picture then distorted? If so, is it right?
With regard to the spaceship 'flickering' when it gets further away from the origin - maybe you mean movement gets choppier?
It sounds like you could be running into a floating point limitation.
If so, the spaceship stops completely when its speed is below a certain value.
Floating point numbers basically consist of two parts:
a rational number, e.g 0.9876, and a factor, say 10^4.
(again a simplification, it actually uses powers of two, not powers of ten).
You can see that floating point numbers have a relative precision (you can express the precision as a percentage of the value). The bigger the number, the bigger the inaccuracy.
The precision of a floating point variable depends on its size. A 'float' (32 bits IIRC) as coordinates has only a couple of digits behind the decimal point, and a 'double' has a bunch more.
I just looked at the vector3df API documentation and it seems Irr uses 32 bit floats by default. I'm afraid you'd have to change stuff in the source to use doubles. Pity, I thought Irr used templates for more stuff.
It sounds like you could be running into a floating point limitation.
If so, the spaceship stops completely when its speed is below a certain value.
Floating point numbers basically consist of two parts:
a rational number, e.g 0.9876, and a factor, say 10^4.
(again a simplification, it actually uses powers of two, not powers of ten).
You can see that floating point numbers have a relative precision (you can express the precision as a percentage of the value). The bigger the number, the bigger the inaccuracy.
The precision of a floating point variable depends on its size. A 'float' (32 bits IIRC) as coordinates has only a couple of digits behind the decimal point, and a 'double' has a bunch more.
I just looked at the vector3df API documentation and it seems Irr uses 32 bit floats by default. I'm afraid you'd have to change stuff in the source to use doubles. Pity, I thought Irr used templates for more stuff.
Yeah, that really seems to be the problem!
The spaceship ignores small changes in speed, if you are at a certain distance to earth. If I could now use double for position (is it enough to change just position?), there would be no nessecerity to use a near value lesser than 1, as you said, I could scale everything up.
But how to do? So far I have my own camera, derived from ICameraSceneNode, but Position is attribute from ISceneNode, but I have to derive from ICameraSceneNode to properly use my camera, haven't I?
Is there a way to workaround that problem, without changing the engine? Because I really want to test it out, so that I can sleep well again...
Thanks a lot for your help!
Ronin
The spaceship ignores small changes in speed, if you are at a certain distance to earth. If I could now use double for position (is it enough to change just position?), there would be no nessecerity to use a near value lesser than 1, as you said, I could scale everything up.
But how to do? So far I have my own camera, derived from ICameraSceneNode, but Position is attribute from ISceneNode, but I have to derive from ICameraSceneNode to properly use my camera, haven't I?
Is there a way to workaround that problem, without changing the engine? Because I really want to test it out, so that I can sleep well again...
Thanks a lot for your help!
Ronin
Well... If you don't mind doing the movement calculations yourself, nothing is stopping you from keeping a more precise position in a separate vector3d<double> (if that is the correct notation).
And then simply do a setposition after every update.
The display position is still as bad as it was before, but considering the resolution of the screen compared to the precision of even a float, you shouldn't see any difference.
But your ship's movement will be much smoother.
That's true whether you have a chase cam or some fixed camera.
Visually it may be better to set every object's position relative to the camera in your case, and place the camera at 0,0,0. That will place the highest absolute precision near the observer.
And then simply do a setposition after every update.
The display position is still as bad as it was before, but considering the resolution of the screen compared to the precision of even a float, you shouldn't see any difference.
But your ship's movement will be much smoother.
That's true whether you have a chase cam or some fixed camera.
Visually it may be better to set every object's position relative to the camera in your case, and place the camera at 0,0,0. That will place the highest absolute precision near the observer.
I had the same problems too.
Every object in my game (space simulator too) has a vector3d<f64> that represents the "real" position,when i set position i subtract the camera real position from object real position (in this way camera is at (0,0,0).
I have now enough precision to fly around the solar system from the Sun to Neptune
I had also the problem of of low zbuffer precision,that i resolved using a 24 bit zbuffer,but i cannot run the game in 16 bit color depth anymore.
In my game 1 irrlicht unit =1 meter,i think it's completely useless to use bigger scaling(oh my god it's english?) like 1 irrlicht unit=10km,because
if one meter in your units is in value 1/10000 than mine,the error would be 1/10000 too,but (1/10000)*10km=1m.
I know I wasn't much clear,anyway what kind of game are you developing?
I noticed too the problem with nearvalue.with values less than 1,i noticed all the stars that I draw using getScreenCoordinatesFrom3DPosition are drawn on the centre of the screen.Nice effect for hyperspace,but a big problem for everything else.
Of course i've got problem with meshes too.
Please tell me if you can solve your problem.
Happy coding!
Every object in my game (space simulator too) has a vector3d<f64> that represents the "real" position,when i set position i subtract the camera real position from object real position (in this way camera is at (0,0,0).
I have now enough precision to fly around the solar system from the Sun to Neptune
I had also the problem of of low zbuffer precision,that i resolved using a 24 bit zbuffer,but i cannot run the game in 16 bit color depth anymore.
In my game 1 irrlicht unit =1 meter,i think it's completely useless to use bigger scaling(oh my god it's english?) like 1 irrlicht unit=10km,because
if one meter in your units is in value 1/10000 than mine,the error would be 1/10000 too,but (1/10000)*10km=1m.
I know I wasn't much clear,anyway what kind of game are you developing?
I noticed too the problem with nearvalue.with values less than 1,i noticed all the stars that I draw using getScreenCoordinatesFrom3DPosition are drawn on the centre of the screen.Nice effect for hyperspace,but a big problem for everything else.
Of course i've got problem with meshes too.
Please tell me if you can solve your problem.
Happy coding!
-
- Posts: 602
- Joined: Sat Aug 23, 2003 2:03 am
- Location: Pottstown, PA
- Contact:
I develop, together with MasterD, a little Space Shooter thingy...
It's our first project, not only with Irrlicht, but in general. So don't expect to much. We want to have Earth, Moon and the player spaceship in proper relations, and the ability to fly around. Fly around is no problem so far, but the relations are. We'll see, what that project will become in future. When we have something to show, we will announce this project in the forum and you can make your own opinion on the project.
We changed the position vector of all game objects to double and rewrite it back to irrlicht in float every frame. Unfortunately that did not solve the problem of choppy movement in far distances, so we decided to make that "camera always in (0,0,0)" approach. Thanks to Phenix description above we managed it, but still it is not perfect. Because now while moving, the whole screen shivers (or the camera is "shaking"). I think it is because player input moves the spaceship, and the camera is just put behind the ship, following its movement.
So, the spaceship is moved according to the camera (because camera is always in (0,0,0)), but virtual position of camera is set according to spaceship. I don't know if this can work.
I tested it with a static camera, that always looks to ship, but doesn't move and it worked smooth and nicely. Moving the camera instead of spaceship should be a solution, but I don't want it.
I hope I made some kind of sense, else ask. What I need is that the camera is always in the same position behind the ship, without shaking.
I really hope there is a solution or a bug in our code, because I really like this new approach.
@Phenix: How do you do your movement? Do you move the camera or the Spaceship?
It's our first project, not only with Irrlicht, but in general. So don't expect to much. We want to have Earth, Moon and the player spaceship in proper relations, and the ability to fly around. Fly around is no problem so far, but the relations are. We'll see, what that project will become in future. When we have something to show, we will announce this project in the forum and you can make your own opinion on the project.
We changed the position vector of all game objects to double and rewrite it back to irrlicht in float every frame. Unfortunately that did not solve the problem of choppy movement in far distances, so we decided to make that "camera always in (0,0,0)" approach. Thanks to Phenix description above we managed it, but still it is not perfect. Because now while moving, the whole screen shivers (or the camera is "shaking"). I think it is because player input moves the spaceship, and the camera is just put behind the ship, following its movement.
So, the spaceship is moved according to the camera (because camera is always in (0,0,0)), but virtual position of camera is set according to spaceship. I don't know if this can work.
I tested it with a static camera, that always looks to ship, but doesn't move and it worked smooth and nicely. Moving the camera instead of spaceship should be a solution, but I don't want it.
I hope I made some kind of sense, else ask. What I need is that the camera is always in the same position behind the ship, without shaking.
I really hope there is a solution or a bug in our code, because I really like this new approach.
@Phenix: How do you do your movement? Do you move the camera or the Spaceship?
I move the ship and the other objects normally using vector3d<f64>,and when I set the position of the nodes I set it to (objectRealPosition-cameraRealPosition).
I set cameraRealPosition=shipRealPosition so that the camera node is in (0,0,0) like ship node.
I think your problem is that you set the ship node to shipRealPosition-cameraRealPosition) immedially after updating the shipRealPosition,but before updating cameraRealPosition setting it equal to shipRealPosition.
If your camera is always at (0,0,0) and your ship's objectnode too,you'll have no problems.
Anyway I suggest you to update first the objectRealPosition vector of every objects,including realPosition of the camera that you'll set equal to realPosition of ship,then set position of every object node in irrlicht.
If you don't do that you might set some nodes using old camera pos and some using new pos.
I hope you'll resolve your problem,my english really doesn't help me to explain
I'm not an advanced c++ programmer too,I've learned it with Irrlicht.
By the way,I'm trying to do something similar to Frontier First Encounters.
I've got A LOT to do too.
Good luck for your project!
I set cameraRealPosition=shipRealPosition so that the camera node is in (0,0,0) like ship node.
I think your problem is that you set the ship node to shipRealPosition-cameraRealPosition) immedially after updating the shipRealPosition,but before updating cameraRealPosition setting it equal to shipRealPosition.
If your camera is always at (0,0,0) and your ship's objectnode too,you'll have no problems.
Anyway I suggest you to update first the objectRealPosition vector of every objects,including realPosition of the camera that you'll set equal to realPosition of ship,then set position of every object node in irrlicht.
If you don't do that you might set some nodes using old camera pos and some using new pos.
I hope you'll resolve your problem,my english really doesn't help me to explain
I'm not an advanced c++ programmer too,I've learned it with Irrlicht.
By the way,I'm trying to do something similar to Frontier First Encounters.
I've got A LOT to do too.
Good luck for your project!
Thanks, and thanks very much for helping me. You were right, now everything is nearly smooth, really a LOT smoother than before.
But I'm afraid scaling everything up is a bit more complicated, though I might be wrong. I can not scale everything to 1m = 1 irrlicht unit, because I have to set the far value of camera to 384.000.000. That dont work, nothing is drawn. Now 1 km is 1 irrlicht unit, but I can see the moon...
How far can you see, do you use bigger values for far plane and light radius?
Still I have a problem with the z-buffer though, I saw several threads on this forum regarding this, but no solution. Is it right that calling createDevice() with z-buffer = true switches zbuffer to 24bit? If yes, it dont solve my problem. Far value is now 1.000.000, but when setting it to 10.000.000 the z-buffer really beat up some textures. I would be interested to see how a w-buffer would work, but i have no idea about that whatsoever...
Do you have a website about your project?
But I'm afraid scaling everything up is a bit more complicated, though I might be wrong. I can not scale everything to 1m = 1 irrlicht unit, because I have to set the far value of camera to 384.000.000. That dont work, nothing is drawn. Now 1 km is 1 irrlicht unit, but I can see the moon...
How far can you see, do you use bigger values for far plane and light radius?
Still I have a problem with the z-buffer though, I saw several threads on this forum regarding this, but no solution. Is it right that calling createDevice() with z-buffer = true switches zbuffer to 24bit? If yes, it dont solve my problem. Far value is now 1.000.000, but when setting it to 10.000.000 the z-buffer really beat up some textures. I would be interested to see how a w-buffer would work, but i have no idea about that whatsoever...
Do you have a website about your project?