Posted: 2nd Jun 2007 18:15
I've been coding for a while now and I still don't actually know what normals are or how to use them (or what normalization is for that matter) can anyone give me some insight as to what they do?

(The DBP help is entirely unhelpful on this matter, it just says:
SET NORMALIZATION ON

This command will normalize all 'normals' contained in 3D rendering data.

and

SET NORMALIZATION OFF

This command will deactivate normalization of all 'normals' data.)



Cowbox
Soharix HQ
http://www.soharix.homstead.com/
Posted: 2nd Jun 2007 18:22
Google is your fiend



A flat polygon situated in 3-D Coordinate Space necessarily has an orientation. It faces some unique direction. An imaginary ray pointing out from the surface of the polygon, and perpendicular to that surface, is called the normal of the polygon.

As there will always be two normals, one on each side of the surface, and pointing in opposing directions, the choice of the side from which the normal projects defines the front or "face" of the polygon. In 3-D computer graphics, as opposed to the physical world, it is usual for a polygon to have only one face or side, and therefore only one normal. This is because polygons are typically used to create a closed mesh representing the surface of a 3-D object and the back side of the polygon is therefore hidden inside the object. To save render time, polygons are kept single-sided and the normal projects from only the exposed face. However, occasionally it is necessary to create double-sided polygons that have normals pointing from both sides, and which therefore can be rendered from both sides as the different sides come into view during the course of an animation. The face side of a polygon is typically established in a Model file by the order in which the vertices of the polygon are listed, clockwise or counterclockwise around the facing (normal) side.

Normals can be associated not only with the flat surfaces of the polygons, but also with the individual points that make up the vertices where polygons meet on the surface of a model. This technique is used in rendering to create the appearance of curved surfaces rather that flat, faceted sides. Such vertex normals can be directly assigned in the model file, but are usually computed during rendering by averaging the normals of the adjacent polygons. This rather subtle idea is described and illustrated in the Lesson 3 tutorial.
Posted: 2nd Jun 2007 19:05
Lol, "Google is your fiend."

Cough cough, anyway:

Ok, that helped. I now know what a normal is.

But what is "normalization"? Surely all polygons are normalized anyway, otherwise they wouldn't be polygons?; If they had normalization turned off, they wouldn't exist.

Cowbox
Soharix HQ
http://www.soharix.homestead.com/
Posted: 2nd Jun 2007 22:22
I'm not sure that you do know what a surface or vertex normal is - they don't have anything to do with the existence of polygons.

Imagine a normal as a vector that points outwards in relation to a polygon (for a surface normal). It describes a direction that light will be reflected around when it hits a polygon. It's a little more complex than that for a vertex normal, but basically the same idea.

A vector itself can be normalised by ensuring that its length is 1 unit. If the length of a normal vector is over 1 it will become lighter, and if under 1 will become darker.

Using the SET NORMALISATION ON command will cause objects to be rendered as if the length of the normals was 1.
Posted: 3rd Jun 2007 13:06


I think I'm getting there.

But what relationship does "length of its normal" have towards the polygons state/look?

Cowbox
Soharix HQ
http://www.soharix.homestead.com/
Posted: 3rd Jun 2007 15:33
Basic explaination to a vertex normal, is a pre-calculated light angle.

If you have already taken high-school (gcse) physics you will know that when light hits a surface, it reflects which dictates how much light you can see in a surface.

This is generally known as the "normal light reflection", or "normal" for short. The way it works is, you have your point in 3D space (the vertex). This is your starting point of where the light is reflected from, we then have a second vector (an imaginary vertex) elsewhere in the scene that determins the angle that the light is reflected to.

The length of a normal, is just that; how long the adverage length of the light is. This allows us to determin the height of the surface.

Graphics have improved since this method was originally created to mimic realistic light, and now this can be done on a per-pixel basis to give you a more precise surface determination.

"Set Normalization On" basically recalculates the normals on objects, or rather it used to. So that it had adverage angle of 180 from the vertex. (i.e. light reflected right back from the vertex) This causes models to look very smooth.
Posted: 3rd Jun 2007 15:34
But what relationship does "length of its normal" have towards the polygons state/look?


The amount of light falling on a surface is usually worked out by calculating the dot product of (minus) the light direction vector and the normal vector. If you, say, double the size of the normal you will double the calculated amount of light. It all depends on how, precisely, the calculation is performed. In most of my shaders, for example, I normalize direction vectors before using them in such calculations - if you don't, unexpected results can be obtained.

The purpose of the dot product is to give a light intensity value between 0 and 1, i.e. between zero and full light. Using normalized light direction and normal vectors ensures this (except that negative values are usually interpreted as zero). You are, in effect, calculating the cosine of the angle between the two vectors.

Hope this helps.
Posted: 4th Jun 2007 0:54


Well it sort of does. But you understand if I say that this isn't going in very well because I am a visual learner and its very hard for me, if I don't know all the names of all the diferrent parts of 3D space properly anyway, to visualise all of this. Maybe some diagrams might help.

Oh and I tried the normalization on command on 1 of my levels in a game and nothing really happened. Then I think i "set the normals" or something to the map object and it made all the polygons really easy to see rather than them all flowing together to form a smooth map. So I think I know roughly what this all does, I just don't really get why it does it (and also what the normalization on/off commands didn't seem to do anything.)

Thank you all though for spending your time trying to help someone who isn't that good with 3D termanology to learn all this.

Cowbox
Soharix HQ
http://www.soharix.homestead.com/
Posted: 4th Jun 2007 19:45
How about this: I'll talk you through a single-poly object.

Imagine a sideways view of that polygon (basically a horizontal line). Draw it.

Now draw another line straight up from it. This is the normal of the polygon (or at least it's direction).

That completes our object. Now we'll get onto rendering...

Draw a line in from an angle that hits the polygon at the same point the normal joins the polygon. This is your incoming light.

Then measure the angle between the normal and the light lines. Use this to draw another line on the opposite side of the normal, but at the same angle. This is your light reflection.



That's it. That's what a normal is used for.

If your normals are all of length 1, then SET NORMALIZATION ON will have no effect
Posted: 4th Jun 2007 22:13
I am a visual learner


Apologies if I'm on the wrong track here and you already knew this, but here's a visual example of normalization 'in action':

+ Code Snippet
Gosub Setup
Do
  CX#=Camera Angle X(): CY#=Camera Angle Y(): CZ#=Camera Angle Z()
  CY#=Wrapvalue(CY#+mousemovex())
  CX#=Wrapvalue(CX#+mousemovey())
  Rotate Camera CX#,CY#,CZ#
  If MouseClick()=1 Then Move Camera 10
  If MouseClick()=2 Then Move Camera -10
  If Scancode() Then Normalise(1)
  Sync
  Center Text 400,5,"Press Any Key To Apply Normalization"
Loop

Rem **************************************************
Rem                  Smooth Matrix
Rem **************************************************
Smooth:
  Rem Averages matrix heights to remove jagged edges
  for Z=0 to 70
    for X=0 to 70
      P0#=Get Matrix Height(1,X,Z):     Rem Current point height
      Rem Get 4 adjoining points heights (if they exist)
      If Z-1>=0
        P1#=Get Matrix Height(1,X,Z-1)
      Else
        P1#=P0#
      Endif
      If X+1<=TilesX
        P2#=Get Matrix Height(1,X+1,Z)
      Else
        P2#=P0#
      Endif
      If Z+1<=TilesZ
        P3#=Get Matrix Height(1,X,Z+1)
      Else
        P3#=P0#
      Endif
      If X-1>=0
        P4#=Get Matrix Height(1,X-1,Z)
      Else
        P4#=P0#
      Endif
      Average#=(P0#+P1#+P2#+P3#+P4#)/5: Rem Av height of other points
      RHeight#=Average#
      Set Matrix Height 1,x,z,RHeight#
    Next x
  Next z
  Update Matrix 1
Return

Setup:
  Set Display Mode 800,600,32
  Sync On: Sync Rate 0: CLS 0: Sync
  AutoCam Off
  Set Camera Range 1.0, 100000.0
  Hide Mouse
  Create Bitmap 1,1024,1024
  Rem ********************
  Rem    Matrix Texture
  Rem ********************
  Ink RGB(0,110,0),0
  Box 0,0,1023,1023
  For N=1 To 15000
    Ink RGB(0,Rnd(150)+50,0),0
    Dot Rnd(512),Rnd(512)
  Next N
  Blur Bitmap 1,1
  Sync
  Get Image 100,0,0,512,512,1
  Sync
  Rem ********************
  Rem       Matrix
  Rem ********************
  Make Matrix 1,7000,7000,70,70: Rem 1 Tile = 100
  Prepare Matrix Texture 1,100,70,70
  Randomize Matrix 1,2000.0
  For N=1 To 40
    X=Rnd(66)+2: Z=Rnd(66)+2
    Set Matrix Height 1,X,Z,7000.0
  Next N
  For N=1 To 15
    Gosub Smooth
  Next N
  t=1
  For z=69 to 0 Step -1
    For x=0 to 69
      Set Matrix Tile 1,x,z,t
      Inc t
    Next x
  Next z
  Update Matrix 1
  Set Current Bitmap 0
  Delete Bitmap 1
  Position Camera 0,3000,0
  Point Camera 3500,0,3500
  Ink RGB(255,255,255),0
Return


Rem *********************************************************
Rem ***                   FUNCTIONS                       ***
Rem *********************************************************


Function Normalise(MatNum)
  Rem By Lee Bamber From DB Example - Adds shaded areas to matrix to give depth
  For z=1 to 70
    For x=1 to 70
      h8#=get matrix height(MatNum,x,z-1)
      h4#=get matrix height(MatNum,x-1,z)
      h#=get matrix height(MatNum,x,z)
      h2#=get matrix height(MatNum,x,z)
      x1#=(x-1)*25.0
      y1#=h#
      x2#=(x+0)*25.0
      y2#=h4#
      dx#=x2#-x1#
      dy#=y2#-y1#
      ax#=atanfull(dx#,dy#)
      ax#=wrapvalue(90-ax#)
      z1#=(z-1)*25.0
      y1#=h2#
      z2#=(z+0)*25.0
      y2#=h8#
      dz#=z2#-z1#
      dy#=y2#-y1#
      az#=atanfull(dz#,dy#)
      az#=wrapvalue(90-az#)
      nx#=sin(ax#)
      ny#=cos(ax#)
      nz#=sin(az#)
      Set matrix normal MatNum,x,z,nx#,ny#,nz#
    next x
  next z
  Update Matrix MatNum
EndFunction


TDK_Man
Posted: 4th Jun 2007 22:31
Hmm, that makes sense.

So basically normalization makes the polygons look nice.

I still don't see how changing the length of the normal would affect it though, I mean, a line is a line is a line is a line. It doesn't matter how long it is, you can still measure an angle against it to reflect the light?

I think this is the bit I was missing.

Cowbox
Soharix HQ
http://www.soharix.homestead.com/
Posted: 4th Jun 2007 22:34
As well as controlling the angle of reflection, they can also be used to affect the intensity of the reflection. If you shorten the normal/vector, the intensity is lowered. If you lengthen the normal/vector, the intensity is raised.
Posted: 4th Jun 2007 22:49
Ah right, so is there a way to set a custom height for the normals or is it just 0 and 1 for DBP?

Because that would be better for making things like HDR (high dynamic range) if you could exceed the intensity beyond 1, to make things brighter than they should go, to create a shine effect.

Cowbox
Soharix HQ
http://www.soharix.homestead.com/
Posted: 4th Jun 2007 23:03
DBPro doesn't set the normals normally - you do. Or rather, your modelling package does (or doesn't as the case may be).

If you have an object that is all-black then it may be that the normals are zero or 'pointing' in the wrong direction. You can get DBPro to create a default set of normals for you by using the SET OBJECT NORMALS command.

You can also manipulate the normals at a low level by accessing them and recalculating them yourself.

+ Code Snippet
sync on

make object sphere 1, 1.0

Increased = 0

do
   if spacekey() = 1 and Increased = 0
      Increased = 1
      lock vertexdata for limb 1, 0
      for i = 0 to get vertexdata vertex count()-1
         set vertexdata normals i, get vertexdata normals x(i) * 1.1, get vertexdata normals y(i) * 1.1, get vertexdata normals z(i) * 1.1
      next
      unlock vertexdata
   else
      if spacekey() = 0 then Increased = 0
   endif
   if upkey() = 1 then SET NORMALIZATION ON
   if downkey() = 1 then SET NORMALIZATION OFF
   sync
loop


Press the spacebar to gradually increase the intensity of the object lighting. Use the up & down keys to see the effect of the SET NORMALIZATION XXX commands.
Posted: 5th Jun 2007 1:13
Ahh that helps.

That probably explains why none of the CS and HL1.5 maps I used to try loading into DBP worked, they were just black. It was probably the normals (and maybe no lighting)

Edit: Never mind about this part. (I figured it out.)

Cowbox
Soharix HQ
http://www.soharix.homestead.com/
Posted: 27th Aug 2007 12:45
This is one extremely useful thread, answers alot of my questions.
I have a feeling, but cant be too sure, but do phong tags have anything to do with normals? i think theyre for curves or something but they display the same effect when turned off.
Posted: 27th Aug 2007 14:03
Well, DBPro does use phong shading (I think, but it might be gourand), but not tags.

Although I explained how a surface normal works, DBPro doesn't actually use them - it uses vertex normals. A vertex normal is usually calculated as the average of the surface normals that use that vertex, but can be set separately.

This gives DirectX 3 normals to use per poly. To get the correct lighting levels for each plotted pixel of the poly, DirectX applies linear interpolation to calculate the actual normal for that point (it's a fancy way of saying it uses a weighted average of the three normals depending on how near that point is to each vertex).

It's because the normal is adjusted across the poly, that the lighting levels change (as the normal affects the reflected light from your poly), and you get smoother lighting across the rendered result, making it smoother looking.
Posted: 27th Aug 2007 14:17
ohh ok. Confusing, but i understand after a while