Forum archive
6DOF raycasting
- Hi Ken,
I've been busy making a 6dof landscape renderer, but without the desired result... I did a 4dof version first, in which I raycast among my heightmap to draw vertical columns. To make it 6dof I tried to raytrace (first hit only) each pixel, this kinda worked, but not at the speed I was aiming for. How did you achieve this with groudraw and steep? I read you use some form of raycasting for this too. Maybe you'd bother to give some pseudocode? (I tried to reverse engineer from the sourcecode, but it's a bit obfuscated ;) Unfortunatly there dont seem to be any good tutorials on 6dof raycasting.
Also you mention you use multiple color values per column in steep, for a better resolution on steep slopes. How should I visualize this? Does it differ per viewing angle?
Martijn Re: 6DOF raycasting
A 4dof engine does raycasting along vertical planes, which project to vertical lines on the screen. The 6dof engine still uses vertical planes, but the trick is they map to diagonal lines on the screen. Drawing these diagonal lines without gaps/pixel artifacts can be tricky. It requires a 2-pass algorithm. The first pass does the raycasting; color data is written to a temporary buffer instead of the screen. The second pass then maps this color data from the temporary buffer to the screen. For a hint on setting up the raycasting, check out GROURAY2.KC (included with EVALDRAW.ZIP).
STEEP uses the standard 2D arrays for color (groucol1) and height (grouhei1). The color only represents the highest voxel of the column - the one at the specified height. To get the colors below it, each column has a 4-byte pointer (grouptr1) to a list of additional colors. I store these lists sequentially on a large array (groucol). To avoid writing a fancy memory allocation system for STEEP, I generate the map once at the beginning, and hope that the size of groucol is never exceeded. As written, modifications to the map (PGUP/PGDN) can result in read page faults as I do not update the color lists to account for the changes.- Thanks for your reply... though Im still a bit confused;
With my 4dof raycasting loop, I render vertical columns perpendicular to the heightmap (I cast rays in a 2d plane, which overlaps the heightmap)
Now when this raycasting plane can tilt (for example when you look down on the heightmap from above) I can only raycast a slice of the heightmap in which the raycasting plane and the heightmap intersect? - I'm not 100% sure what you mean, but I'm going to respond with 'yeah'. Before you try full 6dof, it might be easier to start with an OVERGROU clone. In OVERGROU, all rays start at the center of the screen and travel outward. Each ray is shot out at a different angle. This, and the 4dof case are really just special cases of the 6dof algorithm.
- Ah I see, so it boils down to this? (sorry couldn't get the wonderfull ascii art right ;)):
+----------------+
| |
| ----------------|
|\ ^ /|
| \ | / |
| \ | / |
| \ | / |
| \ | / | 4DOF - camera always points at horizon (parallel to landplane)
| \ | / | fixed fov (always cast rays forward from camera pos)
| \ | / | only need to draw vertical lines, as the camera angle is always parallel to the landplane
| \ | / |
| C |
+---------------+
example 4dof view: camera points at horizon
+----------------+
| |
| ----------- |
| | ^ | |
| | | | | 6DOF - camera can point in any direction
| | <-C-> | | angle of camera determines the fov on the landplane to trace
| | | | | may need to cast rays in every direction on the plane (fx top-down view, the fov is a circle on the landplane)
| | v | | draw (diagonal) lines at angles dependand on camera-landplane angle
| ----------- |
| |
+-----------------+
example 6dof view: camera look down on plane from above (angle = 90 degrees)
pseudo code:
determine the angle between the camera and the plane
determine the fov in which we need to cast rays
(in my 6dof example, the fov for the top-down view would be the square around the camera position)
for each pixel in xres
determine at what angle we should cast the ray from the camera pos at the plane
for 0 to clipping-length
if pixel is higher than previous pixel
store this height
determine the angle the ray hits the pixel (based on the angle between the camera and the plane)
draw line in a x,y,z? space based on angle and project to 2d view
In steep I noticed you only draw 2d lines, how do you determine how these should be draw?
Also the performance using this method would be slower for views that are more top-down, as each pixel from the plane will result in a line being drawn?Edited by bitshit at - Your example 4dof view looks more like a 6dof view where the viewer is looking down slightly. A true 4dof view would have the 'C' infinitely far down (or up), causing the raycast lines to be parallel.
In steep I noticed you only draw 2d lines,...
If I could read your mind, I would have posted a meaningful answer to this. If you don't understand a piece of code, sometimes a good way to learn about it is to hack things in it, recompile, and see what changed. When releasing GROUDRAW.ZIP, I put a lot of effort into making sure the code would compile with Open Watcom. I think you will learn things faster this way than by posting ambiguous questions on the forum, and waiting a day for an equally ambiguous answer. Your example 4dof view looks more like a 6dof view where the viewer is looking down slightly. A true 4dof view would have the 'C' infinitely far down (or up), causing the raycast lines to be parallel.
Yeah I drawn it like that because in my 4dof raycaster I clip the rays, I get your point about ambiguous questions ;)If I could read your mind, I would have posted a meaningful answer to this. If you don't understand a piece of code, sometimes a good way to learn about it is to hack things in it, recompile, and see what changed. When releasing GROUDRAW.ZIP, I put a lot of effort into making sure the code would compile with Open Watcom. I think you will learn things faster this way than by posting ambiguous questions on the forum, and waiting a day for an equally ambiguous answer.
I'll download open watcom and give it a shot! But before I do I have one more question though (to check whether I'm thinking in the right direction); How many rays do you cast in your 6dof engine, always a fixed amount or variable depending on the camera vector / plane intersection?How many rays do you cast in your 6dof engine, always a fixed amount or variable depending on the camera vector / plane intersection?
The number of rays depends on angle and detail level. I keep the maximum ray separation a constant. In full detail, my algorithm casts about 640 when looking at the horizon, and it goes up to around 2000 when looking straight up/down.