- THE OUTLAW TRIAD DEMO-SERIES - ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄþ PART XII þÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Written by : Inopia/OT Edited by : Vulture/OT Topic : Improved flatshading ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄþ Introduction þÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Welcome to the Outlaw Triad demo-series! In these series we will be talking about programming demo-effects in either pascal or assembler. Theory behind the effects shall be discussed while a full sourcecode is also provided. So... it's time to move on to some serious math. We will implement improved flatshading now. I (Inopia) got a lot of these things from an article written by STO/THECLAN, in Insight#1 magazine, and I read PC Underground. Be sure to get them if you want to learn more about programming 3d. Here we go! ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄþ Theory þÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ - VECTORS - Okay, first we need to discuss vectors. A vector is a kind of arrow, with a starting point, a direction and a length. We use 3D vectors, so we define a vector with X,Y,Z. A vector is noted like this: =Vx V=Vy =Vz Ok, a triangle has three coordinates. But we need two vectors to do our calculations with. Let's define those vectors with some vector substraction: V1 = P2 - P1 V2 = P3 - P1 You need to substract all seperate components (x,y,z) from eachother here. So x-x, y-y and z-z. P1,P2 and P3 are the 3d triangle coordinates. V1 and V2 are the vectors we are going to do some calculating with. - VECTORS AND LIGHT - Now we need to find out a vector, in a right angle to the triangle. This is needed to determine the color of the face. Picture this: you have a postcard, a shiny postcard which you got from your girlfriend, who was on vacation in Singapore (without you, cos your car broke down). You hold it into the light. If you hold it like this... 1. |<------------------------------ | | | Lightbeam | | |<------------------------------ Postcard There is a lot of light falling onto the card. But if you hold it like this: 2. \<------------------------------ \ \ \ Lightbeam \ \<------------------------- There is LESS light falling onto the card! Let's find out how we can calculate this. Let's bring up that card again: | | \ | V | \ / | --|----------- V \ / | | / \ | | / \ | | \ 1. 2. As you can see I created a line through the middle of the card, IN A RIGHT ANGLE TO THE CARD. This line is called the normal. Let's shine some light on this, shall we? | <---------------- | \<------------------- | | \ / | --|----------- beam \ / | | / \ | | / \ | | <---------------- \<--------- 1. 2. In the first picture, the normal and the lightbeam have THE SAME ANGLE WITH THE POSTCARD! This means there's a full amount of light shining on the card. In the second picture however, the two angles differ. The angle between the lightsource and the normal is larger than zero. If we can find this angle (between the normal and the lightsource) we can find out how much light is shining onto the postcard, and in our case, the polygon in 3d space!!! - CROSSPRODUCT - DOTPRODUCT - To find the normal, we must we take the crossproduct of the two vectors we calculated before. This will leave us with just one vector. This vector is a right angle with the two other vectors, and thus in a right angle with the triangle. V3 = V1 * V2 V3x = V1y * V2z - V1z * V2y V3y = V1z * V2x - V1x * V2z V3z = V1x * V2y - V1y * V2x There is just one slight problem. These values can vary in size, according to the size of the triangle. We want to get em to be in -1 to 1, so that we can adjust the size to anything we want. As said before, a vector also has a size. One can easily calulate the size of a vector like this: length = sqrt (V3x * V3x + V3y * V3y + V3z * V3z) To shrink a vector to a length of 1, we devide all components of the vector by the length of the vector: V3x = V3x / length V3y = V3y / length V3z = V3z / length We also multiply these values with the maximum number of colors you reserved for the shading. Check the source to see what I mean. Anyhow, V3 holds the normalvector of the triangle. Now we need to come up with a lightsource. Well, the lightsource is easy: it's defined by you. Mostly, the light is coming from the viewer, so the lightsource would be: 0 LS 0 -1 You see? This is a 3d vector also. Now, one more formula coming up... The dotproduct. This formula returns a value which is equal to the cosine of the angle between the lightsource and the triangle. You use the normal you just calculated and the lightvector for the calculation. DP = V3x * LSx + V3y * LSy + V3z * LSz Now, if we take the dotproduct of the normal and the lightvector like stated here, we've calculated the exact color of the face. Draw it and you're done! Phew! Pretty complicated math but well worth the effort. Again, check out the source to see how it can be done. This method is a lot better than just using the avarage z-value of a poly to calculate the color. You can use this method for more complicated objects as well. If you know how to handle 3DS objects, you could try this method on those objects. Go for it! - OPTIMIZATION TIPS - - Well, as you might have guessed, it's impossible to get an engine running fast when you've got all those SQRT's to execute. The solution: calculate all facenormals once, and then just rotate 'em just like the vertices. - There are faces you can't see. Ofcourse you don't have to draw them. Here's a neat trick for that: whenever the Z-value of a facenormal is smaller than zero, don't draw it! Makes the engine running a LOT faster. (note: we will implement this effect in a future trainer) - How can we avoid the lightsource vector and the dotproduct? Like this, we take the Z-value of the facenormal, and adjust it a bit, so that it will fit into the amount of colors you want. The only problem is you can't have a variable lightsource. If you still wanna have that effect, try rotating the normal vectors over other angles than the vertices, or don't rotate the vertices at all (although I think an object that's not moving looks very DULL!). There are probably some untrue things in here so if you know better mail me. (mail me or OT for any other reason). Catch ya later! -Inopia/Outlaw Triad- ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄþ Distro Sites þÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Call our distribution sites! All our releases are available at: BlueNose World HQ +31 (0)345-619401 The Force Distrosite +31 (0)36-5346967 Bugs'R'Us Distrosite +31 (0)252-686092 More distros wanted! The 7 Angels Distrosite +31 (0)715-148377 (preferably outside ShockWave South African HQ +27 (011)888-6345 of the Netherlands) Society HQ United States HQ +1 (518)465-6721 ACe World Brazilian HQ +55 (21)-259-8847 Corps Elite Canadian HQ +403 (ITS)-PRIVATE Also check the major FTP/WWW sites for Outlaw Triad productions. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄþ Contact þÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Want to contact Outlaw Triad for some reason? You can reach us at our distrosites in Holland. Or if you have e-mail access, mail us: Vulture (coder/pr) comma400@tem.nhl.nl Inopia (coder) inopia@horizon.nl Our internet homepage: http://www.tem.nhl.nl/~comma400/vulture.html These internet adresses should be valid at least till june 1997. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Quote: Time is the best teacher. Unfortunately, it kills all its students.