Log In  


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

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.

-ElectricGryphon

16


That is a pretty fox statue.


The opening Star Fox games should have had. xD


Coloured lighting, and shading. Amazing...


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


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
http://www.thingiverse.com/thing:937740

For importing the model, I used Blender (free! As in beer.)
https://www.blender.org/

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: ''

www.blender.org

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.


vertex_list={
{62.739700,37.261948,6.975784},
{65.733696,26.264952,-0.733215},
{59.460701,17.558954,7.602791},
...
face_list={
{1,2,3},
{1,4,5},
{3,4,1},
...


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?


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.


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


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


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?


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.


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!


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.


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.



[Please log in to post a comment]