Advertisement Jump to content
Sign in to follow this  

Creating shadowmap for terrain using heightmap

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there! I'm trying to do some fake lightning by "decolouring" the pixels affected by the shadow... i got the terrain stored in a RAW file, and the color/shadow map as a TGA... How can I shade pixel B (colormap) with pixel A (heightmap value) ? if both were aligned two-dimensionaly, it would simply be: ColorPoint[x][y] -= HeightMap[x][y]; but that's not the case... The TGA is saved as three bytes chunks/pixel... and in a one dimensional array... I've tried to do like this:
#define MAP_SIZE 1024   //same as tga width!!
int incer=0;
int ShadeValue=0;
int TempHeight=-1000;   

 for (int y=0; y < MAP_SIZE; y)
   for (int x=0; x < MAP_SIZE; x++)
      TempHeight = GetHeight(g_HeightMap, x, y );

      if (TempHeight < ShadeValue)
               texture->imageData[incer]   = 0;
               texture->imageData[incer+1]= 0;
               texture->imageData[incer+2] = 0;



but that only displays a shadow small as about a fifth of the map, and it may also be repeated across the terrain... :( anyone who can help me? :D

Share this post

Link to post
Share on other sites
I've just implemented my lightmap (what you call shadowmap) algorithm.

I dont understand the kind of "fake" effect your trying to pull off here.
Why do you increment the color value from the height value?

each vertex in your heightmap has its own color, which is consisted of R,G,B element. Those can be ranged from 0 to 255, or 0.0 - 1.0 in OpenGL...

I'll tell you what am I doing, so maybe you will have an idea of your own.

each vertex should have an RGB values, so I have an array of colors, one for each vertex. I call it the vertex color array.
I than make 2 other identical arrays:
One is for the lightmap (shadowmap) , the other is for the colormap.
The result of the two arrays multiplied together is actually the "vertex color array" I just mentioned.
1) Making the colormap:
I want low places to be blue (water), mid places to be brown (for ground) and high places to look white (snow).
First, I iterate thru the heightmap raw data ("unsigned char" values from 0..255 that i've already loaded from a file), and I arbitrarily set color values, depending on the height of the current vertex:
height = raw_data[x][y];
if ( 0<=height<=50) colormap[x][y] = BLUE
else if (50<height<=100) colormap[x][y] = BROWN
please notive the each color (BLUE, BROWN, etc) is actually a vector with 3 values (for R,G and B).

2) Making the lightmap:
For this part you should have a vertex normal array. one normal for each vertex.
I iterate thru my vertex normal array, and i check the angle of the normal vector with the sun (light source) vector.
Since in trigonometry, the formula for angle between two vectors give you the cossine of the angle, I roughly use that value to detirmine the brightness of the current vertex. the lightmap array is actually an array of "float" type representing brightness:

lightsource_vec = lightsource_pos - vertex_normal_array[x][y]
angle = vertex_normal_array[x][y].Angle(lightsource_vec)
lightmap[x][y] = angle;

3) Putting the two arrays together:
for each (x,y) :
vertex_colormap[x][y] = lightmap[x][y] * colormap[x][y];

Use the vertex_colormap array to set each vertex's color when you draw your scene.

Hope I helped a bit.

Share this post

Link to post
Share on other sites
yes, that's pretty much what I'm doing... :)

get height = shade value...
for every x, substract 1 from shadevalue (this is optional, but I want shadows to become more transparent at distance...)

I \
I \ I
I___\I_\ _ = shadowed terrain

except that I dont have the first step (mud / snow thing) in my algo...
the shadows are calculated correctly, but I cant combine the shadow map onto the texture(color) map because the arrays of data are not the same....

I dont know how to transform a two-dimensional array into a one-dimensional array... :(

Share this post

Link to post
Share on other sites
I think I understand your question now more clearly.
What you really need to know, is how to convers index from a two dimentional array to index of one dimention array, and vice versa... right?

Assuming you raw data array is two dimentional, it should look like this:
"int g_HeightMap[MAP_SIZE][MAP_SIZE]"

and assuming your texture array is:

"int imageData[MAP_SIZE*MAP_SIZE*3]"

Well, lets begin with the first.
1) CONVERTING FROM g_HeightMap[X][Y] TO imageData

for any given x,y { 0<x and y<MAP_SIZE } -->
int 1D_index = (y*MAP_SIZE+x);

2) CONVERTION FROM imageData[1D_index] to g_HeightMap[x][y]

y = (int)((float)1D_index/(float)MAP_SIZE);
x = 1D_index-y*MAP_SIZE;

I hope that gives you an answer.
you cannot implement this method as-is in your case, because you got all the TGA data structure complication.

I dont know why you do : "incer+=bytesPerPixel"...
incer is an index.
if imageData is defined as an array of bytes (each index is a byte), than is should look like that:
char imageData [VERTEX_COUNT*3];
so you should only do:
incer = 0;
for (y)
for (x)
height = getheight(heightmap,x,y)
if (height <...)
imageData [i_vert*3+0] = ... // some "char" type value
imageData [i_vert*3+1] = ... // some "char" type value
imageData [i_vert*3+2] = ... // some "char" type value
else {...something else...}
incer+=1; --> and not "incer+=bytesPerPixel"

I hope all the information I gave you will help a bit , or even a byte :-)

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!