raylighting terrain article

Started by
12 comments, last by Dragon_Strike 19 years, 3 months ago
Ok, perhaps more could be done to elaborate what you are setting up shop with. Lightmaps are implied, is the sun's origin always going to be along the x-axis (y = 0) or along the y-axis (x = 0)?

For my set up I set the ray's origin at a point exactly 64.0 points along the ray that the suns 'rays' travel along. The same ray is used for all points, since a sun's 'rays' are effectively parallel.

So, in my implementation I first check to see if the point is in shadow, if it is, it is shadow colored. If not, it is then tested against the ray for brightness (a dotproduct test.) and set.

Since my engine needs to go through a 24 hour day, I kludged it in to test each vertex each frame (I actually 'cached' results), which is a no-no for performance. I know that, but I was eager to see the results and pushed it in anyway.

From my tests it's easy to see that per-frame testing is not acceptable (as anyone could guess), and that per-vertex lighting doesn't make the terrain look it's best. I'll implement lightmapped terrain next :)
Advertisement
Good article!

Some contribution:
I can explain how i do shadows in Voxel World: i have light heightfield. When heightfield landscape casts shadows, at every point on landscape you have no light till some height, and light above that height, so you can use heightfield to store shading information.

For every vertex, i store height of light at that vertex. When rendering , i interpolate (land_leight-light_height) , and when it is negative, surface is shaded, when positive, lit. Value can be used for coloring of shadows. So, I get correct sharp shadows with it, as if I would use stensil buffer. With two light heights, it is possible to make nearly correct smooth shadows. I think it can be done on GPU using pixel shaders, or stencil buffer.(rendering shadow heightfield like stensil shadows)

How light heights are computed:

Start at one side of map, and horisontally trace to other side, _in direction of sunlight_ (that is, if sun is at north, i trace from north to south). At each point, check if current_light_height is below ground_height, if it is below, {current_light_height=ground_height;} . Then, current_light_height-=length_of_tracing_step * tangent_of_angle_between_sun_and_horisontal_plane; (aka sun "elevation" angle.). Then store result into shadow heightfield at next step's position. (You can just mark point as lit if light height is below ground, and unlit if above.) There is obviously some problems with accurate sharp self-shadowing, but them is eliminated by "delaying" shadows by 1 step.

It is quite efficient method, i process each vertex in heightfield only once.
Some ascii art:
`-._ light direction    `->      _______       /*******\*-._      /**        | s *-.__/*           \_______*-.______________**                        *************there, "*-._" is light heights, and line is landscape, and "s" is inside shadow, and it is traced from left to right.



As about rendering 24 hours day, you can precalculate it. old thread about that.

[Edited by - Dmytry on January 13, 2005 7:35:19 AM]
Quote:Original post by Wudan
Ok, perhaps more could be done to elaborate what you are setting up shop with. Lightmaps are implied, is the sun's origin always going to be along the x-axis (y = 0) or along the y-axis (x = 0)?


well in the articles code its always going to be along the x (x<..) axis... but however u can change that by starting at mapX and move the origin backawards and calculate the ray from 0 towards mapX. You can also do the same thing with the z axis. Basicly u can rotate the rays origin with a 90 degrees angle.

Quote:For my set up I set the ray's origin at a point exactly 64.0 points along the ray that the suns 'rays' travel along. The same ray is used for all points, since a sun's 'rays' are effectively parallel.


You have to put the rays origin at every point in the map to get a correct result. Since all the rays hit the x-axis with the sa,e angle they will all be paralel with eachother.

Ive tried to use other values than 45 degrees since the (x2-x1) * tan(angle) eqations should work with other angles, but it doesnt and i have no idea why... if somebody figured out how to do that u could simulate a 24 hour day...

Quote:So, in my implementation I first check to see if the point is in shadow, if it is, it is shadow colored. If not, it is then tested against the ray for brightness (a dotproduct test.) and set.

Since my engine needs to go through a 24 hour day, I kludged it in to test each vertex each frame (I actually 'cached' results), which is a no-no for performance. I know that, but I was eager to see the results and pushed it in anyway.


You should store all the brightness values in a lightmap from which u get the brightness at each point.
Quote:
From my tests it's easy to see that per-frame testing is not acceptable (as anyone could guess), and that per-vertex lighting doesn't make the terrain look it's best. I'll implement lightmapped terrain next :)

The only way i know is through lightmapping so i cant rly tell which works best.
i jsut figured out ow to use different angles than 45 degrees... simply replace the line...

rayHeight = ( x2-x1 ); with

rayHeight = ( x2-x1 ) * tan(angle*PI/180);

and thats it u can have a 24 hour day..

This topic is closed to new replies.

Advertisement