- THE OUTLAW TRIAD DEMO-SERIES - ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄþ PART XV þÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Written by : Inopia/OT Topics : More Gouraud & Texture ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄþ 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. Hey kids, it's Inopia again with a blurry tutor which you are supposed to read and be happy about. Well, Vulture has been kicking my ass around about a fast way to do texture mapping and gouraud shading so let's talk some more about that. OT already released a trainer covering those topics but hey, who cares! There's always room for improvement... Here we go! ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄþ Theory þÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ - GOURAUD - The problem with Gouruad and Texture routines is that a horizontal line rou- tine also requires sum heavy interpolation, and that's quite a problem if you never coded something like that before (never coded one of those cool texture rotating thingies?). But don't let this scare you off, cuz it's really not that hard. By the way, I advise you to read our other tutor on flat shaded polys, since you aught to understand those principles first and I'm NOT going to explain that AGAIN! So if you don't have it, login to one of our fine distribution points and grab it NOW! Anyway, a mistake that a lot of people make, is that they calculate the deltavalues needed to draw a horizontal line (of wich your poly is made of), every time a new line is drawn. This is not very smart, since an average poly is made of, let's say, 7 lines (depends of course), which means, 7 times a DIV, wich is not very fast. It's also possible to do those deltas ONCE PER POLY! I once had an engine, wich did 256 polys smoothly on a p75... Boy, that sucked :-) But when I upgraded that one thing, my engine suddenly did 1200 polys! (not very fast either, but hey, it's still pascal(-:) Well, first let's do Gouraud shading, and we'll upgrade that to do texture mapping later on. Gouraud is a shading method, where every vertice has it's own color, wich is then interpolated along the polygon. It is quite fast compared to environment mapping, but you won't get that cool lightspot. Ofcourse you can simulate it, but more of that in the optimizations/tricks section. Gouraud polys aren't very different from those flat polys, except for the horizontal line routine. Also, they require not only interpolation of the edge X coordinates, but also of the colors (but that's obvious). You can handle the colors the same as the X coordinates. Remember that now every point does not consist of (X,Y), but of (X,Y,C), where C is the color of that particular vertice. Let's bring up the poly again: TOP - / \ | / \ | Loop1 / \ | / \ | / \ | Q* / MID - / / | / / | Loop2 / / | // | BOT - Remember? Well, we need to know point Q, because we need the delta values of the longest line in the poly (most accurate), which is always Q.X-MID.X. So the first thing we do is calculate point Q. You know Q.Y, because it's the same as MID.Y. Therefore: Q.Y = MID.Y Okay, what else do we know... Well, we know point Q is somewhere on TOP-BOT. Actually, we know it's on TOP-BOT at position MID.Y! So we can now calculate Q.X and Q.C. Just interpolate. We can use the same deltavalues as the ones we used to calculate the edges of the polygon. If you read our tutor on the FLAT SHADED POLYGONS (otpoly.zip), you know how to get it. We'll call it EBR here. What we need to do is take the distance between TOP.Y and Q.Y, multiply it by EBR (the delta), and add top.x: Q.X = (TOP.Y-Q.Y) * EBR.X + TOP.X This can ofcourse also be done with the color values: Q.C = (TOP.Y-Q.Y) * EBR.C + TOP.C Note that we now have TWO right edge deltas, one for the X positions, and one for the colors. Okay, now that we know point Q, let's put it to use. Let's calculate the Delta value for the horizontal line routine thingie. I hope that you know how this formula is going to look like by now, but for the people who want to be sure, here it is: DELTAC = (MID.C - Q.C) / (MID.X - Q.X) The last thing we need to do now, is change the HLINE routine. When you are going to draw a poly, you interpolate the X and C values along the edges. Now you can draw your HLINE. The color of the pixel will be represented by the variable C. All you do, is plot a pixel with color C, add DELTAC to C, and plot the next pixel. Keep this up the whole line, and voila! You have a nice little Gouraud engine running! I know I'm not very good at explaining this stuff, so here's a little code: For I = X1 to X2 do PUTPIXEL(I,YPOS,C) ADD C,DELTAC Next I - TEXTURE MAPPING - So... This covers gouraud. Texture mapping isn't very different. Only that every vertice has an X, Y, U, and V value. (U,V) are the coordinates on the texturemap. Do everything just like gouraud, with the difference that every- thing you do to the Color values, you need to do twice (once to U, and once to V). The HLINE should look something like this: For I = X1 to X2 do PUTPIXEL(I,YPOS,MAP[V*256+U]) ADD U,DELTAU ADD V,DELTAV Next I Optimization/Tricks: - GOURAUD - - This is about gouraud. With Flatshading, you need colors for a face. With gouraud you need colors for every vertice. In the OT file on lightsourcing, we've discussed how to get those face-colors. But how to get those vertice colors? Well, it's really easy. For every vertice, take the average of the colors of all faces using that vertice! hint: pre-calculate a vertex normal by taking the average of all face normals of the faces using that vertice. Do this for all vertices to get all vertex normals. Rotate those vertex normals like you do vertices and then take the dotproduct of the rotated vertice normal and your light vector to calculate the color of the vertice. - Some demos have two vector objects moving through each other. Just check out VERSES from EMF. How they did that? Well, it's called Z-BUFFERING. You need another buffer (or virtual screen, what's in a name?). Just like the colors in gouraud shading, the Z-VALUES are interpolated along the poly, and they are stored into that virtual screen (=Z-BUFFER). When you draw the next face, you check if the Z value of a particulair pixel is smaller than the one already present on the Z-Buffer, and if so you plot (to the screen, as well as to the z-buffer). - As seen in demos like ARABICUM from MASSIVE, you can also just grab sum random values for your vertice colors, and it still looks kinda nice. - TEXTURE MAPPING - - It's faster to use a 256x256 texturemap instead of something like 320x200. The U and V values are interpolated seperately, and when you want to put them toghether to get an offset on your texturemap, you get Y*256+X. In assembler, this would be MOV BH,Y MOV BL,X Because BH is a significant byte, it's automatically shifted 8 bits, which resembles a multiplication by 256. - Environment mapping (fake phong). Now that you know how to do some texture mapping, you can do environment mapping. For every vertice, grab the average of all normalized facenormals of the faces using that vertice and multiply by 128 (for 256x256 texturemaps). Then you just rotate those verticenormals like vertices. When drawing a poly, the (U,V) coordinates resemble the (X,Y) of the rotated verticenormals, +128. The +128 needs to be done, because the (U,V) coordinates have to be centered to the middle of your fine 256x256 texturemap. - Lenz mapping (fake refraction?). I got this tip from PHRED (thanx). Just normalize the vertices and use the (X,Y) coordinates as (U,V) coordinates (don't forget to add 128). It looks kinda lenzy... Gosh, I just realized that OT has covered just about every aspect of the 3D wizardry... it's time we find another subject! Ah yeah, if you know something we could write about, or if you coded a cool engine, if you want to puke at us, or whatever, REACH US!! I myself can be reached at INOPIA@HORIZON.NL (e-mail) You can also check if I'm at #TRAX or #CODERS (irc.demoscene.org & irc.neato.org). Check saturdays and sundays around 23:00 and 24:00. And I'm sure VULTURE is going to paste quite a list of ways to reach Outlaw Triad. Bye, -Inopia/OT- ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄþ Distro Sites þÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ All our releases are available at these fine boards: Amberdawn World HQ +31 (010)-2160945 Excessive force Dutch Distro +31 (0497)-572146 ShockWave South African HQ +27 (011)888-6345 Society HQ United States HQ +1 (518)465-6721 ACe World Brazilian HQ +55 (21)-259-8847 Dark Genesis Canadian HQ +1 (250)561-2850 More distros wanted! Corps Elite Canadian Distro +1 (ITS)-PRIVATE Pixel Wars Italian HQ +39 (744)-220515 Power Point Belgium HQ +32 (3)-4881033 LooK BBS Polish HQ +48 (94)-415621 iK BBS Swedish HQ +46 (63)-35644 Also check the major FTP/WWW sites for Outlaw Triad productions. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄþ Contact þÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Want to contact Outlaw Triad for some reason? Please do so! 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 All our releases are available at our homepage so if you haven't got all, visit us. These internet adresses should be valid at least till june 1997. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Quote: When you tried everything, read the manual...