Author Topic: Lighting Effect  (Read 1862 times)

0 Members and 1 Guest are viewing this topic.

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
Lighting Effect
« on: October 29, 2009 »
This is a nice lighting effect applied to a cube, It uses the surface normals to calculate the lighting.

Press up/down/left/right to move the light vertically/horizontally
Press triangle/cross to move the light in/out

Code: [Select]
//
// Demonstration of how to calculate lighting effects
// An improvement to this meathod would be to use a
// per vertex lighting algorithm
//
FALSE = 0
TRUE = 1
DEBUG = FALSE

label Init
    open window 640, 512
    window origin "cc"

    UP = 16
    RT = 32
    DN = 64
    LF = 128
    TR = 8192
    EX = 16384

label Vertices
    read verts
    dim px(verts), py(verts), pz(verts)
    dim nx(verts), ny(verts), nz(verts)
    dim tx(verts), ty(verts)
    for i = 0 to verts
        read px(i), py(i), pz(i)
    next i

label Polygons
    read polys
    dim p1(polys), p2(polys), p3(polys), p4(polys)
    for i = 0 to polys
        read p1(i), p2(i), p3(i), p4(i)
    next i

label Colours
    dim r1(polys), g1(polys), b1(polys)
    dim r2(polys), g2(polys), b2(polys)
    dim r3(polys), g3(polys), b3(polys)
    dim r4(polys), g4(polys), b4(polys)
    for i = 0 to polys
        read r1(i), g1(i), b1(i)
        read r2(i), g2(i), b2(i)
        read r3(i), g3(i), b3(i)
        read r4(i), g4(i), b4(i)
    next i

label Lighting
    litX = -64.0
    litY = -64.0
    litZ = -64.0
    Ambient = 0.1

label Camera
    camX = 0.0000
    camY = 0.0000
    camZ = -256.0
    Aspect = 512.0

label Loop
    c = peek("port1")
    if (and(c, UP) > 0) litY = litY - 1.0
    if (and(c, RT) > 0) litX = litX + 1.0
    if (and(c, DN) > 0) litY = litY + 1.0
    if (and(c, LF) > 0) litX = litX - 1.0
    if (and(c, TR) > 0) litZ = litZ + 1.0
    if (and(c, EX) > 0) litZ = litZ - 1.0
    rotX = rotX + 0.0100
    rotY = rotY + 0.0020
    rotZ = rotZ + 0.0003
    Rotate(rotX, rotY, rotZ, -camX,-camY,-camZ)
    Render()
    goto Loop

sub Rotate(rx,ry,rz, ox,oy,oz)
    local cx,cy,cz, sx,sy,sz, px,py,pz, nx,ny,nz, tx,ty,tz
    cx = cos(rx)
    sx = sin(rx)
    cy = cos(ry)
    sy = sin(ry)
    cz = cos(rz)
    sz = sin(rz)
    for i = 0 to verts
        px = px(i)
        py = py(i)
        pz = pz(i)
        nx = cz*px + sz*py
        ny = cz*py - sz*px
        nz = cy*pz + sy*nx
        tx = cy*nx - sy*pz
        ty = cx*ny + sx*nz
        tz = cx*nz - sx*ny
        nx(i) = tx
        ny(i) = ty
        nz(i) = tz
        tz = Aspect/(tz+oz)
        tx(i) = (tx+ox)*tz
        ty(i) = (ty+oy)*tz
    next i
end sub

sub Render()
    setdispbuf draw
    draw = 1 - draw
    setdrawbuf draw
    setrgb 1, 015, 015, 063
    setrgb 2, 015, 015, 063
    setrgb 3, 063, 063, 255
    gtriangle -320.0,256.00 to 320.00,256.00 to 320.00,-256.0
    setrgb 2, 063, 063, 255
    gtriangle -320.0,256.00 to -320.0,-256.0 to 320.00,-256.0
   
    //
    // Draw a white circle for the light
    if (litZ >= 0.0) then
        setrgb 1, 255, 255, 255
        lz = Aspect/(litZ-camZ)
        lx = litX*lz
        ly = litY*lz
        fill circle lx, ly, 10
    endif
   
    for i = 0 to polys
        x1 = tx(p1(i))
        y1 = ty(p1(i))
        x2 = tx(p2(i))
        y2 = ty(p2(i))
        x3 = tx(p3(i))
        y3 = ty(p3(i))
        x4 = tx(p4(i))
        y4 = ty(p4(i))
        cp = (x1-x2)*(y3-y2) - (x3-x2)*(y1-y2)
        if (cp > 0) then
            nx1 = nx(p1(i))
            ny1 = ny(p1(i))
            nz1 = nz(p1(i))
            nx2 = nx(p2(i))
            ny2 = ny(p2(i))
            nz2 = nz(p2(i))
            nx3 = nx(p3(i))
            ny3 = ny(p3(i))
            nz3 = nz(p3(i))
            nx4 = nx(p4(i))
            ny4 = ny(p4(i))
            nz4 = nz(p4(i))
            //
            // Calculate the midpoint of polygon
            cx = (nx1+nx2+nx3+nx4)*0.25
            cy = (ny1+ny2+ny3+ny4)*0.25
            cz = (nz1+nz2+nz3+nz4)*0.25
            //
            // Calculate the normal vector using cross-product
            nx = (nz1-nz2)*(ny3-ny2) - (ny1-ny2)*(nz3-nz2)
            ny = (nx1-nx2)*(nz3-nz2) - (nz1-nz2)*(nx3-nx2)
            nz = (ny1-ny2)*(nx3-nx2) - (nx1-nx2)*(ny3-ny2)
            //
            // Calculate the lighting vector
            lx = litX - cx
            ly = litY - cy
            lz = litZ - cz
            //
            // Calculate length of the normal & lighting vectors
            n = 1.0/sqrt(nx*nx + ny*ny + nz*nz)
            l = 1.0/sqrt(lx*lx + ly*ly + lz*lz)
            //
            // Normalise the normal & lighting vectors
            nx = n*nx
            ny = n*ny
            nz = n*nz
            lx = l*lx
            ly = l*ly
            lz = l*lz
            //
            // Calculate dot-product of normal & lighting vectors
            dp = max(Ambient, nx*lx + ny*ly + nz*lz + Ambient)
            //
            // Scale colour channels by dot-product
            setrgb 1, r1(i)*dp, g1(i)*dp, b1(i)*dp
            setrgb 2, r2(i)*dp, g2(i)*dp, b2(i)*dp
            setrgb 3, r3(i)*dp, g3(i)*dp, b3(i)*dp
            gtriangle x1, y1 to x2, y2 to x3, y3
            setrgb 2, r4(i)*dp, g4(i)*dp, b4(i)*dp
            gtriangle x1, y1 to x4, y4 to x3, y3
            //
            // Debug view of surface normals & midpoints
            if (DEBUG = TRUE) then
            pz = Aspect/(nz*60-camZ)
            py = ny*pz*60
            px = nx*pz*60
            cz = Aspect/(cz-camZ)
            cy = cy*cz
            cx = cx*cz
            setrgb 1, 255, 255, 000
            line cx, cy to px, py
            line x1, y1 to px, py
            line x2, y2 to px, py
            line x3, y3 to px, py
            line x4, y4 to px, py
            line x1, y1 to cx, cy
            line x2, y2 to cx, cy
            line x3, y3 to cx, cy
            line x4, y4 to cx, cy
            line x1, y1 to x2, y2
            line x2, y2 to x3, y3
            line x3, y3 to x4, y4
            line x4, y4 to x1, y1
            endif
        endif
    next i
    //
    // Draw a white circle for the light
    if (litZ < 0.0) then
        setrgb 1, 255, 255, 255
        lz = Aspect/(litZ-camZ)
        lx = litX*lz
        ly = litY*lz
        fill circle lx, ly, 10
    endif
    //
    // Display data
    setrgb 1, 255, 255, 255
    text -300,-240, "ROTX : " + str$(rotX)
    text -300,-220, "ROTY : " + str$(rotY)
    text -300,-200, "ROTZ : " + str$(rotZ)
    text -300,-180, "LITX : " + str$(litX)
    text -300,-160, "LITY : " + str$(litY)
    text -300,-140, "LITZ : " + str$(litZ)
end sub

label Model
    data 7 // verts
    data -30.0,30.00,30.00
    data -30.0,-30.0,30.00
    data -30.0,30.00,-30.0
    data -30.0,-30.0,-30.0
    data 30.00,30.00,30.00
    data 30.00,-30.0,30.00
    data 30.00,30.00,-30.0
    data 30.00,-30.0,-30.0
    data 5 // polys
    data 2,0,4,6
    data 7,5,1,3
    data 3,1,0,2
    data 6,4,5,7
    data 0,1,5,4
    data 3,2,6,7
    data 000,255,000, 255,000,000, 000,000,255, 200,200,200
    data 063,063,063, 255,000,255, 255,255,000, 000,255,255
    data 000,255,255, 255,255,000, 255,000,000, 000,255,000
    data 200,200,200, 000,000,255, 255,000,255, 063,063,063
    data 255,000,000, 255,255,000, 255,000,255, 000,000,255
    data 000,255,255, 000,255,000, 200,200,200, 063,063,063
 

Challenge Trophies Won:

Offline Wenlock

  • C= 64
  • **
  • Posts: 67
  • Karma: 4
  • BASIC & Testcards rule.
    • View Profile
Re: Lighting Effect
« Reply #1 on: October 31, 2009 »
Nice effect, I typed it on my clapped out PS2 from the DSi

Wenlock
YABASIC ROOLZ!

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17378
  • Karma: 497
  • evil/good
    • View Profile
    • My Homepage
Re: Lighting Effect
« Reply #2 on: November 02, 2009 »
That's a really nice example of how light sourcing should be done there Rainstorm, thanks for posting it :)

K+
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Galileo

  • ZX 81
  • *
  • Posts: 22
  • Karma: 0
    • View Profile
Re: Lighting Effect
« Reply #3 on: September 04, 2014 »
Hey! This is going to be very useful for me in the future.
Thanks!