Log In  

Cart #19522 | 2016-04-01 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

A funny thing happened on the way to making an actual game.

I found this odd fox statue floating in between the bits and bytes. I hope it's not lonely.


P#19523 2016-04-01 02:05 ( Edited 2016-05-05 07:53)

That is a pretty fox statue.

P#19524 2016-04-01 02:53 ( Edited 2016-04-01 06:53)

The opening Star Fox games should have had. xD

P#19525 2016-04-01 04:25 ( Edited 2016-04-01 08:25)

Coloured lighting, and shading. Amazing...

P#19529 2016-04-01 09:13 ( Edited 2016-04-01 13:13)

What program are you using to build your 3d model(s) and how do you import them?

P#19530 2016-04-01 09:17 ( Edited 2016-04-01 13:17)

Hi BenWiley4000,

The fox is from thingverse, and I should have given the author proper credit:
Low Poly Fox
by slavikk, published Jul 22, 2015

For importing the model, I used Blender (free! As in beer.)

I exported the model as an .OBJ file, without vertex normals.
This is a very simple format that has a plain-text list of x,y,z vertices followed by a list of the vertices for each face.

# Blender v2.72 (sub 0) OBJ File: ''


mtllib church.mtl
o Cube
v 20.000000 -10.000000 -20.000000
v 20.000000 -10.000000 20.000000
v -20.000002 -10.000000 19.999996
usemtl Material
s off
f 2 3 4
f 22 7 6
f 5 21 6
f 2 6 7
f 7 22 8

With some automated search and replace, I was able to turn these into a standard Lua list format stored at the top of the code, which the program accesses directly.


P#19538 2016-04-02 00:35 ( Edited 2016-04-02 04:35)

Awesome, thanks! I don't imagine it would be too tough to reproduce, but if you have a format conversion script, care to share it?

P#19541 2016-04-02 02:52 ( Edited 2016-04-02 06:52)

Sadly, I have nothing so fancy as a python conversion script. I use Notepad++ and just recorded a macro for a couple of search and replaces in a row... "\n" to "},\n{" type of thing. Can't see a way to export it.

P#19543 2016-04-02 12:27 ( Edited 2016-04-02 16:27)

Is there a name for this type of shading? I really like the lines!

P#20130 2016-05-03 14:20 ( Edited 2016-05-03 18:20)

Should be fairly trivial to make a Blender export script that just dumps the lua like that. I might have a go at it =)

P#20133 2016-05-03 20:48 ( Edited 2016-05-04 00:48)

What? I don't get it. I thought the face drawing and shading is done by pico-8.
It just loads the vertices and the face vertices and then draws the faces with the right shading amount right?

For example "a half lighted polygon" which is black will consist out of white and black stripes 50:50.

Or I'm getting something wrong?

P#20141 2016-05-04 05:37 ( Edited 2016-05-04 09:37)

Hi Adge,

You've got it right.

I call it scan line shading for lack of a better word.

For the shading:
There's a table that contains two lists for each of the 16 colors. These control the color of an even line and the color of an odd line for each of (I think) 10 shades of lightness from black to the full color to white. When I radterize the triangles, I alternate between the two colors from line to line.

P#20146 2016-05-04 12:28 ( Edited 2016-05-04 16:28)

Thanks for that information. I'm trying to implement this look into a small love2d software renderer I made. Mostly because of learning purposes. For now there is just 3D to 2D projection a model loader which has some flaws and a "drag'n'rotate" function with some kinetic scrolling.

How did you do shading in general? I took a look at your code but code which isn't mine normally takes me days to get into.
I would just compare the lighting vector with the each normal vector of the object's faces. The more they are pointing at each other the brighter the face is drawn. Normal of a face with points a,b,c can be calculated through dot product of vector ab and ac right?

Is there also some resolution stuff going on? Like the farther the fox is away the less lines are drawn?
Man this looks so awesome!

P#20179 2016-05-04 18:56 ( Edited 2016-05-04 23:01)

Hi adge,

I am not necessarily doing the shading the "correct" way.
(see: https://www.tjhsst.edu/~dhyatt/supercomp/n310.html)

Instead, I am finding the normal for each triangle.
Then I am turning it into a unit vector (length 1).
Then I am setting the shade of the triangle based on a somewhat random yet pleasing combination of the normal vector components. (This is almost the same as performing a dot product on the vector...which is the proper approach.)

See the color_ faces() function:
nx,ny,nz = vector_cross_3d(...
nx,ny,nz = normalize(nx,ny,nz)
face_list[i][4],face_list[i][5]=color_shade(base, mid( (ny-nx+nz)/3+.2,0,.99) )

It's worth noting that my code for this particular demo is not especially pretty or well optimized.

P#20182 2016-05-05 01:57 ( Edited 2016-05-05 05:57)

Wow my intuitive approach to solve this problem wasn't that far away from how it should be done, assuming that the link you shared is the "correct" one.

I bet this is not how modern 3D games render their shaders. I tried to find some explanations but haven't found much valuable stuff.

P#20184 2016-05-05 03:53 ( Edited 2016-05-05 07:53)

[Please log in to post a comment]