DOT3 vertex colors with texcoords

Miscellaneous Forums/General Discussion/DOT3 vertex colors with texcoords

There are a great many routines floating around this forum to handle DOT3 vertex colors, but they aren't completely correct. You have to consider the mapping axes of the vertex, or which direction the texture is laid onto the surface. If the normal map is flipped, the results are going to be different.

Since my brushes from 3D World Studio already use mapping axes, I can correctly normal map my static world quite easily. However, triangle meshes are proving to be more difficult, because their mapping axes must be extrapolated from arbitrary texture coordinates. This is where I am having a problem.

The first step would be to go through all the triangles in the mesh and calculate mapping axes for each vertex in the triangle:
	Method BuildMappingAxes()
		For t=0 To indicearray.size()/6-1
			a=PeekShort(indicearray,t*6+0)
			b=PeekShort(indicearray,t*6+2)
			c=PeekShort(indicearray,t*6+4)
			Ax#=PeekFloat(vertexarray,a*12+0)
			Ay#=PeekFloat(vertexarray,a*12+4)
			Az#=PeekFloat(vertexarray,a*12+8)
			Bx#=PeekFloat(vertexarray,b*12+0)
			By#=PeekFloat(vertexarray,b*12+4)
			Bz#=PeekFloat(vertexarray,b*12+8)
			Cx#=PeekFloat(vertexarray,c*12+0)
			Cy#=PeekFloat(vertexarray,c*12+4)
			Cz#=PeekFloat(vertexarray,c*12+8)
			Au#=PeekFloat(texcoordarray,a*8+0)
			Av#=PeekFloat(texcoordarray,a*8+4)
			Bu#=PeekFloat(texcoordarray,b*8+0)
			Bv#=PeekFloat(texcoordarray,b*8+4)
			Cu#=PeekFloat(texcoordarray,c*8+0)
			Cv#=PeekFloat(texcoordarray,c*8+4)
			TrianglePlane(ax,ay,az,bx,by,bz,cx,cy,cz)
			nx#=TFormedX()
			ny#=TFormedY()
			nz#=TFormedZ()
		Next
	EndMethod

Then you have to figure out what direction the U and V vectors point. Anyone have any code to help me complete this?

Once I get the mapping axes, everything else is ready and working.


Sweet, I got it working. To use this in Blitz3D, you need to get the dotproduct of the light vector and the vertex mapping axis for U and V, to determine the vertex red and green colors, respectively.



	Method BuildMappingAxes()
		mappingaxeschanged=False
		mappingaxisarray=CreateBank(vertexarray.size()*2)
		For t=0 To indicearray.size()/6-1
			a=PeekShort(indicearray,t*6+0)
			b=PeekShort(indicearray,t*6+2)
			c=PeekShort(indicearray,t*6+4)
			v1x#=PeekFloat(vertexarray,a*12+0)
			v1y#=PeekFloat(vertexarray,a*12+4)
			v1z#=PeekFloat(vertexarray,a*12+8)
			v2x#=PeekFloat(vertexarray,b*12+0)
			v2y#=PeekFloat(vertexarray,b*12+4)
			v2z#=PeekFloat(vertexarray,b*12+8)
			v3x#=PeekFloat(vertexarray,c*12+0)
			v3y#=PeekFloat(vertexarray,c*12+4)
			v3z#=PeekFloat(vertexarray,c*12+8)
			w1x#=PeekFloat(texcoordarray,a*8+0)
			w1y#=PeekFloat(texcoordarray,a*8+4)
			w2x#=PeekFloat(texcoordarray,b*8+0)
			w2y#=PeekFloat(texcoordarray,b*8+4)
			w3x#=PeekFloat(texcoordarray,c*8+0)
			w3y#=PeekFloat(texcoordarray,c*8+4)
			
	        x1:Float=v2x-v1x
	        x2:Float=v3x-v1x
	        y1:Float=v2y-v1y
	        y2:Float=v3y-v1y
	        z1:Float=v2z-v1z
	        z2:Float=v3z-v1z
	        
	        s1:Float=w2x-w1x
	        s2:Float=w3x-w1x
	        t1:Float=w2y-w1y
	        t2:Float=w3y-w1y

			r:Float=1.0/(s1*t2-s2*t1)
			
			sx:Float=(t2*x1-t1*x2)*r
			sy:Float=(t2*y1-t1*y2)*r
            sz:Float=(t2*z1-t1*z2)*r
			tx:Float=(s1*x2-s2*x1)*r
			ty:Float=(s1*y2-s2*y1)*r
			tz:Float=(s1*z2-s2*z1)*r
			
			Normalize(sx,sy,sz)
			sx=VectorX()
			sy=VectorY()
			sz=VectorZ()

			Normalize(tx,ty,tz)
			tx=VectorX()
			ty=VectorY()
			tz=VectorZ()

			PokeFloat mappingaxisarray,a*24+0,sx
			PokeFloat mappingaxisarray,a*24+4,sy
			PokeFloat mappingaxisarray,a*24+8,sz
			PokeFloat mappingaxisarray,a*24+12,tx
			PokeFloat mappingaxisarray,a*24+16,ty
			PokeFloat mappingaxisarray,a*24+20,tz
			
			PokeFloat mappingaxisarray,b*24+0,sx
			PokeFloat mappingaxisarray,b*24+4,sy
			PokeFloat mappingaxisarray,b*24+8,sz
			PokeFloat mappingaxisarray,b*24+12,tx
			PokeFloat mappingaxisarray,b*24+16,ty
			PokeFloat mappingaxisarray,b*24+20,tz
			
			PokeFloat mappingaxisarray,c*24+0,sx
			PokeFloat mappingaxisarray,c*24+4,sy
			PokeFloat mappingaxisarray,c*24+8,sz
			PokeFloat mappingaxisarray,c*24+12,tx
			PokeFloat mappingaxisarray,c*24+16,ty
			PokeFloat mappingaxisarray,c*24+20,tz

		Next
	EndMethod


Just to help, here is a bit of my engine code that calculates the vertex colors:
					Case CLASS_POINTLIGHT
						'If lightaffectsface(light,Self)
							For v=0 To vertexarray.size()/12-1
								x#=PeekFloat(vertexarray,v*12+0)
								y#=PeekFloat(vertexarray,v*12+4)
								z#=PeekFloat(vertexarray,v*12+8)
								If pointdistance(lpx,lpy,lpz,x,y,z)<light.range
									mappingaxisu.x=PeekFloat(mappingaxisarray,v*24+0)
									mappingaxisu.y=PeekFloat(mappingaxisarray,v*24+4)
									mappingaxisu.z=PeekFloat(mappingaxisarray,v*24+8)
									mappingaxisv.x=PeekFloat(mappingaxisarray,v*24+12)
									mappingaxisv.y=PeekFloat(mappingaxisarray,v*24+16)
									mappingaxisv.z=PeekFloat(mappingaxisarray,v*24+20)
									normalize x-lpx,y-lpy,z-lpz
									lx#=+vectorx()
									ly#=+vectory()
									lz#=+vectorz()
									vertexdx[v]=vertexdx[v]-dotproduct(mappingaxisu.x,mappingaxisu.y,mappingaxisu.z,lx,ly,lz)
									vertexdy[v]=vertexdy[v]-dotproduct(mappingaxisv.x,mappingaxisv.y,mappingaxisv.z,lx,ly,lz)
									vertexinfluences[v]=vertexinfluences[v]+1
								EndIf
							Next
						'EndIf
					Case CLASS_SUNLIGHT
						tformnormal 0,0,1,light,entity
						lx#=tformedx()
						ly#=tformedy()
						lz#=tformedz()
						For v=0 To vertexarray.size()/12-1
							nx#=PeekFloat(normalarray,v*12+0)
							ny#=PeekFloat(normalarray,v*12+4)
							nz#=PeekFloat(normalarray,v*12+8)
							mappingaxisu.x=PeekFloat(mappingaxisarray,v*24+0)
							mappingaxisu.y=PeekFloat(mappingaxisarray,v*24+4)
							mappingaxisu.z=PeekFloat(mappingaxisarray,v*24+8)
							mappingaxisv.x=PeekFloat(mappingaxisarray,v*24+12)
							mappingaxisv.y=PeekFloat(mappingaxisarray,v*24+16)
							mappingaxisv.z=PeekFloat(mappingaxisarray,v*24+20)
							If dotproduct(lx,ly,lz,nx,ny,nz)<0.0
								vertexdx[v]=vertexdx[v]-dotproduct(mappingaxisu.x,mappingaxisu.y,mappingaxisu.z,lx,ly,lz)
								vertexdy[v]=vertexdy[v]-dotproduct(mappingaxisv.x,mappingaxisv.y,mappingaxisv.z,lx,ly,lz)
								vertexinfluences[v]=vertexinfluences[v]+1
							EndIf
						Next


You would then do something like this:
VertexColor surface,v,vertexdx[v]*128.0+128.0,vertexdy[v]*128.0+128.0

More fun with bumpmaps. I guess the big deal here is the fact that I got them to work correctly on all objects. Bumpmapping is one of those things you can half-ass pretty easily, but it is hard to really complete.

Texture only:


Texture+bumpmap:


Wow, very cool. This is something I'd personally love to impliment (I've been looking into it recently), but I'm somewhat of a beginner and not completely sure where to start.

Feel like teaching me? ;)

Give this code to Fredborg or Swift or someone, and they will implement it in B3D.

I don't know who those guys are but... okay, I'll kick up a fuss and see what I can do...