Page 1 of 1

ZX Spectrum Raytracer

Posted: Fri Jan 26, 2024 9:10 am
by berarma
Not mine, but I found it interesting. I wonder how much faster it would run in machine code.

https://gabrielgambetta.com/zx-raytracer.html

Re: ZX Spectrum Raytracer

Posted: Fri Jan 26, 2024 10:02 am
by Xela
About x10 times faster:

Image
Spectrum Next "pure" Basic 28Mhz

Image
Spectrum Next Tobos FP 28Mhz

Re: ZX Spectrum Raytracer

Posted: Fri Jan 26, 2024 10:14 am
by flatduckrecords
The sources are listed in the article but here's a .tap file I made if anyone else wants to try it out:

zxrt.tap

Re: ZX Spectrum Raytracer

Posted: Fri Jan 26, 2024 12:15 pm
by ZXDunny
320x192, 8bpp in SpecBAS:

Image

Re: ZX Spectrum Raytracer

Posted: Fri Jan 26, 2024 1:12 pm
by Xela
ZXDunny wrote: Fri Jan 26, 2024 12:15 pm 320x192, 8bpp in SpecBAS:
Can I ask you for the program in an adapted form for specbas? The copypaste method did not work for me. Apart from the BRIGHT 1 error, which was clearly highlighted, there is something else preventing it from running.

Re: ZX Spectrum Raytracer

Posted: Fri Jan 26, 2024 1:49 pm
by ZXDunny
Sure :)

Code: Select all

2 origin flip: PAPER 0: INK 7: CLS : let TME=MSECS: LET SW=SCRW/2: LET SH=SCRH/2: GO SUB 8000: GO SUB 7000: DIM C(64): DIM L(64): LET DZ=(ScrW/800)*2: FOR X=0 TO scrw-1 STEP 8: FOR Y=0 TO scrh-1 STEP 8
40 LET DX=(X-SW)/256: LET DY=(Y-SH)/256: GO SUB 1000: LET CTL=PC: LET LTL=PL: LET DX=(X-SW+7)/256: GO SUB 1000: LET CTR=PC: LET LTR=PL: LET DY=(Y-SH+7)/256: GO SUB 1000: LET CBR=PC: LET LBR=PL: LET DX=(X-SW)/256: GO SUB 1000: LET CBL=PC: LET LBL=PL
51 IF CTL=0 AND CTR=0 AND CBR=0 AND CBL=0 THEN GO TO 500
111 LET CI=1: DIM A(8): LET PL=0: FOR U=X TO X+7: LET DX=(U-SW)/256: FOR V=Y TO Y+7: IF CI=1 THEN LET PC=CTL: LET PL=LTL: GO TO 160
141 IF CI=8 THEN LET PC=CBL: LET PL=LBL: GO TO 160
142 IF CI=57 THEN LET PC=CTR: LET PL=LTR: GO TO 160
143 IF CI=64 THEN LET PC=CBR: LET PL=LBR: GO TO 160
150 LET DY=(V-SH)/256: GO SUB 1000
160 LET A(PC+1)=A(PC+1)+1: LET C(CI)=PC: LET L(CI)=PL: LET CI=CI+1: NEXT V: NEXT U: LET MFC=0: FOR C=2 TO 8: IF A(C)>MFC THEN LET MFC=A(C): LET MFI=C
204 NEXT C: LET FC=MFI-1: INK FC
301 LET CI=1: FOR U=X TO X+7: FOR V=Y TO Y+7: IF C(CI)>0 AND H(CI)<=L(CI) THEN PLOT U,V
325 LET CI=CI+1: NEXT V: NEXT U
500 NEXT Y: GO SUB 3000: PRINT AT 0,0; INK 7;(msecs-TME)/1000: NEXT X: STOP
1000 LET MT=1E10: LET A=2*(DX*DX+DY*DY+DZ*DZ): FOR S=1 TO NS: LET B=2*(DX*S(S,1)+DY*S(S,2)+DZ*S(S,3)): LET C=(S(S,1)*S(S,1)+S(S,2)*S(S,2)+S(S,3)*S(S,3))-S(S,4): LET D=B*B-2*A*C: IF D<0 THEN GO TO 1500
1231 LET D=SQR (D): LET T=(B+D)/A: IF T>0 AND T<MT THEN LET PC=S(S,5): LET MT=T: LET CS=S
1250 LET T=(B-D)/A: IF T>0 AND T<MT THEN LET PC=S(S,5): LET MT=T: LET CS=S
1500 NEXT S: IF MT=1E10 THEN LET PC=0: RETURN
1600 LET IX=DX*MT: LET IY=DY*MT: LET IZ=DZ*MT: LET NX=IX-S(CS,1): LET NY=IY-S(CS,2): LET NZ=IZ-S(CS,3): LET PL=AI: GO SUB 2100: IF H=1 THEN RETURN
1615 LET NL=(NX*LX+NY*LY+NZ*LZ): IF NL>0 THEN LET PL=PL+DI*NL/SQR (NX*NX+NY*NY+NZ*NZ)
2000 RETURN
2100 LET A=2*(LX*LX+LY*LY+LZ*LZ): FOR S=1 TO NS: LET CX=IX-S(S,1): LET CY=IY-S(S,2): LET CZ=IZ-S(S,3): LET B=-2*(CX*LX+CY*LY+CZ*LZ): LET C=(CX*CX+CY*CY+CZ*CZ)-S(S,4): LET D=B*B-2*A*C: IF D<0 THEN GO TO 2210
2160 LET D=SQR (D): LET T=(B+D)/A: IF T>0.01 THEN LET H=1: RETURN
2190 LET T=(B-D)/A: IF T>0.01 THEN LET H=1: RETURN
2210 NEXT S: LET H=0: RETURN
3000 RETURN
7000 DIM H(64): RESTORE 7100: FOR I=1 TO 64: READ H(I): LET H(I)=H(I)/64: NEXT I: RETURN
7100 DATA 0,32,8,40,2,34,10,42
7101 DATA 48,16,56,24,50,18,58,26
7102 DATA 12,44,4,36,14,46,6,38
7103 DATA 60,28,52,20,62,30,54,22
7104 DATA 3,35,11,43,1,33,9,41
7105 DATA 51,19,59,27,49,17,57,25
7106 DATA 15,47,7,39,13,45,5,37
7107 DATA 63,31,55,23,61,29,53,21
8000 LET LX=-1/SQR (2): LET LY=1/SQR (2): LET LZ=0: LET AI=0.075: LET DI=1-AI: RESTORE 9000: READ NS: DIM S(NS,5): FOR S=1 TO NS: FOR I=1 TO 5: READ S(S,I): NEXT I: NEXT S: RETURN
9000 DATA 4
9001 DATA 0,-1,4,1,2
9002 DATA 2,0,4,1,1
9003 DATA -2,0,4,1,4
9004 DATA 0,-5001,0,5000^2,6
It's been updated for varying resolutions, and added ORIGIN FLIP to get the graphics upside-down.

Re: ZX Spectrum Raytracer

Posted: Fri Jan 26, 2024 2:01 pm
by Xela
ZXDunny wrote: Fri Jan 26, 2024 1:49 pm Sure :)

It's been updated for varying resolutions, and added ORIGIN FLIP to get the graphics upside-down.
I seem to be doing something wrong... :)

I copied the text, save it to a file, tried to load it into SpecBAS, got error 31 LOAD failed, 0:1

I tried to copy and paste into SpecBAS editor, I choose RUN from the menu, I get this window:
Image

and that's it...

Looks like it's time to start reading the manual :D

Re: ZX Spectrum Raytracer

Posted: Fri Jan 26, 2024 2:22 pm
by ZXDunny
Xela wrote: Fri Jan 26, 2024 2:01 pm I seem to be doing something wrong... :)

I copied the text, save it to a file, tried to load it into SpecBAS, got error 31 LOAD failed, 0:1

I tried to copy and paste into SpecBAS editor, I choose RUN from the menu, I get this window:
Your version of SpecBAS is too old. Grab a new executable from here: https://github.com/ZXDunny/SpecBAS/blob ... pecBAS.exe and replace your exe with that one.

Re: ZX Spectrum Raytracer

Posted: Fri Jan 26, 2024 2:27 pm
by g0blinish
BasinC:
Image

Re: ZX Spectrum Raytracer

Posted: Fri Jan 26, 2024 2:39 pm
by g0blinish
oops, wrong source

Image

Re: ZX Spectrum Raytracer

Posted: Fri Jan 26, 2024 2:46 pm
by Pobulous
g0blinish wrote: Fri Jan 26, 2024 2:39 pm oops, wrong source

Image
Still not the final source....

Re: ZX Spectrum Raytracer

Posted: Fri Jan 26, 2024 3:15 pm
by Xela
ZXDunny wrote: Fri Jan 26, 2024 2:22 pm Grab a new executable from here
Thanx! Now it's working!

Re: ZX Spectrum Raytracer

Posted: Mon Jan 29, 2024 8:46 am
by ggambetta
Well hello there! I wrote the raytracer, and I'm beyond flattered that you guys found it interesting enough to play around with it :)

I've been toying with different ways to improve the attribute clash even more, here's as far as I got:

Image

What it does is computing the average intensity of the two most frequent colors in each 8x8 block. If both are "bright", it PLOTs all the pixels, in either color. If one is "dark" and one is "bright", it does ordered dithering of the "bright" one. If both are "dark", it does ordered dithering of the most frequent one.

Works decently well, but the tradeoff is that the dark areas of the image lose some "light intensity resolution" (i.e. areas that should be ordered-dithered look all black instead).

I'd appreciate any ideas :)

Re: ZX Spectrum Raytracer

Posted: Mon Jan 29, 2024 9:23 am
by bluespikey
ggambetta wrote: Mon Jan 29, 2024 8:46 am
I'd appreciate any ideas :)
A colourised Tau Ceti would be grand :)

Re: ZX Spectrum Raytracer

Posted: Fri Feb 02, 2024 8:57 pm
by Wall_Axe
It looks very good. Are other shapes available like oblongs, can spheres occupy the same space to create new shapes like egg shapes?

Re: ZX Spectrum Raytracer

Posted: Fri Feb 02, 2024 9:00 pm
by ParadigmShifter
+1 for oblong, my favourite shape name. I think you mean oblongoids though?

Re: ZX Spectrum Raytracer

Posted: Fri Feb 02, 2024 9:09 pm
by flatduckrecords
Wall_Axe wrote: Fri Feb 02, 2024 8:57 pm It looks very good. Are other shapes available like oblongs, can spheres occupy the same space to create new shapes like egg shapes?
@ggambetta’s book Computer Graphics from Scratch explains how it all works but here’s a snippet from section one:
We could choose any arbitrary geometric primitive as the building block of our scenes; for raytracing, we’ll use spheres because they’re easy to manipulate with equations.
Part 1, Section 1, Basic Raytracing

Re: ZX Spectrum Raytracer

Posted: Fri Feb 02, 2024 9:14 pm
by ParadigmShifter
Well it's all parametric rather than polygons so they could have had more variety.

Oblongoids, Cylinders, Cones and Tori are all popular. Tori are a bit gnarly working out intersections though IIRC.