From radial blur to lenses!

category: general [glöplog]
Since we're all happy talking about "effects" here, it can be a nice time for me to ask:
HTF should I do a fisheye lens?
I know a fisheye lens is just a normal lens with a big angle, and the effect comes from the distortion (simulation of a real lens).

What's the best aproach to code it on modern hardware?

The main idea is turning | into )

How does ryg do it in fr-054: polar, and how does smash do it in media error?

added on the 2008-01-21 19:26:26 by xernobyl xernobyl
and made by the maker of awesome gifts to mankind such as "false" and "aardappel"!
added on the 2008-01-21 20:31:44 by skrebbel skrebbel
this one was actually done by chaos, not me :). but it's pretty straightforward. the scene is rendered into a cubemap (centered around the viewer). then draw a quad an transform the 2d position into a 3d direction vector (as the name implies, polar just uses spherical coordinates). if you want, you can do the 2d->3d mapping with a texture, then you can morph between different projections by blending between two textures and so on :)
added on the 2008-01-21 20:39:43 by ryg ryg
So I do have to render 4 views (front, up, down, left, and right)...
added on the 2008-01-21 20:45:45 by xernobyl xernobyl
that's probably the easiest way, yes.
added on the 2008-01-21 20:47:51 by ryg ryg
added on the 2008-01-21 22:11:57 by noouch noouch
realtime raytracers are not really my thing
added on the 2008-01-21 22:13:26 by xernobyl xernobyl
No actually that's 5 :). Anyway, they alll use the same camera-space geometry rotated by 90-degree angles, same lighting and shadows, etc., so that's a useful fact right there. !!!!

IIRC there's a Quake 1 port called "Fisheye Quake" that does it in software, and the method is documented in the accompanying readme files. Also the source code is available. But it's the same method anyway.

I guess you could render as little as three (triangular) views and still be able to get a fisheye effect.
added on the 2008-01-21 22:20:36 by doomdoom doomdoom
You know, that's the exact same Quake port you linked to. How about that!
added on the 2008-01-21 22:21:37 by doomdoom doomdoom
I've posted a link to that project above. And everyone knows I can't count. About rendering just 3 I think that it would probably cause some very noticable stiching in the middle of the screen.
added on the 2008-01-21 22:24:10 by xernobyl xernobyl
Well, maybe. Or maybe not. It's not like DirectX has huge precision issues, and you could fine-tune the mapping around the edges to eliminate the stitching. I think. Probably.
added on the 2008-01-21 22:28:13 by doomdoom doomdoom
A simple optimization for the 5 views would be just drawing half of the frames (except the front one). That would work for FOVs smaller than 180, I think.
added on the 2008-01-21 22:34:34 by xernobyl xernobyl
I think. Probably.

Well, I'm convinced :D
xernobyl: Now that would give you stitching :) I think. Probably.
added on the 2008-01-21 22:41:18 by doomdoom doomdoom
1. render scene as cube map (you don't need the 'back' side of the cube I guess)
2. make a lense shaped mesh (just 1 side is necessary)
3. invert the normals on the mesh
4. env map the lens shape with your cube map, make sure it's drawing back faces, and render it

Instant lens distortion. The more curved the lens is the more it'll tend towards fish eye. You need to invert the normals on the lens mesh to change it from reflecting (and showing what's behind the camera) to refracting like a proper lens.
added on the 2008-01-21 22:42:22 by psonice psonice
1. get a large transparent mixing bowl
3. Profit
added on the 2008-01-21 23:21:07 by doomdoom doomdoom
3. Profit
added on the 2008-01-21 23:47:00 by nitro2k01 nitro2k01
The really oldschool way of doing fisheye of course is to use a real fish. It needs to be pretty big, and you cut the eyes out and wear them as contact lenses to get the effect. Just remember to take them out before you go to work, or you'll freak people out (and likely crash your car trying to go round corners).
added on the 2008-01-21 23:48:12 by psonice psonice
MOAR ideas :)
I like psonice idea, but I don't think I can do that with OpenGL or Direct3D.
added on the 2008-01-23 12:50:35 by xernobyl xernobyl
in media error we rendered to cubemap, surprise surprise.. then used a shader which looks it up (it has an atan2 in it). actually in media error in the end i used a smaller-than-screen lookup texture, also rendered on gpu which i only regenerated when the angle changed because it was faster, but your mileage (and graphics hardware) will vary - on newer hw it could be faster just to do the calculations in the shader and not burn bandwith.

the painful thing is rendering the scene 5 times - would really have liked to have done without that. oh, and billboards are an interesting case to handle. :)
if your angle isnt too big you might be able to get away with the much cheaper version - rendering to a bigger-than-the-screen rendertarget and bending your lookup vectors into 2d - but it probably looks like shit compared to the cubemap version and wont give you the big angles, which are the best thing about the effect anyway.
added on the 2008-01-23 13:20:41 by smash smash
i love psonices version, it allows for horribly cheesy effects (plus it can be done with even the crappiest oldest codebase with no extra effort)
added on the 2008-01-23 14:26:10 by skrebbel skrebbel
What about using just 3 images left, right, and bottom or top, and rotating the cubemap a bit?

\/ instead of |_|

like this:
BB Image

I haven't done the math to see what's the maximum angle using this...
added on the 2008-01-23 16:40:48 by xernobyl xernobyl
having the image fucked up in the corners can be a good thing if you really want to simulate a camera. Just add a round frame around (most cheap lenses/cameras can't handle the truth).

BB Image
added on the 2008-01-23 16:45:45 by xernobyl xernobyl