Flat Lighting - ZackWilde27/Z3dPy GitHub Wiki

Say we have this basic Raster pipeline:

for tri in zp.Raster():
    nrm = z3dpy.TriGetNormal(tri)
    zp.PgDrawTriF(tri, nrm[2], screen, pygame)

Creating Lights

Lights will need to be created at the start of the script, and added to the internal list like so:

# Light_Point(vPos, FStrength, fRadius, *vColour)
myLight = z3dpy.Light_Point([0.0, 0.0, 0.0], 0.8, 5.0, (255, 0, 0))

# or

# Light_Sun(vRot, FStrength, unused, *vColour)
myLight = z3dpy.Light_Sun((45.0, 0.0, 0.0), 0.8, 0, (255, 0, 0))


z3dpy.lights.append(myLight)

In 0.2.8, worldColour has been introduced, which is the ambient lighting. It's normalized so white is [1.0, 1.0, 1.0]

z3dpy.worldColour = (0.1, 0.2, 0.3)

Baking

If there are Things that won't move, lighting can be baked to get the same look for cheap.

Call BakeLighting() after creating the lights

zp.lights.append(myLight)

z3dpy.BakeLighting()

# or

# BakeLighting(thingList, *bExpensive, *lightList, *shadowcasters)
z3dpy.BakeLighting([myThing, myOtherThing], False, [myLight])
  • bExpensive

Wether or not to cast rays and check for collisions to create shadows (although it's flat-lit so results will be mixed)

  • lightList

The list of lights being taken into account. By default, it's the z3dpy.lights list.

  • shadowcasters

The list of Things to check against shadow rays. Not used if bExpensive is False, by default it's the same as thingList


# BakeLighting(*thingList, *bExpensive, *lightList, *shadowcasters)
z3dpy.BakeLighting([myThing, myOtherThing], True, [myLight], [myOtherThing])

Keep in mind, flat-lit shadows may look strange in certain cases.

Drawing

When drawing tris, use DrawTriFL() or DrawTriFLB()

for tri in z3dpy.Raster():

    # Dynamic Lighting
    z3dpy.PgDrawTriFL(tri, screen, pygame)

    # Baked Lighting
    z3dpy.PgDrawTriFLB(tri, screen, pygame)

Doing it manually

To do lighting calculations manually, use CheapLighting() or ExpensiveLighting()

# CheapLighting(tri, *lightList)
lighting = z3dpy.CheapLighting(tri, [myLight])

# or

# ExpensiveLighting(tri, *lightList, *shadowcasters)
lighting = z3dpy.ExpensiveLighting(tri, [myLight])

# It doesn't account for the tri's colour, so it needs to be multiplied.

triColour = z3dpy.VectorMul(z3dpy.TriGetColour(tri), lighting)

Now plug the final colour directly into your drawing function. Some modules may require a VectorFloor() to keep things integer-only.

z3dpy.PgDrawTriRGB(tri, triColour, screen, pygame)

Baked Lighting is just retrieving the baked lighting stored in the triangle.

lighting = z3dpy.TriGetShade(tri)

Aside from that, same as dynamic

triColour = z3dpy.VectorMul(z3dpy.TriGetColour(tri), lighting)
z3dpy.PgDrawTriRGB(tri, triColour, screen, pygame)