ZX Spectrum Raytracer
ZX Spectrum Raytracer
Not mine, but I found it interesting. I wonder how much faster it would run in machine code.
https://gabrielgambetta.com/zx-raytracer.html
https://gabrielgambetta.com/zx-raytracer.html
- flatduckrecords
- Manic Miner
- Posts: 834
- Joined: Thu May 07, 2020 11:47 am
- Location: Oban, Scotland
- Contact:
Re: ZX Spectrum Raytracer
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
zxrt.tap
Re: ZX Spectrum Raytracer
320x192, 8bpp in SpecBAS:
Re: ZX Spectrum Raytracer
Sure
It's been updated for varying resolutions, and added ORIGIN FLIP to get the graphics upside-down.
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
Re: ZX Spectrum Raytracer
Re: ZX Spectrum Raytracer
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
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:
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
I've been toying with different ways to improve the attribute clash even more, here's as far as I got:
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
- bluespikey
- Manic Miner
- Posts: 985
- Joined: Tue Jun 30, 2020 3:54 pm
Re: ZX Spectrum Raytracer
It looks very good. Are other shapes available like oblongs, can spheres occupy the same space to create new shapes like egg shapes?
- ParadigmShifter
- Dynamite Dan
- Posts: 1066
- Joined: Sat Sep 09, 2023 4:55 am
Re: ZX Spectrum Raytracer
+1 for oblong, my favourite shape name. I think you mean oblongoids though?
- flatduckrecords
- Manic Miner
- Posts: 834
- Joined: Thu May 07, 2020 11:47 am
- Location: Oban, Scotland
- Contact:
Re: ZX Spectrum Raytracer
@ggambetta’s book Computer Graphics from Scratch explains how it all works but here’s a snippet from section one:
Part 1, Section 1, Basic RaytracingWe 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.
- ParadigmShifter
- Dynamite Dan
- Posts: 1066
- Joined: Sat Sep 09, 2023 4:55 am
Re: ZX Spectrum Raytracer
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.
Oblongoids, Cylinders, Cones and Tori are all popular. Tori are a bit gnarly working out intersections though IIRC.