-=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- (c) WidthPadding Industries 1987 0|577|0 -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- Socoder -> Retro Coding -> Raytracer on a Spectrum Thu, 25 Jan 2024, 02:08 Pakz Raytracer tutorial for zx spectrum basic (webpage) : Linkage Thu, 25 Jan 2024, 02:08 Jayenkai That looks like a fun project to rewrite in JSE!! Thu, 25 Jan 2024, 03:10 Jayenkai Version One Took a couple of little tweaks. I really do need to get Data/Read/Restore going, don't I!!? Dim Geom(100,10) GCount=4 Geom(1,0)=0 Geom(1,1)=0-1 Geom(1,2)=4 Geom(1,3)=1 Geom(1,4)=2 Geom(2,0)=2 Geom(2,1)=0 Geom(2,2)=4 Geom(2,3)=1 Geom(2,4)=1 Geom(3,0)=0-2 Geom(3,1)=0 Geom(3,2)=4 Geom(3,3)=1 Geom(3,4)=4 Geom(4,0)=0 Geom(4,1)=0-5001 Geom(4,2)=0 Geom(4,3)=5000 Geom(4,4)=6 Mode 1,"ZX",3 1 CLS 5 ROX = 0 6 ROY = 0 7 ROZ = 0 8 TMIN = 0 9 TMAX = 10000 10 FOR X = 0 TO 31 20 FOR Y = 0 TO 21 30 RDX = (X - 16) / 32 31 RDY = (11 - Y) / 32 32 RDZ = 1 40 GOSUB 1000 50 PAPER COL 51 Ink COL; Rect x*8,y*8,8.1,8.1 100 NEXT Y 105 GOSUB 3000: Ink 0; Rect 0,0,48,8;Ink 1;Locate 0,0; Print Time 110 NEXT X 120 end 1000 // ===== TraceRay ===== 1001 // Params: (ROX, ROY, ROZ): ray origin; (RDX, RDY, RDZ): ray direction; (TMIN, TMAX): wanted ranges of t 1002 // Returns: COL: pixel color 1010 COL = -1: MINT = 0 debugmode 1 1101 NS=GCount 1102 FOR S = 1 TO NS 1110 SCX=Geom(s,0) SCY=Geom(s,1) SCZ=Geom(s,2) SRAD=Geom(s,3) SCOL=Geom(s,4) 1200 COX = ROX - SCX 1201 COY = ROY - SCY 1202 COZ = ROZ - SCZ 1210 EQA = RDX*RDX + RDY*RDY + RDZ*RDZ 1211 EQB = 2*(RDX*COX + RDY*COY + RDZ*COZ) 1212 EQC = (COX*COX + COY*COY + COZ*COZ) - SRAD*SRAD 1220 DISC = EQB*EQB - 4*EQA*EQC 1230 IF DISC < 0 THEN GOTO 1500 1240 T1 = (-EQB + SQR(DISC)) / 2*EQA 1241 T2 = (-EQB - SQR(DISC)) / 2*EQA 1250 IF T1 >= TMIN AND T1 <= TMAX AND (T1 < MINT OR COL == -1) THEN COL = SCOL: MINT = T1 1300 IF T2 >= TMIN AND T2 <= TMAX AND (T2 < MINT OR COL == -1) THEN COL = SCOL: MINT = T2 1500 NEXT S 1999 IF COL == -1 THEN COL = 0 2000 RETURN 3000 //REM ===== Get timestamp in seconds ===== 3001 TIME=Mills(1) //TIME = (65536*PEEK 23674 + 256*PEEK 23673 + PEEK 23672) / 50 3002 RETURN -=-=- ''Load, Next List!'' Thu, 25 Jan 2024, 03:28 Pakz I was thinking of JSE when I noticed the tutorial pop up in my facebook feed. It was from the ''Spectrum for everyone' group. I was hoping to see it ported To busy myself at the moment. Thu, 25 Jan 2024, 04:12 Jayenkai Version Two Dim Geom(100,10) GCount=4 Geom(1,0)=0 Geom(1,1)=0-1 Geom(1,2)=4 Geom(1,3)=1 Geom(1,4)=6 Geom(2,0)=2 Geom(2,1)=0 Geom(2,2)=4 Geom(2,3)=1 Geom(2,4)=2 Geom(3,0)=0-2 Geom(3,1)=0 Geom(3,2)=4 Geom(3,3)=1 Geom(3,4)=18 Geom(4,0)=0 Geom(4,1)=0-5001 Geom(4,2)=0 Geom(4,3)=5000 Geom(4,4)=24 Graphics 320,240,3;SetFont "ZX";SetFontSize 8 1 CLS AI = 0.075 DI = 0.7 - AI LX = -1 LY = 1 LZ = 1 5 ROX = 0 6 ROY = 0 7 ROZ = 0 8 TMIN = 0 9 TMAX = 10000 w2=ScreenWidth()/2 h2=ScreenHeight()/2 10 FOR X = 0 TO ScreenWidth() 20 FOR Y = 0 TO ScreenHeight() 30 RDX = (X - w2) / 32 31 RDY = (h2 - Y) / 32 32 RDZ = 8 40 GOSUB 1000 //50 PAPER COL //51 Ink COL; Plot x,y //Rect x*8,y*8,8.1,8.1 Plot x,y 100 NEXT Y 105 Ink 0; Rect 0,0,ScreenWidth(),8;Ink 1;Locate 0,0; Print Mills(1) 110 NEXT X 120 end 1000 // ===== TraceRay ===== 1001 // Params: (ROX, ROY, ROZ): ray origin; (RDX, RDY, RDZ): ray direction; (TMIN, TMAX): wanted ranges of t 1002 // Returns: COL: pixel color 1010 COL = -1: MINT = 0:CS=-1 1101 NS=GCount 1102 FOR S = 1 TO NS 1110 SCX=Geom(s,0) SCY=Geom(s,1) SCZ=Geom(s,2) SRAD=Geom(s,3) SCOL=Geom(s,4) 1200 COX = ROX - SCX 1201 COY = ROY - SCY 1202 COZ = ROZ - SCZ 1210 EQA = RDX*RDX + RDY*RDY + RDZ*RDZ 1211 EQB = 2*(RDX*COX + RDY*COY + RDZ*COZ) 1212 EQC = (COX*COX + COY*COY + COZ*COZ) - SRAD*SRAD 1220 DISC = EQB*EQB - 4*EQA*EQC 1230 IF DISC < 0 THEN GOTO 1500 1240 T1 = (-EQB + SQR(DISC)) / 2*EQA 1241 T2 = (-EQB - SQR(DISC)) / 2*EQA 1250 IF T1 >= TMIN AND T1 <= TMAX AND (T1 < MINT OR COL == -1) THEN COL = SCOL:CS=S; MINT = T1 1300 IF T2 >= TMIN AND T2 <= TMAX AND (T2 < MINT OR COL == -1) THEN COL = SCOL:CS=S; MINT = T2 1500 NEXT S 1999 IF COL == -1 THEN COL = 0 Ink COL if CS>-1 // Lighting MT=1 NX = RDX*MT - Geom(CS, 0): NY = RDY*MT - Geom(CS, 1): NZ = RDZ*MT - Geom(CS, 2) PL = AI NL = (NX*LX + NY*LY + NZ*LZ) IF NL > 0 THEN PL = PL + (DI * NL) / SQR(NX*NX + NY*NY + NZ*NZ) PL=Limit(PL,0,1) r=GetRed()*PL;g=GetGreen()*PL;b=GetBlue()*PL SetCol r,g,b endif 2000 RETURN Had to tweak a number of elements for this to work, but.. Yeah, it works! .. I think! -=-=- ''Load, Next List!'' Thu, 25 Jan 2024, 04:21 Pakz 9470 here for version 2 on chrome on ipad M2. Thu, 25 Jan 2024, 04:59 Jayenkai Yeah, it's not quick, is it All those for loops. JSE really struggles when you do the double-loop thing. (11864 on iPad Air "the one before the M1") -=-=- ''Load, Next List!'' Thu, 25 Jan 2024, 05:13 Pakz I think I read it took half an hour? On a original spectrum. So could be a lot worse.