solidcorp Posted February 6 Share Posted February 6 This is part of a collection of Ray Tracing projects I've been working on. I'm pretty proud of this one in particular. See the video description for details. 0:05 / 0:06 23 Quote Link to comment Share on other sites More sharing options...
Beeblebrox Posted February 6 Share Posted February 6 (edited) Very cool, great use of dithering and rich colours. For ease I've just copied the text from your video: All the frames of this video and the audio were created by an ATARI 8 bit computer emulator. The program to render this ray traced animation is 10 lines of ATARI BASIC, each line is under 80 characters long. This animation took 16 hours to render running the Atari800win Plus emulator at full (~3200%) speed. Frames were captured by HyperCam2. The sound is also from ATARI 8 bit computers and requires clocking the audio at 1.79MHz, combining audio channels to get 16bit frequency range and creating a deep overtone. I love this sound. This sound was captured from the emulator using Audacity. The dithered four color 160x192 pixel frames were extracted from the window capture and and were combined with the sound in HitFilm Express where the title frame was also created. Edited February 6 by Beeblebrox 1 3 Quote Link to comment Share on other sites More sharing options...
_The Doctor__ Posted February 6 Share Posted February 6 accelerated 3,200% took 16 hours? So we won't be watching this on our real Atari if that's the case. Interesting exercise, how long between frames being captured? Automatic trigger or fully recorded then edited ? 2 Quote Link to comment Share on other sites More sharing options...
MaPa Posted February 7 Share Posted February 7 And how many frames were calculated in that 16h time? Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted February 7 Share Posted February 7 Is this based on https://mastodon.me.uk/@coprolite9000/111762131524979212 2 Quote Link to comment Share on other sites More sharing options...
solidcorp Posted February 7 Author Share Posted February 7 3 hours ago, Wrathchild said: Is this based on https://mastodon.me.uk/@coprolite9000/111762131524979212 Yep, which is based on someone else's program, @coprolite9000 just added the dithering. I saw it on Y-Combinator news. I've had to make lots of modifications to get it to work in Atari BASIC. The dithering is implemented with a diabolical hack that took a while to unravel Atari BASIC has no modulus operator Atari BASIC has no integer operations (e.g. DIV16) Had to adjust for screen resolution and aspect ratio Had to find suitable colors Disabled attract mode Added animation Fit in in 10 lines less than 80 characters - masochism I've other adaptations in mode 7+ with sound and color editing, and adapted it to GTIA modes too and added sound and music and color editing. I'll post more and eventually source soon. 5 Quote Link to comment Share on other sites More sharing options...
solidcorp Posted February 7 Author Share Posted February 7 (edited) 19 hours ago, _The Doctor__ said: accelerated 3,200% took 16 hours? So we won't be watching this on our real Atari if that's the case. Interesting exercise, how long between frames being captured? Automatic trigger or fully recorded then edited ? At 3200% it took about 10 minutes to render a frame, some take longer than others based on reflections. On classic hardware or unaccelerated emulator I guess that would be around 4.5 to 5 hours per frame. I used Hypercam2 and the lowest framerate I could capture was 1 frame per second, in the edit I playback at 30000% to 60fps video which is about 1 Atari frame every 1/30th of a second I think. I captured a LOT more frames than I needed but I did what was easy. Edited February 7 by solidcorp 3 Quote Link to comment Share on other sites More sharing options...
solidcorp Posted February 7 Author Share Posted February 7 4 hours ago, MaPa said: And how many frames were calculated in that 16h time? 110 Quote Link to comment Share on other sites More sharing options...
w1k Posted February 7 Share Posted February 7 how i can try this on real hw? Quote Link to comment Share on other sites More sharing options...
Beeblebrox Posted February 7 Share Posted February 7 3 hours ago, w1k said: how i can try this on real hw? You can't. Unless someone compiles each frame and loads it as a dithered image from a suitable capacity/speed storage medium, running it in sequence. I think the point here is to see a simulated/emulated Atari program having ray traced all the frames, albiet greatly accelerated. Otherwise it would have taken weeks. 1 Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted February 7 Share Posted February 7 (edited) I wonder if in Altirra you could use a breakpoint on a access to a byte which triggers a screen save. You could then splice those images into a gif? @phaeron or even trigger the .writemem command and in this case dump the screen mem. Edited February 7 by Wrathchild Quote Link to comment Share on other sites More sharing options...
phaeron Posted February 8 Share Posted February 8 5 hours ago, Wrathchild said: I wonder if in Altirra you could use a breakpoint on a access to a byte which triggers a screen save. You could then splice those images into a gif? @phaeron or even trigger the .writemem command and in this case dump the screen mem. I mean, sure, you could do that... or you could rewrite it in asm so it runs faster than 1frame/4h. Even just running it under TBXL would speed things up quite a lot. Quote Link to comment Share on other sites More sharing options...
pcrow Posted February 8 Share Posted February 8 This is a job for a fast floating point package. This would be worth exploring compiled BASIC options. But I expect if you did some profiling, you would find that the vast majority of the time is in the floating point package, and it's likely really doing floating point except for loop indices, so compiling or even rewriting in assembly wouldn't save that much time. The totally cheating thing to do, which would also be cool in its own way, would be to raytrace the same thing on modern computer, and then convert the frames to Atari with RastaConverter. Then the ultimate hack would be to find a way to get the Atari to cycle through the frames at a reasonable speed. (If you manage to get all the frames in 16K, you could bank select a bunch, but probably not enough.) 1 Quote Link to comment Share on other sites More sharing options...
Beeblebrox Posted February 8 Share Posted February 8 4 hours ago, pcrow said: This is a job for a fast floating point package. This would be worth exploring compiled BASIC options. But I expect if you did some profiling, you would find that the vast majority of the time is in the floating point package, and it's likely really doing floating point except for loop indices, so compiling or even rewriting in assembly wouldn't save that much time. The totally cheating thing to do, which would also be cool in its own way, would be to raytrace the same thing on modern computer, and then convert the frames to Atari with RastaConverter. Then the ultimate hack would be to find a way to get the Atari to cycle through the frames at a reasonable speed. (If you manage to get all the frames in 16K, you could bank select a bunch, but probably not enough.) Check this out: Quote Link to comment Share on other sites More sharing options...
ilmenit Posted February 8 Share Posted February 8 16 hours ago, solidcorp said: Yep, which is based on someone else's program, @coprolite9000 just added the dithering. I saw it on Y-Combinator news. I've had to make lots of modifications to get it to work in Atari BASIC. The dithering is implemented with a diabolical hack that took a while to unravel Atari BASIC has no modulus operator Atari BASIC has no integer operations (e.g. DIV16) Had to adjust for screen resolution and aspect ratio Had to find suitable colors Disabled attract mode Added animation Fit in in 10 lines less than 80 characters - masochism I've other adaptations in mode 7+ with sound and color editing, and adapted it to GTIA modes too and added sound and music and color editing. I'll post more and eventually source soon. can you share the code? 2 Quote Link to comment Share on other sites More sharing options...
dmsc Posted February 9 Share Posted February 9 Hi! 18 hours ago, ilmenit said: can you share the code? From the original BBC source at https://bbcmic.ro/?t=9ctpk you can translate it to other BASIC. This is a FastBasic version, the ATR includes the Altirra Mathpack for more speed, it starts with Z=2.25 and goes further by 0.25 each frame. Spoiler DATA DITH() B. = 0,8,2,10,12,4,14,6,3,11,1,9,15,7,13,5 GR.31 SE.0,2,6 SE.1,1,10 SE.2,14,14 Z0%=2 DO Z0%=Z0%+0.25 FOR N=0 TO 191 POKE 77,0 COLOR 0: PLOT 159,N FOR M=0 TO 159 X%=0 Y%=-.1 Z%=Z0% U%=(M-79.5)/80 V%=(95.5-N)/120 W%=1 / SQR(U%*U%+V%*V%+1) U%=U%*W% V%=V%*W% I%=SGN U% DO E%=X%-I% F%=Y%-I% P%=U%*E%+V%*F%-W%*Z% D%=P%*P%-E%*E%-F%*F%-Z%*Z%+1 IF D%>0 T%=-P% - SQR D% IF T%>0 X%=X%+T%*U% Y%=Y%+T%*V% Z%=Z%-T%*W% E%=X%-I% F%=Y%-I% G%=Z% P%=2*(U%*E%+V%*F%-W%*G%) U%=U%-P%*E% V%=V%-P%*F% W%=W%+P%*G% I%=-I% ELSE EXIT ENDIF ELSE EXIT ENDIF LOOP IF V%<0 P%=(Y%+2)/V% TMP = (INT(X%-U%*P%)+INT(Z%-W%*P%)) & 1 V%=-V%*(TMP*.5+.3)+.2 ENDIF COLOR 3 - (INT(48*SQR V%) + DITH((M & 3) + (N & 3) * 4)) / 16 PLOT M,N NEXT NEXT LOOP raytrace.atr 6 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted February 9 Share Posted February 9 (edited) Deleted. Edited February 9 by flashjazzcat Quote Link to comment Share on other sites More sharing options...
sanny Posted February 9 Share Posted February 9 (edited) 8 hours ago, dmsc said: From the original BBC source at https://bbcmic.ro/?t=9ctpk you can translate it to other BASIC. Doesn't this miss a "NEXT"? Two opening "FOR"s and only one "NEXT"? But it seems to work somehow Edited February 9 by sanny more text Quote Link to comment Share on other sites More sharing options...
Rybags Posted February 9 Share Posted February 9 It seems to be tolerated, not sure if a nested unclosed FOR loop replaces a previous active one or creates a new stack entry. But if you put the NEXT outside of the outer loop you get an error same as if the loop was never created. e.g. 10 FOR A=1 TO 10 20 FOR B=A TO 20 80 ? B 90 NEXT A 100 NEXT B Quote Link to comment Share on other sites More sharing options...
dmsc Posted February 9 Share Posted February 9 Hi! 2 hours ago, sanny said: Doesn't this miss a "NEXT"? Two opening "FOR"s and only one "NEXT"? But it seems to work somehow In BBC Basic, you can specify more than one variable as argument to NEXT, you can write " NEXT M,N ", this is the same as "NEXT M : NEXT N". Also, you can omit the variable names so the "NEXT , " is the same as "NEXT : NEXT". I could add this syntax to FastBasic, it is a simple addition to the parser. Have Fun! 3 Quote Link to comment Share on other sites More sharing options...
R0ger Posted February 9 Share Posted February 9 Really great piece of programming .. I love it. I ported it to VB6 and experimented a bit with fixed decimal point to eventually do something like this in assembler .. but the quadratic equation doesn't go too well with that approach. So I also experimented a bit with ray marching, where the math is easier. Still nothing to show up, and it might never be, but it's certainly interesting topic. Quote Link to comment Share on other sites More sharing options...
phaeron Posted February 9 Share Posted February 9 Reversed the math in the BBC version... I'm guessing that in assembly this would probably best be implemented with 16 or 24-bit fixed point, even with the square roots. 40 -- set view position X=0:Y=-.1:Z=3: -- compute view vector U=(M-159.5)/160:V=(N-127.5)/160 -- normalize view vector W=1/SQR(U*U+V*V+1):U=U*W:V=V*W -- choose first sphere to hit test based on left/right side I=SGNU -- unused? G=1 50 -- compute relative vector X/Y between camera and sphere (Z implicit) E=X-I:F=Y-I -- compute negated distance from eye along ray to perpendicular center plane of sphere P=U*E+V*F-W*Z -- compute squared distance along ray between sphere center plane and intersection point -- P*P = squared distance from eye to sphere center plane -- E*E+F*F+Z*Z = squared distance from eye to sphere position -- (E*E+F*F+Z*Z)-P*P = squared horizontal distance between sphere and plane intersection, by Pythagorean theorem -- 1 = squared radius of sphere -- 1-((E*E+F*F+Z*Z)-P*P) = squared distance between plane and ray-sphere interaction, by Pythagorean theorem D=P*P-E*E-F*F-Z*Z+1 IF D>0 -- compute ray collision time, picking nearer (entry) intersection T=-P-SQRD -- reject collision if it's behind ray origin (ray starts inside or past sphere) IF T>0 -- advance ray to intersection point X=X+T*U:Y=Y+T*V:Z=Z-T*W -- compute sphere normal at intersection point E=X-I:F=Y-I:G=Z -- reflect ray direction across normal plane P=2*(U*E+V*F-W*G) U=U-P*E:V=V-P*F:W=W+P*G -- flip to testing against other sphere I=-I GOTO50 60 -- check if ray pointing down for floor intersection IFV<0 -- compute negated distance to floor P=(Y+2)/V -- compute X/Z of floor intersection and texture V=-V*((INT(X-U*P)+INT(Z-W*P)AND1)/2+.3)+.2 -- tone mapping and ordered dithering based on either floor texture or sky gradient from view vector Y 70 GCOL0,3-(48*SQRV+?(PAGE+5+M MOD4+N MOD4*4)/3)DIV16 4 Quote Link to comment Share on other sites More sharing options...
dmsc Posted February 9 Share Posted February 9 Hi! 2 hours ago, phaeron said: -- unused? G=1 50 -- compute relative vector X/Y between camera and sphere (Z implicit) E=X-I:F=Y-I I suspected the original was EFG = XYZ - (I,I,0) , so EFG is the full relative vector, and crept from and old version with Z=1 and finally left unused. I removed that from my FastBasic version. The ray-tracing code is straightforward, the clever thing was testing only one sphere at a time, as after a reflection in one sphere you can only hit the other one - this makes rendering the two spheres as fast as rendering only one. Have Fun! 1 Quote Link to comment Share on other sites More sharing options...
+CharlieChaplin Posted February 10 Share Posted February 10 Well, ... a little more than 10 lines... (12K of TB XL code) - Christbaum Kugel Editor (XMAS bulb editor), KugelEdi.ATR - listing from C't magazine, Germany 1/1986 - Raytracing editor and demo, in german language - works with TB XL - uses Gr. 8 and only one sphere - one can choose between 4 backgrounds (squares/chessboard, triangles, etc.) - one can set various viewpoints and angles (light, camera, etc.) - with Atari 800 Win and 2000x speed, calculations for one picture take approx. 1-2 minutes - comes with a ready-made demo on the disk (includes 8 calculated raytracing pictures, the animation requires 128K then) => three more (simple) 128K raytracing demos in Gr. 8 available by K. Pelzer, based on the C't program RayAni1.ATR, RayAni2.ATR, RayAni3.ATR => K. Pelzer later created a similar raytracing demo in Gr. 9+11 (most likely based on or inspired by the C't program) Ray128K.ATR (original name: Landscape) KUGELEDI.ATR RAYANI1.ATR RAYANI2.ATR RAYANI3.ATR RAY128K.ATR 2 Quote Link to comment Share on other sites More sharing options...
dmsc Posted February 10 Share Posted February 10 Hi! I made a disk based animation, uncompressed from disk to screen. All 100 frames were rendered with my code above, in FastBasic, then saved to disk and compressed. Decompression code: Spoiler ' Decompresses video frames from file to screen GR.31 SE.0,2,6 SE.1,1,10 SE.2,14,14 BUF=DPEEK(88) BUF1=DPEEK(88)-8192 ' Loop forever DO ' Open video file, read initial frame OPEN #1,4,0,"D:VIDEO.BIN" BGET #1,BUF1,7680 WHILE ERR() < 128 PAUSE 0 POKE 77,0 MOVE BUF1,BUF,7680 ' For first read, check error GET #1,N IF ERR() > 1 THEN EXIT MOVE BUF,BUF1,N P=BUF1+N E=BUF1+7679 Q=0 WHILE P<E GET #1,N IF Q ' Copy from last frame MOVE P+8192,P,N P=P+N Q=0 ELSE ' Read data from file IF N THEN BGET #1,P,N P=P+N Q=1 ENDIF WEND WEND CLOSE #1 LOOP Have Fun! video.atr 4 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.