Free website sponsorship

Recent Forum Topics

View Discussion beeen a while

since i been oon here :( - summer break = me away from computer.... - how was everyones summer..... - ....any1 have ideas for a csharp project

View Discussion How to setup php so I can use mail() function?

You can set it up in php.ini. http://www.w3schools.com/PHP/php_ref_mail.asp has information on the configuration options required.

View Discussion Creating Identical Tables: HTML and CSS Article

http://programming-designs.com/page/editorials/item/6 - It was under the articles/editorials section of the main site, not the most logical place but PD only had one html tut...

View Discussion LISP

Lisp is cool in a few ways, but the one that strikes most people is that everything is a list. Hence, it is a pretty good list processor. When the first element of a list is not escaped (quoted - described below), th...

View Discussion Review Script: New Job Board Software

We are happy to announce the release of [url=http://www.smartjobboard.com]SmartJobBoard[/url] job board software. [url=http://www.smartjobboard.com]SmartJobBoard[/url] i...


3D Shading in Visual Basic

In the two previous tutorials from the series 3D-in-VB we saw how to create a basic 3D environment made up of dots. This, although quite fun to play with for a few minutes is never really going to become a proper game. In this tutorial we are going to see how it is possible to create filled shapes and shade them for realism.

Adding polygons is the easy part as all we have to do is keep the corners of the polygon grouped together using a method so that we can draw it as one shape. Each point is manipulated as before. We should also create a color value for this shape as our world is not really going to be very interesting with just one colour everywhere. Our goal at hand is to create a realistic three dimensional world as nothing is more interesting than real life.

To draw the polygons we have to reach for a tool outside of Visual Basic. We will be using Windows API's for this. An API is one of the many functions which are combined together to make Windows. We will just be using the polygon API for this project which is quite simple. A good list of API's is found on our Programming/Web tools section where the API Viewer is available for download.

To define an API, more specifically, the API we will be using, we use this code:

Private Declare Function Polygon Lib "gdi32" _
(ByVal hdc As Long, lpPoint As POINTAPI, ByVal nCount As Long) As Long

Private Type POINTAPI
X As Long
Y As Long
End Type


The function uses this type to hold it's data so we have to define it as well. The function has three pieces of data that must be passed into it. The first one is a reference to an object. This is easy to get as it will be your object's property (if your drawing object is a picturebox or form). The lppoint will be the first item in your array of values for the polygon. nCount is simply the number of points in your polygon. Be careful to make sure you array is big enough for the nCount value as API's can crash you system if abused.

The next step is to sort the polygons into the right order. This is easily done by using a quicksort or similer. I just lifted my sort off something else so I work go through the details of sorting here. I usually sort by finding the average of the z points of the polygon and using that as the depth indicator.

Now we are onto the more advanced bit, the shading. I first did the shading by keeping the lighting effect fixed from the front. i.e. just comparing the angle of the face with the Z axis. This did not look very good as the shading did not change when you moved the camera. I changed the coding so that the camera is the light source.

First we need to work out the normal of out plane. This a the line which is perpendicular to the plane. To get this we use some vector algebra. The thing to remember with vectors is that they only have a size and direction, not a position. We need three points to work out the normal, each with X, Y and Z coordinates.

NormalX = ((y1 - y0) * (z2 - z0)) - ((z1 - z0) * (y2 - y0))
NormalY = ((z1 - z0) * (x2 - x0)) - ((x1 - x0) * (z2 - z0))
NormalZ = ((x1 - x0) * (y2 - y0)) - ((y1 - y0) * (x2 - x0))

Now we have the normal we have to find the angle between this vector and our camera's vector. The camera's vector is easily worked out by just finding the center of the shape (You are at 0,0 so the vector is from 0,0 the the object).

Now we have the two vectors we just need to find the angle between them. This is easily done by more vector algebra.

Shade =
(NormalX * midx + NormalY * midy + NormalZ * midz) /
(Sqr(midx ^ 2 + midy ^ 2 + midz ^ 2) * Sqr(NormalX ^ 2 + NormalY ^ 2 + NormalZ ^ 2))

This is displayed in shorter algebra.

Shade =
(Normal . mid) /
(|normal| * |mid|)

|vector| is just the length of the vector. We can easily use pythagorean's theorem for this. The dot product just multiplies each dimension of the vector.

The result we end up with is the cosine of the angle but we have no need to convert it to degrees as it works fine just as it is.

Now you just multiply the color by the shade (assuming you are working in RGB) and hey presto you have a shading program. You may want to lessen the intensity of the shading to make it a bit more real looking.

The source code for this tutorial uses matrix manipulation for the general 3D but that's a different tuorial. It would work exactly the same with the stuff from the other tutorial. For a challenge, try using the method we provided and see if you can get it working.

Download the accompanying source code.