Archived

This topic is now archived and is closed to further replies.

DanielH

Terrain shadows

Recommended Posts

Just do some raytracing, after you build your height map, and store the result (shaded or not shaded) on each vertex. Then, when you render it, use a different color (maybe 0.5,0.5,0.5) to blend with the current texture.

Share this post


Link to post
Share on other sites
For simplicity you could check the angle the terrain has at a given point and choose a light value. That won't do shadows but it looks quite good.
Btw the new Unreal Engine does Raytracing for terrain shadowing so it can't be that bad.

[edited by - noVum on November 8, 2002 5:50:16 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by DanielH
noVum,
that sounds good. can u show some code how i get the angle of a point?


for each vertex in your terrain map, go through all your terrain's triangles and find a surface normal for all the triangles that include that vertex. average the normals together and you get a normal for that vertex. if you use glNormal3f() as you draw out your terrain and then enable and setup glLighting, you'll end up with properly shaded terrain. that way, it'll be dynamically shaded as well, so you can light up the terrain with dynamic lights.

if you want your terrain just statically shaded, do similar calculations to get vertex normals for all the vertices of your map. then you'll want to make up some sort of vector at which the "sunlight" hits your world. compare the vertex normals to the sunlight vector and set a color value for each vertex based on the angle between the two. 180 - 90degrees = black -> pure white. 90 - 0 = black (i.e. normal is pointing away from the light). save that color array in some meaningful way and then do a blend with the shading color and the texture color to get the final shaded appearance of your terrain map.

look up "smallest angle between two vectors" on google to get the math for calculating the angle between the normal and sunlight vector.

look up "3D math tutorial" to learn what vectors are, how to use them, and how to find normal vectors from 3 points.

look up "openGL redbook" and read the chapter on lighting in openGL to see how it all works.

post more questions and i'll try to clarify what you need to learn. (a little busy today at work so i don't have a ton of time to make this post verbose)

-me

[edited by - Palidine on November 8, 2002 6:40:49 PM]

[edited by - Palidine on November 8, 2002 6:41:56 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Raduprv
Just do some raytracing, after you build your height map, and store the result (shaded or not shaded) on each vertex. Then, when you render it, use a different color (maybe 0.5,0.5,0.5) to blend with the current texture.


Do you have some source code for this?

I am trying to get this working but for some reason my ray-poly colision detection isn''t working.
I''m not expiranced with 3D stuff, and I''m just using the collision detection tutorials from www.gametutorials.com. I don''t know if I using the collision detections functions wrong, or if they arn''t working.



Jason Mickela
ICQ : 873518
Excuse my speling.

Vallejo Punk
The V-Town Have-Nots
Eskapo

"I don''t have to take this, I''m going to where I''m appreciated, my mom''s house"

Share this post


Link to post
Share on other sites
I know how to get the normal now, but i cant find any information about calculating the angle between the vector and the sunlight

Share this post


Link to post
Share on other sites
quote:
Original post by DanielH
I know how to get the normal now, but i cant find any information about calculating the angle between the vector and the sunlight

Dotproduct: intensity of point = Normal DOT Sunlight direction. DOT is the dotproduct, ie: intensity = N.x * S.x + N.y * S.y + N.z * S.z; Both normal and sunlight direction need to be normalized for it to work. intensity will range from -1 to 1. Clamp everything less than 0 to 0: intensity = max(0, intensity).

Share this post


Link to post
Share on other sites
For some reason just every other triangle get shaded and the other is black!

What am i doing wrong?


procedure TOctree.CalculateShadows(pNode: TOctree);
type
TVectorArray = array[0..0] of TVectorEX;
var
i: Cardinal;
pVertices: ^TVectorArray;
vNormal: TVector3;
intensity : GLfloat;
Color : TRGB;
begin
if pNode = nil then Exit;

if pNode.SubDivided then
begin
CalculateShadows(pNode.FOctreeNodes[TOP_LEFT_FRONT]);
CalculateShadows(pNode.FOctreeNodes[TOP_LEFT_BACK]);
CalculateShadows(pNode.FOctreeNodes[TOP_RIGHT_BACK]);
CalculateShadows(pNode.FOctreeNodes[TOP_RIGHT_FRONT]);
CalculateShadows(pNode.FOctreeNodes[BOTTOM_LEFT_FRONT]);
CalculateShadows(pNode.FOctreeNodes[BOTTOM_LEFT_BACK]);
CalculateShadows(pNode.FOctreeNodes[BOTTOM_RIGHT_BACK]);
CalculateShadows(pNode.FOctreeNodes[BOTTOM_RIGHT_FRONT]);
end
else
begin

// Make sure we have valid vertices assigned to this node
if pNode.FVertices = nil then Exit;

// Store the vertices in a local pointer to keep code more clean
pVertices := @pNode.FVertices[0];


// Go through all of the vertices (the number of triangles * 3)
i := 0;
while i < pNode.TriangleCount * 3 do
begin

vNormal := Normal(pVertices.PosVector, pVertices[i+1].PosVector, pVertices[i+2].PosVector);
intensity := vNormal.x * g_Sun.x + vNormal.y * g_Sun.y + vNormal.z * g_Sun.z;
if intensity < 0.1 then intensity := 0.1;
Color.r := intensity; Color.g := intensity; Color.b := intensity;
pVertices[i].Color := Color;
pVertices[i + 1].Color := Color;
pVertices[i + 2].Color := Color;

Inc(i, 3);
end;

end;
end;

Share this post


Link to post
Share on other sites
quote:
Original post by griffenjam
[quote]Original post by Raduprv
Just do some raytracing, after you build your height map, and store the result (shaded or not shaded) on each vertex. Then, when you render it, use a different color (maybe 0.5,0.5,0.5) to blend with the current texture.


Do you have some source code for this?

I am trying to get this working but for some reason my ray-poly colision detection isn''t working.
I''m not expiranced with 3D stuff, and I''m just using the collision detection tutorials from www.gametutorials.com. I don''t know if I using the collision detections functions wrong, or if they arn''t working.


I don''t have any C source code, I did that looong time ago, in ASM, and it looked good. But it was a vertex engine, so I don''t know exactly how it looks with vertex shades (but I guess it looks better than nothing)

Share this post


Link to post
Share on other sites
Maybe you should play with the light source possition, until you find out where your normals are, and then adjust them properly.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
If you are calculating your normals by taking three points from your poly and doing the crossproduct the order of the points matters. Depending on which order you choose your points you can get the normal pointing "up" or "down". If you arent consistent then you get some pointing one way and some the other and you end up with some triangles properly shaded and others black because OpenGL treats them like they are facing the wrong way.

If you have questions about the math involved you should post your questions to the Math forum here, you might get a more technical response.

To do shadows on your terrain have you looked into shadow maps? Try www.vterrain.org they have links to some good papers which deal with this.

Share this post


Link to post
Share on other sites