cell shading fx

Blitz3D Forums/Blitz3D Beginners Area/cell shading fx

Pete Carter(Posted 2006) [#1]
ive seen people get cell shading effects in blitz 3d can anyone give me an example of how to pull this off. im doing a transformers game and cell shading would make it look just like the cartoon which would be great!

before anyone says look in the code archives i have and they all seam to copy the mesh and colour it black to give black out lines which is slow and really quite ugly. i have quite dtailed model running around so copying them all for a cell effect wouldnt work. any ideas anyone?


jhocking(Posted 2006) [#2]
Can you point out an example where you don't think it's ugly? That's pretty much the way to do the outlines for cel shading: copy the mesh, push out the vertices, invert the normals, and color the copy black.

Incidentally, note that that's just the black outlines. For the actual shading, you'll want to use spherical environment mapping.


Ross C(Posted 2006) [#3]
You can get the blck outlines, simply by using spherical enviroment mapping. Create a texture, with a white circle, just nearly touching the edges of the texture, with the rest of the texture black. Apply it as a spherical enviroment map, and your sorted.


Pete Carter(Posted 2006) [#4]
thanks ill try it out! :O)


QuickSilva(Posted 2006) [#5]
Hey Pete, how about creating a worklog for your Transformers game?

Jason.


Stevie G(Posted 2006) [#6]
I've never tried that before Ross C! Got a picture of the results? Hopefully it'll look better than the flipmesh thing.

Stevie


Ross C(Posted 2006) [#7]
Well, it works well if the mesh doesn't have sharp, highly angled polygons. Limme see if i can dig it out :o)

The idea behind this, is that sphere maps, basically map the texture onto an entity, like a sphere. Whatever is on the very outside of the texture, will be closest to the outside of the mesh.


Ross C(Posted 2006) [#8]
www.rosscrooks.pwp.blueyonder.co.uk/celshaded.zip

The texture used is the spherical enviroment one. The thickness of the black circle, will be the thickness of the outline. To make it thinner, make sure the black cicle still touches the outside of the textures edges.


Baystep Productions(Posted 2006) [#9]
ACTUALY there was a code archive entry invlolving copying the entity using vertex morphing to scale it perfectly a little bigger, and coloring it all black. Oh not to mention some funny EntityFX settings and Flip Mesh. It works okay, but this seems better.


Shifty Geezer(Posted 2006) [#10]
The downside to a spherical map is that it maps to the surface according to angle of surface relative to the camera, and colours it black (or whatever outline effect you have). So if you have a long surface tilted slightly away from the camera, say looking along a car bonnet so the front of the bonnet is in the middle of the screen and the back of the bonnet, under the windscreen, is a little way higher than the midpoint of the screen, the whole bonnet is black. You also tend not to get a uniform outline.

If you replace the sphere in Ross's example with a cube or cylinder, you can see this problem clearly. If applied to a 'human character', front on it works, but if the character is lying down it doesn't.

The only really effective way is to use an inverted outline mesh, or use OpenGL!


jhocking(Posted 2006) [#11]
If you replace the sphere in Ross's example with a cube or cylinder, you can see this problem clearly. If applied to a 'human character', front on it works, but if the character is lying down it doesn't.

Or, for that matter, seeing a standing character from the side. This is exactly the problem. I know about the spherical map thing, which is largely why I referred to spherical mapping for the shading. However, for the outlines I do the inverted mesh thing. Look in the gallery for a screenshot of my current project.


SoggyP(Posted 2006) [#12]
Hello.

I know jack about 3d but to solve the above problem re spherical shading couldn't you somehow rotate the texture on the object so that it always points towards the camera in the same way?

Goodbye.


SoggyP(Posted 2006) [#13]
Hello.

And if not, why not? Dammit!

Goodbye.


jhocking(Posted 2006) [#14]
The whole point of a spherical map is that it always points towards the camera, so nothing to do there. Thing is, it distorts to fit the mesh's shape. Applied to a sphere it won't distort of course, but on any other shape the texture smooshes around.


SoggyP(Posted 2006) [#15]
Hello.

Jack sends his regards :o)

Goodbye.


Baystep Productions(Posted 2006) [#16]
Yes like I said there is a code archive example of what you are talking about. It is only one function. Here is a repost of the code.

Original post by sswift
Function Cel_Shade(Shaded_Entity, OutlineScale#=0.025)


	; Copy the entity's mesh.		
	Outline_Entity = CopyMesh(Shaded_Entity) 		
						
	; Update the vertex normals so that all surfaces are smoothed between.  We can't have normals at corners
	; which point in diffrent directions for each face or the outline will have cracks.
	UpdateNormals Outline_Entity 
			
	; Disable lighting & fog.
	EntityFX Outline_Entity, 1+8
	
	
	; Loop through all surfaces.
	Surfaces = CountSurfaces(Outline_Entity)
	For LOOP_Surface = 1 To Surfaces

		Surface_Handle = GetSurface(Outline_Entity, LOOP_Surface)
	
		; Loop through all vertices in this surface.				
		Verts = CountVertices(Surface_Handle) - 1
		For LOOP_Verts = 0 To Verts-1
			
			; Move the vertices out in the direction of the vertex normals, which now point inwards because
			; the mesh was inverted.  Move them by the distance specified in the shader this object uses.

			Vx#  = VertexX#(Surface_Handle, LOOP_Verts)
			Vy#  = VertexY#(Surface_Handle, LOOP_Verts)
			Vz#  = VertexZ#(Surface_Handle, LOOP_Verts)

			VNx# = VertexNX#(Surface_Handle, LOOP_Verts)
			VNy# = VertexNY#(Surface_Handle, LOOP_Verts)
			VNz# = VertexNZ#(Surface_Handle, LOOP_Verts)
										
			VertexCoords Surface_Handle, LOOP_Verts, Vx#+(VNx#*OutlineScale#), Vy#+(VNy#*OutlineScale#), Vz#+(VNz#*OutlineScale#)
				
		Next

	Next


	; Turn the mesh inside out.
	FlipMesh Outline_Entity
	
	; Set the entity to be black.
	EntityColor Outline_Entity, 0, 0, 0

	; Place the entity at the same location as the original entity.
	PositionEntity Outline_Entity, EntityX#(Shaded_Entity, True), EntityY#(Shaded_Entity, True), EntityZ#(Shaded_Entity, True)
	
	; Parent the outline to the original entity so it moves with it automatically.
	EntityParent Outline_Entity, Shaded_Entity


End Function



Play(Posted 2008) [#17]
really great function thx


Ben(t)(Posted 2008) [#18]
awesome function