# raylighting terrain article

This topic is 4785 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Ive been assigned to make a programming work at school and give it in as an article... i have been working on my own way to creat shadowmaps for terrain and have come up with a at in atleast my opinion good method ... i thought id ask you guys for suggestions on improvements on the article and/or the code... here is the link.. http://www.falconclan.org/Ray%20Lighting%20Article.doc any help will be apriciated...

##### Share on other sites
where did u get that wierd adress from.. lol

##### Share on other sites
Your article looks really good, and it's easy to understand (this being said without trying to implement it ... yet.) It's also just the kind of explaination I've been looking for. I'll drop it on my terrain engine tonight (it's really simple, doesn't look nearly as good as the one in your article) and see how it fairs.

##### Share on other sites
Hi Dragon,

your article looks good and the results look good, too!
I must stress that I am not a ray tracer nor did I write a very intersting myself, but I guess one other way to shade the terrain would be:

p := the surface point you want to shade
n := the normal of the surface at point p
r := ray form p to the light source
phi := the angle between r and p (calculated by phi = acos(dot(n, r)/|n|*|r|))

Now you calculate for every point you are interested in
the intensity the light is hitting the surface at point p
I(p) = cos(phi) = dot(n,r)/|n|*|r|

you get values -1 <= I(p) <= 1
I(p) = 1 if the normal is pointing directly towards the light source
I(p) = 0 if the normal is orthogonal to the ray pointing to the lighsource (no shadow, but no extra light energy)
I(p) = -1 if the normal points in the opposite direction (full shadow)

This results woun't result in smooth shadowing (because the normal is for every point in a plane the same), but you can go on like this:
scatter in random directions at point p, so light is reflected to other surface points, or maybe easier (but I don't know how it will look like)
use multiple light sources. The light sources should be near to eachother. for every surface point p you calculate the intensity for each light source and divide it by the number of sources to get the final intensity. Maybe that gives you smoother shadow borders.

This only one way to do it. And it will look approximately the same than your way. But I hope you find it interesting (because you get the possibility of scattering the light and such things :)

Bye,
Constantin

##### Share on other sites
K, I didn't understand some of the things in your paper, or didn't have easy access to some of the things I'd need data for, but I pushed the concept in and came up with the following nifty time lapse shots of my terrain engine doing some very basic shadow stuff.

Shot 1
Shot 2
Shot 3
Shot 4
Shot 5
Shot 6
Shot 7

##### Share on other sites
Hi Wudan,

is it possible that you calculated only the shading for the vertices and let OpenGL interpolate between them?
It looks a little bit like that because I can see the mesh geometry in the shadow. As far as I understood the article, he generated a lightmap which is a texture. This texture is used to texture the terrain mesh. If you do so you get a much better shadow resolution.

-- Constantin

##### Share on other sites
In my shots above I calculated the color per vertex, as I don't use lightmaps in my engine. It was a pretty quick implementation and it does not run anywhere near as smooth as it should.

##### Share on other sites
ive updated the article a bit.. the only differance is that ive added "shadowDepth" which makes the calculations the same at every height which wasnt the case before...

http://www.falconclan.org/RayLightingArticle1.doc

conman ur method seems good 2... ill try it...

##### Share on other sites
wudan what is that u dont understand?

##### Share on other sites
To be honest and fair, I'm a business student and haven't taken any engineering courses, computer science courses, or technical writing classes.

However, I don't feel that the initial part of the tutorial or the description of the tecnique are adequate.

I'll have some more time to post my particular questions later on tonight. I hope that you will find it beneficial.

##### Share on other sites
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 :)

##### Share on other sites
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.

[Edited by - Dmytry on January 13, 2005 7:35:19 AM]
Quote:
 Original post by WudanOk, 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.

##### Share on other sites
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..