Адрес: ул. Б. Очаковская 32 Москва Россия
Наши официальные канал и чат в telegram, группа в ВКонтакте

Демонстрация расчета световых эффектов

Улучшением этого метода было бы использование алгоритма повершинного освещения.

Библиотеки и примеры программ на языке Yabasic
Аватара пользователя
Anton
Site Admin
Сообщения: 137
Зарегистрирован: Чт фев 08, 2024 7:03 pm
Откуда: Москва

Демонстрация расчета световых эффектов

Сообщение Anton »

Демонстрация расчета световых эффектов
Листинг программы:

Код: Выделить всё

//
// Demonstration of how to calculate lighting effects
// An improvement to this meathod would be to use a
// per vertex lighting algorithm
//
// Adapted from PS2 version of Yabasic for Galileo 2014/09

DEBUG = FALSE

label Init
    clear screen
    open window 640, 512
    window origin "cc"
    backcolor 0,0,255

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

do
    c$ = inkey$(0.1)
    if c$="up" litY = litY - 1.0
    if c$="right" litX = litX + 1.0
    if c$="down" litY = litY + 1.0
    if c$="left" litX = litX - 1.0
    if c$="z" litZ = litZ + 1.0
    if c$="x" litZ = litZ - 1.0
    rotX = rotX + 0.0100
    rotY = rotY + 0.0020
    rotZ = rotZ + 0.0003
    Rotate(rotX, rotY, rotZ, -camX,-camY,-camZ)
    Render()
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()
    clear window
   
    // Draw a white circle for the light
    if (litZ >= 0.0) then
        color 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
            color min(abs(r1(i)*dp),255), min(abs(g1(i)*dp),255), min(abs(b1(i)*dp),255)
            fill triangle x1, y1 to x2, y2 to x3, y3
            fill triangle 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
            color 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
        color 255, 255, 255
        lz = Aspect/(litZ-camZ)
        lx = litX*lz
        ly = litY*lz
        fill circle lx, ly, 10
    endif
    //
    // Display data
    color 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
  
Демонстрация работы программы:
2025-05-16_17-45-26.gif
У вас нет необходимых прав для просмотра вложений в этом сообщении.