Outlining meshes

Blitz3D Forums/Blitz3D Programming/Outlining meshes

Nack(Posted 2008) [#1]
What I want to do is this, remember Maplet? Remeber how it have black outline thing around each mesh? I want something like that, not cel-shade. Just normal outline.

I tried searching it, but failed. Plus dun really know what to serach as I do not know what this is called.

Also, I never used it too much before so I never looked into it. but is CameraProject() very memory intensive?

Any ideas?


boomboom(Posted 2008) [#2]
-Get your object
-Duplicate it
-Scale it up 0.1 (the more your scale the thicker the blackness).
-Flip Normals
-Colour it black and apply fullbright entityfx


JustLuke(Posted 2008) [#3]
-Scale it up 0.1 (the more your scale the thicker the blackness).

Actually, to create a consistent outline, you need to scale each vertex of your duplicated mesh outward by a set amount rather than scaling the mesh itself. But even using this method, you'll get a very "dirty" looking outline that will appear thicker the closer the model gets to the camera.

I don't think that anyone has come up with a pretty method of outlining meshes in Blitz3d yet.


Ross C(Posted 2008) [#4]
If you get the vertex normal of each vertex, and project the meshes vertices outwards at that angle, you will get a perfect outline. Only probem is, your outline mesh will completely encompass the mesh. You could mess about with entityorder, rendering the mesh you want outlined, and it's outline in a seperate pass.

I think flip mesh, as boomboom said, would probably get around that problem actually

As boomboom said, the outlinemesh needs to be the colour you want, plus it needs the fullbright entityfx flag.

The above way should give you a perfect outline. Best to store the outlines for each mesh, so you only need to generate them once, then parent the outline to the mesh your outlining.

Obviously, if your animating your mesh, then you'll need to find a different way...


Ross C(Posted 2008) [#5]
On further thought, the greater the angle, the more you'll need to project the vertex outwards.


Ross C(Posted 2008) [#6]
Ok, here is a rough thing. I think sswift did something similar?

Arrow keys to move camera. press "1" to generate the outline.

Graphics3D 800,600
SetBuffer BackBuffer()

Global piv = CreatePivot()
Global camera = CreateCamera(piv)
PositionEntity camera,0,0,-10

light = CreateLight()

Global cube = Createtorus(5,1,10,5)


CameraClsColor camera,200,200,200

While Not KeyHit(1)

	If KeyHit(2) Then
		outline_mesh = create_outline(cube)
		UpdateNormals cube

	End If
	
	If KeyDown(200) Then RotateEntity piv,EntityPitch(piv)+1,EntityYaw(piv),0
	If KeyDown(208) Then RotateEntity piv,EntityPitch(piv)-1,EntityYaw(piv),0
	If KeyDown(203) Then RotateEntity piv,EntityPitch(piv),EntityYaw(piv)+1,0
	If KeyDown(205) Then RotateEntity piv,EntityPitch(piv),EntityYaw(piv)-1,0
	
	UpdateWorld
	RenderWorld
	Flip

Wend
End

Function create_outline(entity)

	Local outline = CopyMesh(entity,entity)

	Local surf = GetSurface(entity,1)
	Local verts = CountVertices(surf)
	
	Local dest_surf = GetSurface(outline,1)
	
	Local x#,y#,z#
	
	For loop = 0 To verts-1
	
		x = VertexX(surf,loop) + (VertexNX(surf,loop)*0.1)
		y = VertexY(surf,loop) + (VertexNY(surf,loop)*0.1)
		z = VertexZ(surf,loop) + (VertexNZ(surf,loop)*0.1)
		VertexCoords dest_surf,loop,x,y,z
		
	Next
	
	EntityColor outline,100,100,100
	EntityFX outline,1
	FlipMesh outline
	
	Return outline
	
End Function

Function CreateTorus(torrad#,torwidth#,segments,sides,parent=0)

	torusmesh=CreateMesh(parent)
	surf=CreateSurface(torusmesh)
	
	FATSTEP#=360.0/sides
	DEGSTEP#=360.0/segments

	radius#=0
	x#=0
	y#=0
	z#=0
	
	fat#=0
	Repeat
		radius = torrad + (torwidth)*Sin(fat)
		deg#=0
		z=torwidth*Cos(fat)
		Repeat
			x=radius*Cos(deg)
			y=radius*Sin(deg)
			AddVertex surf,x,y,z,x,y,z			
			deg=deg+DEGSTEP	
		Until deg>=360
		fat=fat+FATSTEP
	Until fat>=360
	
	For vert=0 To segments*sides-1
		v0=vert
		v1=vert+segments
		v2=vert+1
		v3=vert+1+segments
		
		If v1>=(segments*sides) Then v1=v1-(segments*sides)
		If v2>=(segments*sides) Then v2=v2-(segments*sides)
		If v3>=(segments*sides) Then v3=v3-(segments*sides)
		
		AddTriangle surf,v0,v1,v2
		AddTriangle surf,v1,v3,v2	
	Next
	
	UpdateNormals torusmesh

	Return torusmesh
End Function


Credit to BODYPRINT for the CreateTorus() function. Very simple to work. It works good on a mesh that is a closed mesh, as it uses vertex normals to project the outline. So, make sure there's no cracks :o)


Nack(Posted 2008) [#7]
I was looking more of a wireframe render. But this method DOES look good. I think I mite use this instead.

Thank a lot! =]


JustLuke(Posted 2008) [#8]
Don't forget that with this method your outlined models will have double their normal polygon count, the outlines will vary in relation to the models' distances from the camera, and animation becomes a little tricky.

It's one of those methods that seems to work, but once you use it you realise that it is a very ugly and impractical solution for anthing other than primitive, unanimated shapes that do not vary their distance from the camera. There's got to be a better method, I'm sure.


Ross C(Posted 2008) [#9]
Yeah, shapes with holes in them are a little funny. And anything unwelded really looks strange. Just keep the outline small.

I'm not sure any other way is possible in blitz tbh. It's a job for shaders surely?

Another method, for higher poly meshes, is to use a sphereical reflection map. Since anything at the edges of the sphere map, just mapped to the outside of the mesh, you can paint this black and it will give the mesh a black outline.

It doesn't work very well with sharp corners and low poly meshes. Benefit here, is you can use it on animated meshes, and it doesn't add to the poly count/surface count.


boomboom(Posted 2008) [#10]
as far as I know those are the only 2 mothods Ross, The dupe/scale/flip and the sphere map.


Stevie G(Posted 2008) [#11]
For all shapes ... copy the mesh, weld it and use the inbuilt updatenormals function prior to fliping and extruding the normals. This'll give you a better outline for sharper edges.

If you want wireframe, there are plenty of examples in the code archives and you can search the other forums.