Hi Martin(/Harm/Vadim),
I hope you don't mind that I modified your code. I was playing around with it a bit (along with AI, since I don't really understand the code ;-)).
My goal was to explore the possibilities for speed optimization in pure BASIC.
For a faster speed (now 44 seconds on 640x480 display), I halved the resolution (using double pixels)!
MODE 3:CLS :Map RESET:Timer =0
Dim Float x,y,z,u,v,w,e,f,p,d,t,uo,vo,tp,v2,xi,zi,i3=1/320
Dim Integer m,n,k,o,c,uc=320,vc=240
Dim Integer G(15)=(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
Colour Map G(),G()
For n=0 To 479:vo=(n-vc)*i3:v2=vo*vo+1:o=28*n
For m=1 To 640 Step 2
x=0:y=-.1:z=3.8:uo=(m-uc)*i3:w=1/Sqr(uo*uo+v2):u=uo*w:v=vo*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 Then Exit Do
t=-p-Sqr(d):If t<0 Then Exit Do
Inc x,t*u:Inc y,t*v:Inc z,-t*w:e=x-i
p=2*(u*e+v*(y-i)-w*z):Inc u,-p*e:Inc v,-p*(y-i):Inc w,p*z:i=-i
Loop
If v<0 Then
tp=(y+2)/v:xi=x-u*tp:zi=z-w*tp
k=((xi+4096)+Int(zi+4096))And 1
c=10-k*10
Else
c=Int(14-v*25+((7*m+o)Mod 16)\2)
EndIf
c=c*(c>0 And c<15)+15*(c>=15)
Line m,480-n,m+1,480-n,,G(c):Next
Next
Print Timer
Variable ListVariable List
+----------+---------+-------------------------------------------------------------+
| Variable | Type | Description |
+----------+---------+-------------------------------------------------------------+
| x, y, z | Float | Current position of the ray in 3D world space. |
| u, v, w | Float | Direction components (X, Y, Z) of the ray, normalized to 1. |
| e, f | Float | Distance vectors from current ray position to sphere center.|
| p | Float | Auxiliary variable for dot product and reflection math. |
| d | Float | Discriminant to check for sphere hits (d > 0). |
| t | Float | Calculated distance to the sphere surface hit point. |
| uo, vo | Float | Screen coordinates mapped to the normalized viewport plane. |
| tp | Float | Distance from current ray position to the floor (y = -2). |
| v2 | Float | Pre-calculated vo^2 + 1 for faster ray normalization. |
| xi, zi | Float | Exact X and Z coordinates of the hit point on the floor. |
| i3 | Float | Pre-calculated constant 1/320 to avoid divisions. |
| m, n | Integer | Loop counters for horizontal pixels and vertical lines. |
| k | Integer | Grid state (0 or 1) from the checkerboard formula. |
| o | Integer | Offset used for the pseudo-dithered sky pattern. |
| c | Integer | Final color index (0-15) after logic and clamping. |
| uc, vc | Integer | Screen center constants (320, 240). |
| G() | Array | Palette array for mapping to MMBasic color indices. |
| i | Float | Sign factor to switch between sphere positions (1 or -1). |
+----------+---------+-------------------------------------------------------------+
Functional Block Description1. Initialization & Setup (Lines 1-8)The code sets the display MODE 3 and resets the color Map. It initializes
all necessary variables and the G() array, which maps indices 0-15 to
the system's color palette.
2. Ray Normalization & Viewport Mapping (Lines 9-11)Inside the nested loops, the code converts screen pixels (m, n) into
3D ray slopes (uo, vo). Line 11 is critical: it calculates the unit
vector components (u, v, w) using the Pythagorean normalization
formula to prepare for accurate physical reflections.
3. Reflection Loop (Lines 12-17)The Do...Loop handles the ray-sphere intersections.
Lines 13-14: Calculate the discriminant 'd' and distance 't' to
check if a sphere is hit.
Lines 15-16: If hit, the position is updated (Inc x, y, z) and
the ray's direction (u, v, w) is mathematically reflected.
Line 17: Toggles 'i' to check the other sphere in the next iteration.
4. Floor and Horizon Logic (Lines 18-23)Floor (Lines 19-21): If the ray points down (v < 0), the floor
intersection (tp) and checkerboard coordinates (xi, zi) are calculated.
Your optimized '10-k*10' logic assigns colors without 'If' branches.
Sky (Lines 22-23): If the ray points up, a dithered gradient color
is calculated based on the vertical slope.
5. Boolean Clamping & Output (Lines 25-26)Line 25: The high-performance Boolean expression clamps 'c' between
0 and 15 without using the slower 'If' or 'Min/Max' commands.
Line 26: The 'Line' command outputs a 2-pixel segment to the screen.

Regards
Michael