Bump Mapping & Normal Mapping

Blitz3D Forums/Blitz3D Programming/Bump Mapping & Normal Mapping

MadMunky(Posted 2004) [#1]
Can anyone point me to a blitz3d prog/demo with the source which demos on how to do bump maping, we tryed adding normal maps but it slowed down the game to much, will bump maps work any better?

Thanks


Mustang(Posted 2004) [#2]
Normal maps = bump maps, just better (harder) way to do those than the old "heightmap bumpmaps" method.


AntonyWells(Posted 2004) [#3]
Were you using world space or tangant(sp) space?

Tangant mapping is slower because it's pretty much cpu dependent, but world space is very fast on most cards. We had tech demos of 20-40 of rob's statues flying about with per pixel lighting, no slowdown, even on a g3.
as it's basically just another blending mode..(dot3)

try this, world space mapping technique,

    x#=entityX(myMesh)-entityX(light) 
    y#=entityY(myMesh)-entityY(light)
    z#=entityZ(myMesh)-entityZ(light)
    td=entitydistance(myMEsh,light)
    x=x/td
    y=y/td
    z=z/td
    entityColor myMesh,128+128*x,128+128*y,128+128*z


per frame on any normal mapped entities.

You'll want to tweak the normals to add things like fall off and perhaps correct distance etc, but it's very fast.


MadMunky(Posted 2004) [#4]
Ok anyone got any ideas why this is happening? We are using Omni for the light source which follows the character but when you turn the light isnt working correctly and some walls are dark.







The player hasnt moved just turn around, any ideas?


skidracer(Posted 2004) [#5]
Normal maps can't usually be used by themselves as they do not provide any ambient light. The result of the normal map stage is alway 0-100% so you need to use multitexturing to add an ambient light stage to the surface calculation.


MadMunky(Posted 2004) [#6]
So why does the wall work at the front but not at the back there all the same wall/mesh/texture/normal map?


skidracer(Posted 2004) [#7]
Without ambient light any surfaces facing away from the normal-map-light will be black.


AntonyWells(Posted 2004) [#8]
That's odd. Ambient light stage?(Raises eye-brow bond stylee)

I just scaled the world-space normal to simulate differant light levels. Ie. x=x*distance (Distance being from 0 to 1)

distance worked out ( distance =(fallOff-entityDistance(light,mesh))/fallOff

Unless I'm getting the wrong end of the stick(Would not be the first time.Nor the last..)


MadMunky(Posted 2004) [#9]
we use a point light at the center of the player, so there must be light reflecting on all walls near the player. So, ambient lighting is not the point here i think.

What do you mean by "The result of the normal map stage is alway 0-100% so you need to use multitexturing to add an ambient light stage to the surface calculation"

Thanks


skidracer(Posted 2004) [#10]
Normal maps work by multiplying a single *directional* light vector with the vectors encoded in each texel of the texture.

The result of this multiply is 0..1 (black to white) which you can use to contribute extra detail to the final colour of the rendered surface but is not much use by itself (unless you're into ambientless (?) black and white lighting effects)...


TartanTangerine (was Indiepath)(Posted 2004) [#11]
I suspect that you are using object space normal maps and not tangent space.

------------Something I found on the web---------------
The main idea behind using tangent space is going through extra steps to allow the reuse of a normal map texture across multiple parts of the model (storing normals/binormals/tangents at the vertices, and computing the normals of the normal map relative to them, then converting back when rendering. Also, you could use tangent-space to skin a flat bump texture around a model.) By writing a tutorial on object space, I'm not saying object space is better. However it does have some advantages, and is certainly a usable approach. Below are a few of my thoughts on the two methods for those interested, I'm not qualified to give a great comparison of the two though. There are some tricks or different ways to do things with any method.

Advantages to using Object Space:

It's simpler to implement and I find it more straightforward to think about. The normal map contains the normals pointing in their actual directions (for an unrotated model at least.) You get to forget about per vertex normals, tangents, and binormals ( which I'll call n/t/b for short. ) This means less initial calculations, and you don't have to worry about poorly behaved n/t/b causing distortion. It's also faster because you don't have to rotate the n/t/b with your model, or convert light vectors to tangent space. Level of detail algorithms or anything else that reduces and changes the vertices in your model can easily run fine. (In tangent space the changing n/t/b interpolations caused by removed vertices would distort the mesh normals. )

Disadvantages (as opposed to Tangent Space):

You can't reuse texture coordinates for symmetric parts of the model. If you had a model that is completely symetric along an axis, and 1 MB normal map, that means 0.5 MBs of it is redundant information. If this bothers you, keep in mind this is only for something rendered as one piece. In the case mentioned above you could render the model in two halves, each using the same normal map, but one rendered with the light vector x component reversed ( or y or z depending on the axis of symmetry. ) Which would be a bit of extra work itself though.
The main disadvantage to not using tangent space is that you can't use a detail normal map for fine close-up detail in addition to the one that approximates the high resolution mesh. (You can add details into the object space normal map when generating it, however, a detail normal map would be highly repeating, thus offering much greater resolution than just using the one normal map.)


AntonyWells(Posted 2004) [#12]
One thing to consider is in Blitz G=z and B=Y. (I.e reverse them in your 'equations')

If you're still stuck after that, say so and I'll dig up some code off my hd that works.


MadMunky(Posted 2004) [#13]
Otacon: Im really confused as to what we are doing wrong so any demo code which you think would help us would be grate :)


AntonyWells(Posted 2004) [#14]
Here's the smallest test I could find of mine, this is for a mesh using world space normal mapping.

EntityLight will be of most use to you, it allows you to set the right entityColor based on both the lights position and the actual meshes orietnation. (It does this by projecting the light into object space first)

Get rob's normal mapping demo for a compatible mesh/normal map. You can then compare it with your mesh in the test below to help pin-point any probs with your own normal maps.

Graphics3D 640,480,16,2:HidePointer
SetBuffer BackBuffer():MoveMouse 320,240
;load And prep mesh For mapping
	
	ta =LoadMesh("3d/a.b3d") ;load mesh
	ScaleMesh ta,1,1,1 ;This is specific to the statue rob used. Remove or adjust for alternative media.
	;nm=LoadTexture("normal.png") ;Normal map. If using rob's statue, it's the same one he used.
	nm=LoadTexture("3d/n2.png")
	t2=LoadTexture("3d/diffusemap.png")
	t1=LoadTexture("t1.jpg")
	
	;TextureBlend nm,4 ;dot3 blendng
	EntityTexture ta,nm,0,0 ;set as base texture.
	EntityTexture ta,t2,0,1
	TextureBlend nm,4
	TextureBlend t2,3
	HideEntity ta
      num=40 ;number of statues/meshes
      for tv=1 To num
      	ti=CopyEntity(ta)
      	RotateEntity ti,0,Rnd(160),0
	      PositionEntity ti,Rnd(-1000,1000),15,Rnd(-1000,1000)
      	h.h=New h
      	h\id=ti
      Next

;-
Type h
	Field id
End Type
AntiAlias False
Dither False
;-
	
;-end of bump-mapping prep.
	vcam=CreateCamera() 
  	cp=CreatePivot() ;just something for the camera to focus on
	PositionEntity cp,0,25,0
      lp=CreateSphere()
      FitMesh lp,-2,-2,-2,4,4,4
      PointEntity vcam,cp ;centre on the statue.
      PositionEntity vcam,0,15,-120
      PointEntity vcam,cp
      p=CreatePlane()
      EntityTexture p,t1
      ScaleTexture t1,10,10
      AmbientLight 128,128,128

Repeat
 
	xa#=xa+0.2
	If MouseDown(2) PositionEntity lp,EntityX(vcam),EntityY(vcam)+5,EntityZ(vcam)
	If MouseDown(1) PositionEntity lp,Cos(xa)*60,15,Sin(xa)*60
	fr=fr+1
	
	ms=MilliSecs()
	If ms>ls
	   ls=ms+1000
	  fps=fr
	fr=0
	EndIf
	
      TurnEntity vcam,MouseYSpeed(),-MouseXSpeed(),0
	RotateEntity vcam,EntityPitch(vcam),EntityYaw(vcam),0
	MoveMouse 320,240
	FlushMouse
	RenderWorld
	Text 10,10,fps
	
	If KeyDown(17) MoveEntity vcam,0,0,0.3
	If KeyDown(31) MoveEntity vcam,0,0,-0.3
	If KeyDown(30) MoveEntity vcam,-0.3,0,0
	If KeyDown(32) MoveEntity vcam,0.3,0,0
	
	
	For h.h=Each h
		entitylight( h\id,lp) 
	Next
	
	Text 1,30,"Tris>"+TrisRendered() 
	Text 1,45,fps
	Flip False
Until KeyDown(1)

Function entityLight(entity,light) ;call every frame.
	ox=EntityX(light)
	oy=EntityY(light)
	oz=EntityZ(light)
	TFormPoint ox,oy,oz,light,entity
	PositionEntity light,TFormedX(),TFormedY(),TFormedZ() ;Transpose light into 
	dx# =EntityX(light)-EntityX( entity)
	dy# =EntityY(light)-EntityY( entity)
	dz# =EntityZ(light)-EntityZ( entity)
	nl#=Sqr(dx*dx+dy*dy+dz*dz)
	nx#=dx/nl
	ny#=dy/nl
	nz#=dz/nl
	nl=(255-nl)/255.0 ;fall off. 
	nl=1-nl
	If nl>1 nl=1
	If nl<0 nl=0
	nx=nx*nl
	ny=ny*nl
	nz=nz*nl
	EntityColor entity,128+(128*nx),128+(128*nz),128+(128*ny)
	PositionEntity light,ox,oy,oz ;return light.
End Function 



MadMunky(Posted 2004) [#15]
Right a slight problem

These pictures are from a program called DotMyBot which we tryed to work from but got the problem of the dark walls

With Normal Map


Without Normal Map


These ones are from the code you did above, and they dont look really like they have normal maps more like reflective.

With Normal Map


Without Normal Map


Any ideas :)


AntonyWells(Posted 2004) [#16]
Heh, nope, works fine with Rob's statue.

Can't test it atm, stuck using a Voodoo5 until my g5 gets here from PcWorld. soz ;)


MadMunky(Posted 2004) [#17]
Whats robs statue that your talking about?


MadMunky(Posted 2004) [#18]
Right heres a file with the problem we have including source if anyone can fix it it would be a massive help!

http://www.dungeon-maker.com/uploader/uploads/bump/bump.rar


AntonyWells(Posted 2004) [#19]
rob's statue is a pictureesque statue he had scholars of italian fine art produce of him, so he could bask in the glory of Rob all day long.
Well, not really, it's a statue baked with a normal map he used in his demo. check his sig.


MadMunky(Posted 2004) [#20]
when i tried robs statue with the code you gave me, the model is massive and it doesnt look like its bump maped :(


AntonyWells(Posted 2004) [#21]
Well wait a few days until my g5 gets here, I can't imagine why it's not working anymore. It worked on a g3 too 'cos I sent tests to evak and they worked fine..so unless you have a really old card it should work..


MadMunky(Posted 2004) [#22]
I have a ati radeon 9000m


MadMunky(Posted 2004) [#23]
Dont suppose anyone else out there know where i can get a demo on how to do normal maps which includes the source?

How come rob didnt release his source? (That would be handy)


AntonyWells(Posted 2004) [#24]
Yeah, as it goes search on blitzcoder.com's forums. I posted the source code to Rob's demo.(I.e I emulated what he did, not his actual code)


Genexi2(Posted 2004) [#25]
Well, dunno if its me, but Rob's statue demo had no detailed texture like your stone wall correct? I just remember it being a grey model with a nice lighting job applied to it.....


Rob(Posted 2004) [#26]
*hic*


Floyd(Posted 2004) [#27]
This is exactly why Blitz3D normal/bump mapping is so limited.

The bump texture encodes normals in world space, not local or tangent space.
Even though the cube uses the same texture on all six sides the normal map is correct for only one of them.

For example, suppose it is correct for the front face.
When the same bump map is applied to the back face the normals point into the cube.

You need a separate bump map for each side.


AntonyWells(Posted 2004) [#28]
It's not limited, it's identical to how you'd do it in C++ or whatever imo.
You just have to do tangant mapping, i.e instead of a universal entityColor job, you have calc it per-tri which involves transforming the light into tri(Tangant) space. and painting the vert colors with this.
There's nothing to stop anyone doing this in blitz.
This is the slowest but best method.

Or option 2, you spread the normal map across six faces,(I.e each face has a unique direction)..this isn't as nice though, only of use on things like rob's statue, and is the method I posted above. This much easier, faster but not as nice.


MadMunky(Posted 2004) [#29]
Can anyone explain how i would add the more normal maps i.e. 4 for each side (Dont worry about top and bottom) using the code I have above :)


MadMunky(Posted 2004) [#30]
So has no one worked out how to apply a normal map to a cube?


MadMunky(Posted 2004) [#31]
Not quite sure what i did but this seems to work :)

www.dungeon-maker.com/uploader/uploads/bump/bumpupdated.rar

Just in case anyone want to use it.


MadMunky(Posted 2004) [#32]
Forget that, I really dont get this. I can rotate the cube and its fine all sides work not problems, but when u move the camera you get the dark sides, so surely it means theres something funny with the light code which isnt making the light follow the camera correctly


MadMunky(Posted 2004) [#33]
Right Update: I will get this sorted some how.

I changed the code so that I could freely move each object.

1. If i rotate the cube with the light and camers staying still it works fine. The normal maps are fine on each side of the cube.

2. I move the camera and not the cube I get dark patchs

3. I moved the camera and the light source, but i still get dark patchs!!

What is the difference between moving the cube and moving the camera/light?


MadMunky(Posted 2004) [#34]
Should i give up?


TartanTangerine (was Indiepath)(Posted 2004) [#35]
Never give up.. "The Answer is out there...."