
Code:
Code: Select all
EnableExplicit
;Torus Knot Raymarching - SPP Example
;I followed along the great tutorial by The Art of Code (Martijn)
;https://www.youtube.com/watch?v=2dzJZx0yngg
;Great channel if you want to learn about shaders :)
XIncludeFile "spp.pbi"
Structure VEC2
x.f
y.f
EndStructure
Structure VEC3
x.f
y.f
z.f
EndStructure
Structure VEC4
x.f
y.f
z.f
w.f
EndStructure
Global time.f
Macro vlMix(_x_,_y_,_a_)
(_x_ * (1 - _a_) + _y_ * _a_)
EndMacro
Macro v2(_v_,_x_,_y_)
_v_\x = _x_
_v_\y = _y_
EndMacro
Macro v2Length(_v_)
Sqr((_v_\x * _v_\x) + (_v_\y * _v_\y))
EndMacro
Macro v2Rotate(_v_,_a_,_out_)
_out_\x = (_v_\x * Cos(_a_)) - (_v_\y * Sin(_a_))
_out_\y = (_v_\x * Sin(_a_)) + (_v_\y * Cos(_a_))
EndMacro
Macro v2RotateXY(_x_,_y_,_a_,_out_)
_out_\x = (_x_ * Cos(_a_)) - (_y_ * Sin(_a_))
_out_\y = (_x_ * Sin(_a_)) + (_y_ * Cos(_a_))
EndMacro
Macro v3(_v_,_x_,_y_,_z_)
_v_\x = _x_
_v_\y = _y_
_v_\z = _z_
EndMacro
Macro v3Add(_v1_,_v2_,_out_)
_out_\x = _v1_\x + _v2_\x
_out_\y = _v1_\y + _v2_\y
_out_\z = _v1_\z + _v2_\z
EndMacro
Macro v3Sub(_v1_,_v2_,_out_)
_out_\x = _v1_\x - _v2_\x
_out_\y = _v1_\y - _v2_\y
_out_\z = _v1_\z - _v2_\z
EndMacro
Macro v3MulVal(_v_,_val_,_out_)
_out_\x = _v_\x * _val_
_out_\y = _v_\y * _val_
_out_\z = _v_\z * _val_
EndMacro
Macro v3DivVal(_v_,_val_,_out_)
_out_\x = _v_\x / _val_
_out_\y = _v_\y / _val_
_out_\z = _v_\z / _val_
EndMacro
Macro v3Cross(_v1_,_v2_,_out_)
_out_\x = (_v1_\y * _v2_\z) - (_v1_\z * _v2_\y)
_out_\y = (_v1_\z * _v2_\x) - (_v1_\x * _v2_\z)
_out_\z = (_v1_\x * _v2_\y) - (_v1_\y * _v2_\x)
EndMacro
Macro v3Dot(_v1_,_v2_)
((_v1_\x * _v2_\x) + (_v1_\y * _v2_\y) + (_v1_\z * _v2_\z))
EndMacro
Macro v3Length(_v_)
Sqr((_v_\x * _v_\x) + (_v_\y * _v_\y) + (_v_\z * _v_\z))
EndMacro
Macro v3RayPos(_ro_,_rd_,_dst_,_out_)
v3MulVal(_rd_,_dst_,_out_)
v3Add(_ro_,_out_,_out_)
EndMacro
Macro v3NormalSub(_ray_,_normal_,_out_)
v3Sub(_ray_,_normal_,_out_)
v3Normalize(_out_)
EndMacro
Macro v3MixColor(_c1_,_c2_,_factor_,_out_)
_out_\x + vlMix(_c1_\x,_c2_\x,_factor_)
_out_\y + vlMix(_c1_\y,_c2_\y,_factor_)
_out_\z + vlMix(_c1_\z,_c2_\z,_factor_)
EndMacro
Macro v3PowVal(_v_,_val_,_out_)
_out_\x = Pow(_v_\x,_val_)
_out_\y = Pow(_v_\y,_val_)
_out_\z = Pow(_v_\z,_val_)
EndMacro
Procedure.i v3Normal(*p.VEC3,val.f,*out1.VEC3,*out2.VEC3,*out3.VEC4)
v3(*out1,*p\x - val,*p\y,*p\z)
v3(*out2,*p\x,*p\y - val,*p\z)
v3(*out3,*p\x,*p\y,*p\z - val)
ProcedureReturn
EndProcedure
Procedure.i v3Normalize(*v.vec3)
Protected length.f
length = v3Length(*v)
v3DivVal(*v,length,*v)
ProcedureReturn
EndProcedure
Procedure v3Reflect(*pos.VEC3,*normal.VEC3,*out.VEC3)
Protected dot.f
dot = v3Dot(*pos,*normal)
*out\x = *pos\x - 2.0 * dot * *normal\x
*out\y = *pos\y - 2.0 * dot * *normal\y
*out\z = *pos\z - 2.0 * dot * *normal\z
ProcedureReturn
EndProcedure
Procedure.f GetDist(*p.VEC3)
Protected.f r1,r2,a,d
Protected.VEC2 cp,cr
r1 = 1.7
r2 = 0.2
v2(cp,*p\x,*p\z)
v2(cp,(v2Length(cp) - r1),*p\y)
a = ATan2(*p\x,*p\z)
v2Rotate(cp,(a * 3.0 + time),cr)
cp = cr
cp\y = Abs(cp\y) - 0.3
d = v2Length(cp) - r2
ProcedureReturn d
EndProcedure
Procedure.f RayMarch(*ro.VEC3,*rd.VEC3)
Protected index.i,p.VEC3,do.f,ds.f
For index = 0 To 99
v3RayPos(*ro,*rd,do,p)
ds = GetDist(@p)
do + ds
If do > 100.0 Or Abs(ds) < 0.01
Break
EndIf
Next
ProcedureReturn do
EndProcedure
Procedure.i GetNormal(*p.VEC3,*out.VEC3)
Protected.VEC3 n0,n1,n2,n3
v3Normal(*p,0.01,@n0,@n1,@n2)
v3(n3,GetDist(@n0),GetDist(@n1),GetDist(@n2))
v3NormalSub(*p,n3,*out)
ProcedureReturn
EndProcedure
Procedure.i GetRayDir(*uv.VEC2,*p.VEC3,*l.VEC3,z.f,*out.VEC3)
Protected.VEC3 f,r,v,u,c
v3Sub(*l,*p,f)
v3Normalize(@f)
v3(v,0.0,1.0,0.0)
v3Cross(v,f,r)
v3Normalize(@r)
v3Cross(f,r,u)
v3MulVal(f,z,c)
*out\x = c\x + *uv\x * r\x + *uv\y * u\x
*out\y = c\y + *uv\x * r\y + *uv\y * u\y
*out\z = c\z + *uv\x * r\z + *uv\y * u\z
v3Normalize(*out)
ProcedureReturn
EndProcedure
Procedure.i Background(*rd.VEC3,*color.VEC4)
Protected.VEC3 a,b
v3(a,0.2,0.1,0.1)
v3(b,0.2,0.5,1.0)
v3MixColor(a,b,(*rd\y * 0.5 + 0.5),*color)
ProcedureReturn
EndProcedure
Procedure.i Callback(*coord.VEC2,*color.VEC4,*output.VEC2)
Protected.VEC2 uv
Protected.VEC3 ro,rd,v,p,n,r
Protected.f d,dif
v2(uv,(*coord\x - 0.5 * *output\x) / *output\y,(*coord\y - 0.5 * *output\y) / *output\y)
v3(ro,1.0,1.0,- 3.0)
v2RotateXY(ro\y,ro\z,time,ro)
v3(v,0.0,0.0,0.0)
GetRayDir(@uv,@ro,@v,0.5,@rd)
d = RayMarch(@ro,@rd)
v3(*color,0.0,0.0,0.0)
Background(@rd,*color)
If d < 100.0
v3RayPos(ro,rd,d,p)
GetNormal(@p,@n)
v3Reflect(@rd,@n,@r)
v3(v,1.0,2.0,3.0)
v3Normalize(@v)
dif = v3Dot(n,v) * 0.1 + 0.5
v3(*color,dif,dif,dif)
EndIf
v3PowVal(*color,0.4545,*color)
ProcedureReturn
EndProcedure
sppCreate(#Null$,512,512,#SPP_WINDOW_NORMAL,256,256,@Callback(),#True,60,@time)
End