Allegro.cc - Online Community

Allegro.cc Forums » Game Design & Concepts » [Art] Water at Night

Credits go to BAF, HoHo, miran, and Vasco Freitas for helping out!
This thread is locked; no one can reply to it. rss feed Print
 1   2 
[Art] Water at Night
Richard Phipps
Member #1,632
November 2001
avatar

The problem is the land looks flat because of the lack of shading (or pillow shading to use an 'art' term). If you added a simple lighting effect based on the bump map effect it should look a lot better.

Onewing
Member #6,152
August 2005
avatar

Quote:

If this project turns out well, my future plans for a sequel would involve a spherical planet and using OpenLayer.

Quote:

Are you using OpenGL, by the way? What about using proper lighting and shadowing? That would look great.

Nope, I'm just using allegro, no add-on libraries. Due to time restrictions, I'm not going to tag on any library that I haven't worked with before. I am planning to expand my knowledge this summer.

I know (more like...'knew') the shading would be somewhat an issue. However, I really don't find it essential to the game itself, even though I'm trying to be realistic as possible. With my limited knowledge in the field, the limit as I approach a totally realistic simulation is infinity (amount of time). Thus, I have to make sacrifices to make sure the game continues progress. If all turns out well, I can revamp it for my next sequel.

I will, however, take a short look at possible means of shading. I'll limit myself to one hour of design/programming on it and if it can't be done in that time, I'll move on.

------------
Solo-Games.org | My Tech Blog: The Digital Helm

Fladimir da Gorf
Member #1,565
October 2001
avatar

Making some simple lighting would be easy - just calculate the dot product between the slope and the sun direction. Remember that unless you want to treat sun as a directional light, you'll need to calculate the direction of the sun at each point. In OL terms, but can be used anywhere: (~ is normalization)

Vec2D lightDir = ~( point - sunPos );
float lightIntensity = -( lightDir * slopeNormal );
if( lightIntensity < 0.0 ) {
  lightIntensity = 0.0;
}

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

Onewing
Member #6,152
August 2005
avatar

Quote:

Making some simple lighting would be easy

It was, although the current lighting scheme doesn't look at the mountains, it's more like putting a lamp over a sketch/picture of "mountains".

Quote:

Vec2D lightDir = ~( point - sunPos );

Let me make sure I understand this, if the point is on the left, lightDir will be 1 and if the point is on the right of the sun, lightDir will be -1? And I'm drawing a blank on the slopeNormal (probably because I'm at work and not suppose to be browsing forums).

[edit] - btw, you never commented on the brown-ish terrain if you liked it better than the red.

------------
Solo-Games.org | My Tech Blog: The Digital Helm

Fladimir da Gorf
Member #1,565
October 2001
avatar

Quote:

[edit] - btw, you never commented on the brown-ish terrain if you liked it better than the red.

Well, they both look a bit unrealistic...

Quote:

if the point is on the left, lightDir will be 1 and if the point is on the right of the sun, lightDir will be -1?

Well, if you think of the vector as a 1D vector, then yes.

Quote:

And I'm drawing a blank on the slopeNormal

That's the normal of the slope of the hill at the processed point. You could calculate it by finding 3 points around the point and calculating the normal with them.

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

relay01
Member #6,988
March 2006
avatar

I have nothing to contribute to this conversation because I know not what you speak about. I am a certified allegro newbie but... Thought I'd put my name out there... carry on

_____________________________________

Onewing
Member #6,152
August 2005
avatar

Okay, I tried to draw out some numbers to see if I could make some sense of them. I'm going wrong in the logic, so feel free to inform me where and/or what I'm doing wrong. (This is the first time I've used any vector math in any thing other than a classroom that was poorly taught [even the teacher was falling asleep as he lectured]).

Okay, let's get some concrete numbers to work with:

                V2
                *
             (100,101,52)

   V1                          V3
   *            *              *                                            *
(99,100,48)  (100,100,50)  (101,100,49)                                 (200,200)

Assume the above dots are nodes in the graph where the parenthesis gives (x,y,z) where z is the height of that node. The (200,200) is the location of the sun. Let's say we are calculating the light at point (100,100,50). You said pick three points to calculate the normal. Should I take the cross product of these three locations? I searched for a quick refresh session on cross and dot products that led to this:

GameDev.net - Vectors and Planes

It says I only need two vectors on a plane to find the normal vector? And if I should take the cross product of three vectors, should I take the cross product on V1 and V2 to find a new Vc to cross product with V3?

Whatever the case, I'll try to step through your procedure anyway.

//from graph above
lightDir = ~(point - sunPos)
         = ~((100,100) - (200,200))
         = ~(-100,-100)
         = (-1,-1)

Assuming the sun is always higher, the lightDir vector would be (-1,-1,-1)

//from graph above
slopeNormal = V1 X V2 X V3
    V1 X V2 = {(100 * 52) - (48 * 101),
               (99 * 52) - (48 * 100),
               (99 * 101) - (100 * 100)}
            = {5200 - 4848, 5148 - 4800, 9999 - 10000}
            = {352, 348, -1}
    V1XV2 X V3 = {(348 * 49) - (-1 * 100),
                  (352 * 49) - (-1 * 101),
                  (352 * 100) - (348 * 101)}
               = {17052 - -100, 17248 - -101, 35200 - 35148}
               = {16952, 17349, 52}
               = slopeNormal

Phew, I know this can't be right, but I'm gonna keep pluggin' numbers...

//Now for the dot product (assuming GameDev's code section of the dot product is correct
lightIntensity = -(lightDir * slopeNormal)
               = -((-1,-1,-1) * (16952,17349,52))
               = -((16952 * -1) + (17349 * -1) + (52 * -1)) 
               = -(-16952 - 17349 - 52)
               = -(34353) = -34353

So might lightIntensity came out to -34353. I plugged these numbers because I wanted to show that I am trying to figure this out without you babying me all the way, but I just haven't done enough of this kind of math to know the logistics of it. It's definitely a lot more complicated than my "the intensity of a pixel is it's height in proportion to the Max_Height * sunlight where sunlight = ((m * distance_from_sun) + b) / 100"

See, I told you, now I've spent too much time on this subject when I could've have been making progress. :-/ (although, thanks are in order)

------------
Solo-Games.org | My Tech Blog: The Digital Helm

Fladimir da Gorf
Member #1,565
October 2001
avatar

Quote:

= (-1,-1)

That vector doesn't have the length of one. Instead the length is sqrt(2).

Quote:

So might lightIntensity came out to -34353.

In that case it might not be wrong - the slope just isn't facing the sun, but is in the dark side of the hill. Of course to further improve the quality of the graphics you could add some constant light intensity to lit up the dark areas.

Quote:

See, I told you, now I've spent too much time on this subject when I could've have been making progress.

Well, sooner or later you'll have to improve the graphics, too...

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

Onewing
Member #6,152
August 2005
avatar

Quote:

That vector doesn't have the length of one. Instead the length is sqrt(2).

I'm getting the unit vector mixed up with normalization. What exactly does normalization do?

Quote:

the slope just isn't facing the sun, but is in the dark side of the hill.

According to the graph above, I can't imagine that to be true, unless there were some higher heights from 101 to 200, but that wouldn't make sense either, considering the formula doesn't look at any of those coordinates.

Another problem I have is this formula doesn't seem to take into affect how bright the light source is. Lastly, if 34353 was the intensity, I can't just multiply that with whatever color the ground is, it was produce some monstrous number, unless, that's what suppose to happen.

------------
Solo-Games.org | My Tech Blog: The Digital Helm

HoHo
Member #4,534
April 2004
avatar

Quote:

What exactly does normalization do?

It sets the vector lenght to one. That means you divide every vector coordinate by the lenght of the vector.

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Onewing
Member #6,152
August 2005
avatar

Hmmm, okay, if I take the (-100,-100) and normalize it, I get approx. (.71, .71). Would the Z still be -1? Or am I suppose to do the dot product with a 2 dimension vector and 3 dimension vector(which I thought I couldn't do)?

[edit] - typo

[edit] - If I move the sun to (101,101), I will get the same lightDir (as one would expect) and therefore, the exact same lightIntensity as if the sun were at (200,200), that can't be right...

------------
Solo-Games.org | My Tech Blog: The Digital Helm

Fladimir da Gorf
Member #1,565
October 2001
avatar

Quote:

Another problem I have is this formula doesn't seem to take into affect how bright the light source is. Lastly, if 34353 was the intensity, I can't just multiply that with whatever color the ground is, it was produce some monstrous number, unless, that's what suppose to happen.

Naturally you can just multiply the results with whatever you want. But the results should be in range [0, 1], there's something wrong with the calculation if you get such big numbers. Did you remember that the surface normal must be normalized as well?

Quote:

Or am I suppose to do the dot product with a 2 dimension vector and 3 dimension vector(which I thought I couldn't do)?

Heh, I forgot to say that all vectors and positions should be, in fact, 3D. That must be one of your problems.

Quote:

[edit] - If I move the sun to (101,101), I will get the same lightDir (as one would expect) and therefore, the exact same lightIntensity as if the sun were at (200,200), that can't be right...

Except that the formula is used in every 3D game/program out there...

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

Onewing
Member #6,152
August 2005
avatar

Quote:

Except that the formula is used in every 3D game/program out there...

I wouldn't be trying out these numbers if I thought this was all bogus, and I know you know what you are talking about, I'm just trying to get a good grasp of it myself. ;)

No, I never normalized the final value from the cross products, which is indeed a "d'oh" moment, considering the name, slopeNormal. But let me make sure, do I have to take the cross product of three vectors? Does it matter which three vectors I choose? And is there a method for doing the cross product on three vectors at the same time, or do I have to do it like I did above?

Quote:

But the results should be in range [0, 1]

That's what I wanted to hear.

------------
Solo-Games.org | My Tech Blog: The Digital Helm

Fladimir da Gorf
Member #1,565
October 2001
avatar

You just need two vectors: (point1, point2) and (point1, point3), for example. Then get a cross product between those two.

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

Onewing
Member #6,152
August 2005
avatar

Hmmm...something isn't working right. I've spent the past few hours making sure everything is as posted, but without a proper understanding of what's going on, I can't seem to tweak it right.

The Cross Product makes sense to me, but what is the Dot Product producing? Anyways, here's some results of the new code (keep in mind the moon is still trying to shade the right side). The first image is the normal (except for the far left side of the screen, which has already started converting to the other formulas).

The second screen is the result from the code posted below.

http://comp.uark.edu/~spsilve/terrain10a.JPG
http://comp.uark.edu/~spsilve/terrain10b.JPG

Code that is being used:

1class VECTOR
2{
3public:
4 float x;
5 float y;
6 float z;
7.
8.
9.
10 
11float VECTOR::length()
12{
13 return (sqrtf( (x * x) + (y * y) + (z * z)));
14}
15 
16void VECTOR::normalize()
17{
18 float temp = 1/length();
19 
20 x *= temp;
21 y *= temp;
22 z *= temp;
23}
24 
25float vDotProduct(VECTOR v1, VECTOR v2)
26{
27 return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
28}
29 
30VECTOR vCrossProduct(VECTOR v1, VECTOR v2)
31{
32 VECTOR vTemp;
33 vTemp.x = (v1.y * v2.z) - (v1.z * v2.y);
34 vTemp.y = (v1.z * v2.x) - (v1.x * v2.z);
35 vTemp.z = (v1.x * v2.y) - (v1.y * v2.x);
36 
37 return vTemp;
38}
39 
40//The function that determines the intensity of the light
41float PLANET::find_light(int x, int y)
42{
43 //Declarations
44 VECTOR v1, v2, vPoint, vSun;
45 VECTOR lightDir, slopeNormal;
46 float light_int;
47 int x1, x2;
48 int y1, y2;
49 
50 //setup vectors
51 x1 = x - 1;
52 y1 = y;
53 x2 = x;
54 y2 = y + 1;
55 if(x1 < 0) x1 = MAXX - 1;
56 if(y2 >= MAXY) y2 = 0;
57 
58 //Technically, x1,x2,y1,y2 will always be either -1,0 or 1, the z's will not
59 v1.x = x1 - x;
60 v1.y = y1 - y;
61 v1.z = ground[x1][y1].height - ground[x][y].height;
62 
63 v2.x = x2 - x;
64 v2.y = y2 - y;
65 v2.z = ground[x2][y2].height - ground[x][y].height;
66 
67 //The point needing its light intensity
68 vPoint.x = x;
69 vPoint.y = y;
70 vPoint.z = ground[x][y].height;
71 
72 vSun.x = sun; // sun moves during the game
73 vSun.y = 240; // The screen height is 480
74 vSun.z = MAX_HEIGHT;
75 
76 //Algorithm given by Fladimir
77 lightDir = vSubtract(vPoint, vSun);
78 lightDir.normalize();
79 
80 slopeNormal = vCrossProduct(v1, v2);
81 slopeNormal.normalize();
82 
83 light_int = -(vDotProduct(lightDir, slopeNormal));
84 if(light_int < 0.0)
85 light_int = 0.0;
86 
87 // Increase light strength
88 light_int = light_int * 100;
89 if(light_int > 1.0) light_int = 1.0;
90 
91 return light_int;
92}

Any ideas? (And yes, I know that the DotProduct and whatnot functions are already written somewhere and there probably was no need to rewrite them. Oh well).

[EDIT - Food for thought]
From the pictures, the light looks inverted (lighted where it should be shaded and heavily shaded where it should be light). This means the x,y of the hill are going the opposite way of the light source x,y. Look below:

                X    Y     Z
slopeNormal     +    +     -
lightDir        -    -     -
DotProduct      -    -     +

Since the light_int takes the negative of the DotProduct, if the DotProduct comes out to positive, then it will be negative, which will be less than 0, therefore, equalling 0. Thus, somehow, slopeNormal.z * lightDir.z > (slopeNormal.x * lightDir.x) + (slopeNormal.y * lightDir.y).

------------
Solo-Games.org | My Tech Blog: The Digital Helm

Fladimir da Gorf
Member #1,565
October 2001
avatar

Yeah, it looks like the intensity is inverted. Could you try not inverting the results of the dot product?

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

Onewing
Member #6,152
August 2005
avatar

I tried, but it wasn't much better. Imagine taking a negative of that picture above.

I think it has something to do with the points that I'm picking for figuring the slopeNormal. I tried several different values that led to several different results.

The scope of the world is basically 640 X 480 X 30000.

------------
Solo-Games.org | My Tech Blog: The Digital Helm

 1   2 


Go to: