Page 1 of 1

My First Submission - A ray marched sphere and plane.

Posted: Thu Jul 14, 2022 6:12 pm
by Phongy
Enjoy!

Code: Select all

dim res(2)

scale = SCREEN_SCALE()
scale = 0.25
v2init(SCREEN_WIDTH() * scale,SCREEN_HEIGHT() * scale, res)

st = 2

SHADOW OFF

GRAPHICS
REFRESH OFF
for y = 0 to res(1) step st
	for x = 0 to res(0) step st
	
	dim frag(2)
	v2init(x, res(1)-y, frag)

	dim ro(3)
	dim rd(3)
	dim q(3)

	v3init(0, 0, 1, ro)
	v3init((frag(0)-0.5*res(0))/res(1), (frag(1)-0.5*res(1))/res(1), 0, q)

	v3sub(rd, q, ro)
	v3norm(rd)

	h=0
	t=1

	for i=0 to 128 step t
		dim rds(3)

		v3copy(rds, rd)
		v3scale(rds, t)

		dim p(3)
		v3add(p, ro, rds)
		
		h=scene(p)
		t=t+h

		if h < 0.01 then
			break
		end if 

	next i

	if h < 0.01 then
		dim rds(3)

		v3copy(rds, rd)
		v3scale(rds, t)
	
		dim p(3)
		v3add(p, ro, rds)

		dim n(3)
		scenenorm(p, n)

		dim l(3)
		v3init(1,1,-1,l)

		dim tol(3)
		v3sub(tol, l, p)
		v3norm(tol)

		dif = v3dot(n, tol)
		dif = dif * dif * dif
		dif = saturate(dif)

		dif = dif * (5 / v3dot(tol, tol))
		draw pixel x,y color dif, dif, dif
	else
		draw pixel x,y color 3/255, 173/255, 252/255
	end if

	next x

	REFRESH
next Y

def scene(p())

	dim o(3)
	dim o2(3)

	v3init(0,0,-2,o)
	v3init(1.5,-(1-0.25),-2,o2)
	
	d = sphere(o, 1, p)
	d = min(d, sphere(o2, 0.25, p))
	d = min(d, p(1) + 1)

	return d
end def

def scenenorm(p(), n())
	e = 0.001
	d = scene(p)

	dim right(3)
	dim up(3)
	dim back(3)

	v3init(e, 0, 0, right)
	v3init(0, e, 0, up)
	v3init(0, 0, e, back)

	v3add(right, p, right)
	v3add(up, p, up)
	v3add(back, p, back)

	rd = scene(right)
	ud = scene(up)
	bd = scene(back)

	v3init(rd-d, ud-d, bd-d, n)
	v3scale(n, 1/e)

end def

rem ==== v3 math ====

def v3init(x, y, z, v())
	v(0)=x
	v(1)=y
	v(2)=z
end def

def v3length(v()) = sqrt(v(0)*v(0)+v(1)*v(1)+v(2)*v(2))

def v3distance(v0(), v1())
	dim s(3)
	v3sub(s, v0, v1)
	return v3length(s)
end def

def v3add(o(), v1(), v2())
	o(0)=v1(0)+v2(0)
	o(1)=v1(1)+v2(1)
	o(2)=v1(2)+v2(2)
end def

def v3sub(o(), v1(), v2())
	o(0)=v1(0)-v2(0)
	o(1)=v1(1)-v2(1)
	o(2)=v1(2)-v2(2)
end def

def v3norm(v())
	l = v3length(v)
	v3scale(v, 1/l)
end def

def v3dot(l(), r())
	return l(0)*r(0)+l(1)*r(1)+l(2)*r(2)
end def

def v3scale(v(), s)
	v(0)=v(0)*s
	v(1)=v(1)*s
	v(2)=v(2)*s
end def

def v3copy(o(), v())
	o(0)=v(0)
	o(1)=v(1)
	o(2)=v(2)
end def

def v2init(x, y, v())
	v(0)=x
	v(1)=y
end def

def v2scale(v(), s)
	v(0)=v(0)*s
	v(1)=v(1)*s
end def

def v3print(v())
	print v(0);v(1);v(2)
end def

def saturate(s) = min(1.0, max(0.0, s))

rem ==== sdf ====

def sphere(o(), r, p())
	return v3distance(o, p) - r
end def

def dp() 
	debug pause
end def
Change scale and step to change quality settings at the expense of speed.

Thanks