Anyone have a func to tangent normal map verts?

Blitz3D Forums/Blitz3D Programming/Anyone have a func to tangent normal map verts?

JoshK(Posted 2004) [#1]
This gives bad and evil and horrible results. Does anyone have a function to adjust vertex colors according to the normal, to display a regular bump map on walls?

I think the blue value controls the lightness/darkness of the surface, and the red and green values control the x/y vector. However, I can't translate this into results that looks like anything.

Function NormalMapMesh(mesh,recursive=True)
temp=CreatePivot()
RotateEntity temp,45,35,0
If EntityClass(mesh)="Mesh"
	For s=1 To CountSurfaces(mesh)
		surf=GetSurface(mesh,s)
		For v=0 To CountVertices(surf)-1
			TFormNormal VertexNX(surf,v),VertexNY(surf,v),VertexNZ(surf,v),mesh,temp
			r=1.0-(TFormedX())*128.0+128.0
			g=(TFormedY())*128.0+128.0
			b=(TFormedZ())*128.0+128.0
			VertexColor surf,v,r,g,b,VertexAlpha(surf,v)
			Next
		Next
	EndIf
If recursive
	For c=1 To CountChildren(mesh)
		normalmapmesh GetChild(mesh,c),True
		Next
	EndIf
FreeEntity temp
End Function



JoshK(Posted 2004) [#2]
Wooooo, got it. I had to switch the x and y values (weird!).

Here is the result:


My wannabee Doom texture:

Normal map:


"Diffuse" map, to give it a little more shading:


And the texture map:


And the code:
Function NormalMapMesh(mesh,recursive=True)
temp=CreatePivot()
RotateEntity temp,45,45,0
If EntityClass(mesh)="Mesh"
	For s=1 To CountSurfaces(mesh)
		surf=GetSurface(mesh,s)
		For v=0 To CountVertices(surf)-1
			TFormNormal -VertexNX(surf,v),VertexNY(surf,v),VertexNZ(surf,v),mesh,temp
			r=255.0-128.0*(TFormedY()+1.0)
			g=255.0-128.0*(TFormedX()+1.0)
			b=255.0-128.0*(TFormedZ()+1.0)
			VertexColor surf,v,r,g,b,VertexAlpha(surf,v)
			Next
		Next
	EndIf
If recursive
	For c=1 To CountChildren(mesh)
		normalmapmesh GetChild(mesh,c),True
		Next
	EndIf
FreeEntity temp
End Function



AntonyWells(Posted 2004) [#3]
Blitz has a tformnormal func? I had no idea you could use it to do tangant mapping...Does it work across uneven meshes with tiling normal maps?


Matty(Posted 2004) [#4]
I can notice the effect of normal mapping with Rob's demo with the statue but I have never been able to notice anything different with walls textured with a normal map as opposed to a regular texture? What am I supposed to be looking for?


JoshK(Posted 2004) [#5]
It really takes a full room to see the effect properly. Basically, the highlights you see on the texture aren't drawn on the texture, and can be drawn dynamically from any angle. Look at some of the Doom 3 screenshots in the off-topic thread, and you'll notice that textures on a wall appear different, based on their position relative to a light. The quality of the bumpmaps in Doom 3 is, amazingly, the same as th crappy textures I drew up today. Look at the dsark panel pieces in the shot above. One is lit from the left, one from the right. I did NOT just flip the texture.

Again, I think this is something that you have to create a full room with before you can really appreciate the effect.


Matty(Posted 2004) [#6]
Fair enough, I guess that it would be more noticeable if the light source was moving so that I could see the highlights change with the light's motion.


AntonyWells(Posted 2004) [#7]
halo, i'm actuallying doing a game now I can test this code on. it's a crappy level I did myself in maplet, but the textures can be normal mapped in exploration..if you don't me using your code to do it? (I'll release it here)

Any luck getting lights to work with it? unless you're setting normals based on a light elsewhere in the code.


JoshK(Posted 2004) [#8]
Here is a more dramatic example. I am still having trouble getting all the normals mapped correctly. Some of the angles in this picture are wrong relative to the light source. There is no lighting in this scene, except for dot3.



JoshK(Posted 2004) [#9]



JoshK(Posted 2004) [#10]
Directional lights are easy, but I am still having problems getting a point light to work:

Function NormalMapMesh(mesh,x#=0,y#=0,z#=0)
If EntityClass(mesh)="Mesh"
	temp=CreatePivot()
	PositionEntity temp,x,y,s
	For s=1 To CountSurfaces(mesh)
		surf=GetSurface(mesh,s)
		For v=0 To CountVertices(surf)-1
			RotateEntity temp,0,0,0
			TFormPoint VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v),mesh,temp
			d#=PointDistance(TFormedX(),TFormedY(),TFormedZ(),0,0,0)
			range#=1024.0
			If d<range
				d#=Sqr((range-d)/range)
				b#=d*255
				Else
				b=0
				EndIf
			AlignToVector temp,TFormedX(),TFormedY(),TFormedZ(),3
			RotateEntity temp,EntityPitch(temp),EntityYaw(temp),EntityRoll(temp)
			TFormNormal VertexNX(surf,v),VertexNY(surf,v),VertexNZ(surf,v),mesh,temp
			r#=(1.0-TFormedX())*127.5
			g#=(1.0-TFormedY())*127.5
			If TFormedZ()>0 b=0
			VertexColor surf,v,r,g,b
			Next
		Next
	FreeEntity temp
	EndIf
For c=1 To CountChildren(mesh)
	normalmapmesh GetChild(mesh,c)
	Next
End Function



Rob(Posted 2004) [#11]
Good going man. Will you be the first to get doom 3 style visuals in Blitz?


JoshK(Posted 2004) [#12]
I think it's possible. I think you could even calculate geometric "stencil" shadows in real-time, and render them in a second pass. However, that's out of the scope of my WWII game, and I am not going to pursue it past just getting a point light source working.


AntonyWells(Posted 2004) [#13]
Halo, iirc one of the key aspects of tangent mapping is to map along the u,v vector. (I.e so the tangent conversation remains within texture space as needed, rather than just poly/tri space)
so you probably want to take that into account when updating the vertex colors.


JoshK(Posted 2004) [#14]
Actually, if I WERE doing Doom-style lighting, here is how I would do it:

1. Render the scene with the ambientlight set to, well, the ambientlight level you want. Color all vertices the equivalent of (128,128,255), corrected for the vertex normal.

2. Project shadows to and from every object in the room. This is not impossible, especially with the low-poly scenes Doom uses. Create a mesh from these "stencil" shadows.

3. For each light, calculate object vertex colors according to the light position. Use an additive blend on the walls of the map. Set the ambient light to the light's color. Render the scene, using your stencil mesh from step 2 to completely black out shadowed areas.

So you render one ambient pass, and one additional pass per light source.


sswift(Posted 2004) [#15]
.


JoshK(Posted 2004) [#16]
I can't really spend any more time on this. Here is a demo that uses a very small amount of code. Maybe someone else can play with it:
http://www.leadwerks.com/post/DOOM3BB.zip (57 kb)

Function NormalMapMesh(mesh,x#=-1,y#=-1,z#=1,style=0,range#=200)
If EntityClass(mesh)="Mesh"
	temp=CreatePivot()
	If style=0
		AlignToVector temp,x,y,z,3
		RotateEntity temp,EntityPitch(temp),EntityYaw(temp),0
		EndIf
	For s=1 To CountSurfaces(mesh)
		surf=GetSurface(mesh,s)
		For v=0 To CountVertices(surf)-1
			Select style
				;Directional light
				Case 0
					TFormNormal VertexNX(surf,v),VertexNY(surf,v),VertexNZ(surf,v),mesh,temp
					r#=(1.0-TFormedX())*127.5
					g#=(1.0-TFormedY())*127.5
					b#=(1.0-TFormedZ())*127.5
					If TFormedZ()>0
						r=127.5
						g=127.5
						b=0
						EndIf
				;Point light
				Case 1
					RotateEntity temp,0,0,0
					TFormPoint VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v),mesh,temp
					AlignToVector temp,TFormedX(),TFormedY(),TFormedZ(),3
					RotateEntity temp,EntityPitch(temp),EntityYaw(temp),0
					TFormNormal VertexNX(surf,v),VertexNY(surf,v),VertexNZ(surf,v),mesh,temp	
					r#=(1.0-TFormedX())*127.5
					g#=(1.0-TFormedY())*127.5
					b#=(1.0-TFormedZ())*127.5
					If TFormedZ()>0 b=0
					TFormPoint VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v),mesh,temp
					d#=PointDistance(TFormedX(),TFormedY(),TFormedZ(),0,0,0)
					If d<range
						d#=Sqr((range-d)/range)
						b#=d*255
						Else
						r=127.5
						g=127.5
						b=0
						EndIf
				End Select
			VertexColor surf,v,r,g,b
			Next
		Next
	FreeEntity temp
	EndIf
For c=1 To CountChildren(mesh)
	normalmapmesh GetChild(mesh,c)
	Next
End Function



Jeroen(Posted 2004) [#17]
function pointDistance is not in the zip


JoshK(Posted 2004) [#18]
Ah:

Function PointDistance#(Ax#,Ay#,Az#,Bx#,By#,Bz#)
Return Sqr((ax-bx)^2.0+(ay-by)^2.0+(az-bz)^2.0)
End Function


JoshK(Posted 2004) [#19]
Is anyone playing with this? It's quite possible that my normals maps could be f***ed as well.


Dreamora(Posted 2004) [#20]
[removed first posting, problem from my side]

I created a normal map out of your diffuse and it seems like yours is ok.

I read somewhere that point light are causing some problems in Dot3Bump ( don't know where exactly it was, I think there was a thread about this here in the boards with people discussing like FredBorg etc )