Raymarching Shadertoy demo meets multicore

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
ShawnLG
Posts: 142
Joined: Dec 25, 2008 20:21

Raymarching Shadertoy demo meets multicore

Post by ShawnLG »

D.J.Peters posted a Shadertoy demo running in freebasic. It ran too slow. I added multithreading to help with computing the pixels in parallel like on a GPU. It uses threads on every scan line. Compile with "-gen gcc -O 3" for best result.

Original post.
https://www.freebasic.net/forum/viewto ... s#p216409

You will need:

matn.bi

Code: Select all

'Original glslstyle.bi by D.J. Peters.
'Edited by ShawnLG.
'Cleaned up source.
'Fix bugs.
'Added features for better compatibility with freebasic.
'Seperated datatypes into their own .bi files.
#include once "vecn.bi"


'   ########
'  # mat2 #
' ########
'M subscript for matrices (column),(row)
type mat2
    declare constructor(d as single=1)
    declare constructor(a as single,b as single, c as single,d as single) 
    
    declare operator cast as string
  
    as single m00=any,m10=any
    as single m01=any,m11=any
end type

constructor mat2(d as single)
    m00=d : m10=0
    m01=0 : m11=d
end constructor
constructor mat2(a as single, b as single, c as single, d as single) 
    m00=a : m10=b
    m01=c : m11=d
end constructor

operator mat2.cast () as string
    return "(" + str(m00) + ", " + str(m01) + "), (" + str(m10) + ", " + str(m11) + ")"
end operator

operator *(byref l as mat2, byref r as vec2) as vec2' assume column vector
    return vec2(l.m00 * r.x + l.m01 * r.y, _
                l.m10 * r.x + l.m11 * r.y)
end operator
operator *( byref r as vec2, byref l as mat2) as vec2' assume row vector
    return vec2(l.m00 * r.x + l.m10 * r.y, _
                l.m01 * r.x + l.m11 * r.y)
end operator

operator *(byref l as mat2, byref r as mat2) as mat2
    return mat2(l.m00 * r.m00 + l.m01 * r.m10, _'m00
                l.m10 * r.m00 + l.m11 * r.m10, _'m10
                l.m00 * r.m10 + l.m01 * r.m11, _'m01
                l.m10 * r.m01 + l.m11 * r.m11)  'm11
end operator



'   ########
'  # mat3 #
' ########
type mat3
    declare constructor(d as single=1)
    declare constructor( a as single, b as single, c as single, d as single, e as single, f as single, g as single, h as single, j as single)
    declare constructor(byref a as vec3, byref b as vec3, byref c as vec3)
    
    declare operator cast as string
    
    declare sub setZRotationD(deg as single)
    declare sub setZRotationR(rad as single)
    declare sub setRotationD(byref axis as vec3, deg as single)
    declare sub setRotationR(byref axis as vec3, rad as single)
    declare sub setScaling(byref scale as vec2)
    declare sub setScaling(scale as single)
    declare sub setScaling(scaleX as single, scaleY as single)
    as single m00=any,m10=any,m20=any
    as single m01=any,m11=any,m21=any
    as single m02=any,m12=any,m22=any
end type
constructor mat3(d as single)
    m00=d : m10=0 : m20=0'currect
    m01=0 : m11=d : m21=0 
    m02=0 : m12=0 : m22=d
end constructor
constructor mat3(a as single, b as single, c as single, d as single, e as single, f as single, g as single, h as single, j as single)
    m00=a : m10=b : m20=c'currect
    m01=d : m11=e : m21=f 
    m02=g : m12=h : m22=j
end constructor

constructor mat3(byref a as vec3, byref b as vec3, byref c as vec3)
    m00=a.x : m10=a.y : m20=a.z 'currect
    m01=b.x : m11=b.y : m21=b.z 
    m02=c.x : m12=c.y : m22=c.z
end constructor

operator mat3.cast () as string
    return "(" + str(m00) + ", " + str(m01) + ", " + str(m02) + "), (" + str(m10) + ", " + str(m11) + ", " + str(m12) + "), (" + str(m20) + ", " + str(m21) + ", " + str(m22) + ")"
end operator


sub mat3.setZRotationD(deg as single)
    setZRotationR(deg*Deg2Rad)
end sub
sub mat3.setZRotationR(rad as single)
    dim as single co = cosf(rad)
    dim as single si = sinf(rad)
    m00= co : m10 = si : m20 = 0
    m01=-si : m11 = co : m21 = 0
    m02=  0 : m12 = 0  : m22 = 1
end sub
sub mat3.setRotationD(byref axis as vec3, deg as single)
    setRotationR(axis,deg*Deg2Rad)
end sub
sub mat3.setRotationR(byref axis as vec3, rad as single)
    dim as single co = cosf(rad)
    dim as single si = sinf(rad)
    dim as single oc = 1.0 - co
    m00 = oc * axis.x * axis.x + co
    m10 = oc * axis.x * axis.y - axis.z * si
    m20 = oc * axis.z * axis.x + axis.y * si
    m01 = oc * axis.x * axis.y + axis.z * si
    m11 = oc * axis.y * axis.y + co
    m21 = oc * axis.y * axis.z - axis.x * si
    m02 = oc * axis.z * axis.x - axis.y * si
    m12 = oc * axis.y * axis.z + axis.x * si
    m22 = oc * axis.z * axis.z + co
end sub

sub mat3.setScaling(byref scale as vec2)
    setScaling(scale.x,scale.y)
end sub
sub mat3.setScaling(scale as single)
    setScaling(scale,scale)
end sub
sub mat3.setScaling(scaleX as single, scaleY as single)
    M00 = scaleX : M10 = 0      : M20 = 0
    M01 = 0      : M11 = scaleY : M21 = 0
    M02 = 0      : M12 = 0      : M22 = 1
end sub

operator *(byref l as mat3, byref r as vec3) as vec3' assume column vector
    return vec3(l.m00 * r.x + l.m01 * r.y + l.m02 * r.z, _
                l.m10 * r.x + l.m11 * r.y + l.m12 * r.z, _
                l.m20 * r.x + l.m21 * r.y + l.m22 * r.z)
end operator

operator *(byref r as vec3, byref l as mat3) as vec3' assume row vector
    return vec3(l.m00 * r.x + l.m10 * r.y + l.m20 * r.z, _
                l.m01 * r.x + l.m11 * r.y + l.m21 * r.z, _
                l.m02 * r.x + l.m12 * r.y + l.m22 * r.z)
end operator

operator *(byref l as mat3, byref r as mat3) as mat3
    return mat3(l.m00 * r.m00 + l.m01 * r.m10 + l.m02 * r.m20, _'m00
                l.m10 * r.m00 + l.m11 * r.m10 + l.m12 * r.m20, _'m10
                l.m20 * r.m00 + l.m21 * r.m10 + l.m22 * r.m20, _'m20
                _
                l.m00 * r.m01 + l.m01 * r.m11 + l.m02 * r.m21, _'m01
                l.m10 * r.m01 + l.m11 * r.m11 + l.m12 * r.m21, _'m11
                l.m20 * r.m01 + l.m21 * r.m11 + l.m22 * r.m21, _'m21
                _
                l.m00 * r.m02 + l.m01 * r.m12 + l.m02 * r.m22, _'m02
                l.m10 * r.m02 + l.m11 * r.m12 + l.m12 * r.m22, _'m12
                l.m20 * r.m02 + l.m21 * r.m12 + l.m22 * r.m22)  'm22
end operator


'   ########
'  # mat4 #
' ########
type mat4
    declare constructor(d as single=1)
    declare constructor(a as single,b as single,c as single,d as single,e as single,f as single,g as single,h as single,i as single,j as single,k as single,l as single,m as single,n as single,o as single,p as single) 
    
    declare operator cast as string

    declare sub setProjection(fov as single=45, aspectRatio as single=4/3, near as single=0.1, far as single=100.0)
    declare sub setOrtho2d(x as single, y as single, w as single, h as single)
    declare sub setOrtho2d(x as single, y as single, w as single, h as single, near as single, far as single)
    declare sub setOrtho(left_ as single, right_ as single, bottom as single, top as single, near as single, far as single)

    as single m00=any,m10=any,m20=any,m30=any
    as single m01=any,m11=any,m21=any,m31=any
    as single m02=any,m12=any,m22=any,m32=any
    as single m03=any,m13=any,m23=any,m33=any
end type

constructor mat4(a as single,b as single,c as single,d as single, _
                 e as single,f as single,g as single,h as single, _
                 i as single,j as single,k as single,l as single, _
                 m as single,n as single,o as single,p as single) 
    m00=a : m10=b : m20=c : m30=d
    m01=e : m11=f : m21=g : m31=h
    m02=i : m12=j : m22=k : m32=l
    m03=m : m13=n : m23=o : m33=p
end constructor
constructor mat4(d as single)
    m00=d : m10=0 : m20=0 : m30=0
    m01=0 : m11=d : m21=0 : m31=0
    m02=0 : m12=0 : m22=d : m32=0
    m03=0 : m13=0 : m23=0 : m33=d
end constructor

operator mat4.cast () as string
    return "(" + str(m00) + ", " + str(m01) + ", " + str(m02) + ", " + str(m03) + "), ("_
                + str(m10) + ", " + str(m11) + ", " + str(m12) + ", " + str(m13) + "), ("_
                + str(m20) + ", " + str(m21) + ", " + str(m22) + ", " + str(m23) + "), ("_
                + str(m30) + ", " + str(m31) + ", " + str(m32) + ", " + str(m33) + ")"
end operator

sub mat4.setProjection(fov as single, aspectRatio as single, near as single, far as single)
    dim as single a = 1.0 / tanf((fov * Deg2Rad) * 0.5)
    dim as single b = a / aspectRatio
    dim as single c = (far + near)     / (near - far)
    dim as single d = (2 * far * near) / (near - far)
    m00 = b : m10 = 0 : m20 = 0 : m30 = 0
    m01 = 0 : m11 = b : m21 = 0 : m31 = 0
    m02 = 0 : m12 = 0 : m22 = c : m32 =-1
    m03 = 0 : m13 = 0 : m23 = d : m33 = 0
end sub



sub mat4.setOrtho2d(x as single, y as single, w as single, h as single)
    setOrtho( x, x + w, y + h, y, 1, -1)
end sub
sub mat4.setOrtho2d(x as single, y as single, w as single, h as single, near as single, far as single)
    setOrtho( x, x + w, y, y + h, near, far)
end sub

sub mat4.setOrtho(left_ as single, right_ as single, bottom as single, top as single, near as single, far as single)
    dim as single x_orth = 2 / (right_ - left_)
    dim as single y_orth = 2 / (top    - bottom)
    dim as single z_orth =-2 / (far    - near)
    dim as single tx = -(right_ + left_ ) / (right_ - left_)
    dim as single ty = -(top    + bottom) / (top    - bottom)
    dim as single tz = -(far    + near  ) / (far    - near)
    m00 = x_orth : m10 = 0      : m20 = 0      : m30 = 0
    m01 = 0      : m11 = y_orth : m21 = 0      : m31 = 0
    m02 = 0      : m12 = 0      : m22 = z_orth : m32 = 0
    m03 = tx     : m13 = ty     : m23 = tz     : m33 = 1
end sub

operator *(byref l as mat4, byref r as vec4) as vec4'assume column vector
    return vec4(l.m00 * r.x + l.m01 * r.y + l.m02 * r.z + l.m03 * r.w, _
                l.m10 * r.x + l.m11 * r.y + l.m12 * r.z + l.m13 * r.w, _
                l.m20 * r.x + l.m21 * r.y + l.m22 * r.z + l.m23 * r.w, _
                l.m30 * r.x + l.m31 * r.y + l.m32 * r.z + l.m33 * r.w)
end operator

operator *(byref r as vec4, byref l as mat4) as vec4' assume row vector
    return vec4(l.m00 * r.x + l.m10 * r.y + l.m20 * r.z + l.m30 * r.w, _
                l.m01 * r.x + l.m11 * r.y + l.m21 * r.z + l.m31 * r.w, _
                l.m02 * r.x + l.m12 * r.y + l.m22 * r.z + l.m32 * r.w, _
                l.m03 * r.x + l.m13 * r.y + l.m23 * r.z + l.m33 * r.w)
end operator

operator *(byref l as mat4, byref r as mat4) as mat4
    return mat4( _
    l.m00 * r.m00 + l.m01 * r.m10 + l.m02 * r.m20 + l.m03 * r.m30, _'m00
    l.m10 * r.m00 + l.m11 * r.m10 + l.m12 * r.m20 + l.m13 * r.m30, _'m10
    l.m20 * r.m00 + l.m21 * r.m10 + l.m22 * r.m20 + l.m23 * r.m30, _'m20
    l.m30 * r.m00 + l.m31 * r.m10 + l.m32 * r.m20 + l.m33 * r.m30, _'m30
    _
    l.m00 * r.m01 + l.m01 * r.m11 + l.m02 * r.m21 + l.m03 * r.m31, _'m01
    l.m10 * r.m01 + l.m11 * r.m11 + l.m12 * r.m21 + l.m13 * r.m31, _'m11
    l.m20 * r.m01 + l.m21 * r.m11 + l.m22 * r.m21 + l.m23 * r.m31, _'m21
    l.m30 * r.m01 + l.m31 * r.m11 + l.m32 * r.m21 + l.m33 * r.m31, _'m31
    _
    l.m00 * r.m02 + l.m01 * r.m12 + l.m02 * r.m22 + l.m03 * r.m32, _'m02
    l.m10 * r.m02 + l.m11 * r.m12 + l.m12 * r.m22 + l.m13 * r.m32, _'m12
    l.m20 * r.m02 + l.m21 * r.m12 + l.m22 * r.m22 + l.m23 * r.m32, _'m22
    l.m30 * r.m02 + l.m31 * r.m12 + l.m32 * r.m22 + l.m33 * r.m32, _'m32
    _
    l.m00 * r.m03 + l.m01 * r.m13 + l.m02 * r.m23 + l.m03 * r.m33, _'m03
    l.m10 * r.m03 + l.m11 * r.m13 + l.m12 * r.m23 + l.m13 * r.m33, _'m13
    l.m20 * r.m03 + l.m21 * r.m13 + l.m22 * r.m23 + l.m23 * r.m33, _'m23
    l.m30 * r.m03 + l.m31 * r.m13 + l.m32 * r.m23 + l.m33 * r.m33)  'm33
end operator



' The matrixCompMult function returns a matrix resulting from a component-wise multiplication. 
' The function has two input parameters of the type singleing point matrix and returns a matrix of the same type. 
' The indices of the returned matrix are calculated as follows: z[i][j] = x[i][j] * y[i][j]
' Side note: This is NOT the matrix multiplication known from linear algebra. 
' To obtain the "normal" matrix multiplication the * operator is used: z = x * y
function matrixCompMult overload (byref x as mat2,byref y as mat2) as mat2
    dim as mat2 z
    dim as single ptr pz=@z.m00,px=@x.m00,py=@y.m00
    dim as integer i2
    for i as integer = 0 to 1
        dim as integer ij=i2
        for j as integer = 0 to 1
            pz[ij] = px[ij] * py[ij] :ij+=1
        next
        i2+=2
    next
    return z
end function
function matrixCompMult (byref x as mat3, byref y as mat3) as mat3
    dim as mat3 z
    dim as single ptr pz=@z.m00,px=@x.m00,py=@y.m00
    dim as integer i3
    for i as integer = 0 to 1
    dim as integer ij=i3
        for j as integer = 0 to 1
            pz[ij] = px[ij] * py[ij] :ij+=1
        next
        i3+=3
    next
    return z
end function
function matrixCompMult (byref x as mat4, byref y as mat4) as mat4
    dim as mat4 z
    dim as single ptr pz=@z.m00,px=@x.m00,py=@y.m00
    dim as integer i4
    for i as integer = 0 to 1
        dim as integer ij=i4
        for j as integer = 0 to 1
            pz[ij] = px[ij] * py[ij] :ij+=1
        next
        i4+=4
    next
    return z
end function
vecn.bi

Code: Select all

'Original glslstyle.bi by D.J. Peters.
'Edited by ShawnLG.
'Cleaned up source.
'Fix bugs.
'Added features for better compatibility with freebasic.
'Seperated datatypes into their own .bi files.

#include once "crt.bi" ' math.bi ...
#define DEG2RAD M_PI/180.0
#define RAD2DEG 180.0/M_PI

#undef atn
#undef exp
#undef log
#undef sqrt
#undef exp2
#undef log2
#undef pow
#undef ceil
#undef floor


'   ########
'  # vec2 #
' ########

type vec2
    declare constructor
    declare constructor(pxy as single)
    declare constructor(px as single, py as single)
    declare constructor(byref v2 as vec2)
    'assignment operators
    declare operator let(pxy as single)
    declare operator let(byref p as vec2)
    'cast as string for print function
    declare operator cast() as String
    'evaluate and assign
    declare operator +=(v as single)
    declare operator -=(v as single)
    declare operator *=(v as single)
    declare operator /=(v as single)
  
    declare operator +=(byref v2 as vec2)
    declare operator -=(byref v2 as vec2)
    declare operator *=(byref v2 as vec2)
    declare operator /=(byref v2 as vec2)
    'Swizzle functions
    declare function xx as vec2
    declare function xy as vec2
    declare function yx as vec2
    declare function yy as vec2
    'Common letters used by vectors
    union : as single x,u,s : end union
    union : as single y,v,t : end union
end type

constructor vec2
end constructor
constructor vec2(pxy as single)
    x=pxy : y=pxy
end constructor
constructor vec2(px as single, py as single)
    x=px : y=py
end constructor
constructor vec2(byref v2 as vec2)
    x=v2.x : y=v2.y
end constructor

operator vec2.let(pxy as single)
    x=pxy:y=pxy
end operator
operator vec2.let(byref p as vec2)
    x=p.x:y=p.y
end operator

operator vec2.cast () as string
    return "(" + str(x) + ", " + str(y) +  ")"
end operator

operator vec2.+=(v as single)
    x+=v : y+=v
end operator
operator vec2.-=(v as single)
    x-=v : y-=v
end operator
operator vec2.*=(v as single)
    x*=v : y*=v
end operator
operator vec2./=(v as single)
    x/=v : y/=v
end operator  

operator vec2.+=(byref v2 as vec2)
    x+=v2.x : y+=v2.y
end operator
operator vec2.-=(byref v2 as vec2)
    x-=v2.x : y-=v2.y
end operator
operator vec2.*=(byref v2 as vec2)
    x*=v2.x : y*=v2.y
end operator
operator vec2./=(byref v2 as vec2)
    x/=v2.x : y/=v2.y
end operator

function vec2.xx as vec2
    return vec2(x,x)
end function
function vec2.xy as vec2
    return vec2(x,y)
end function
function vec2.yx as vec2
    return vec2(y,x)
end function
function vec2.yy as vec2
    return vec2(y,y)
end function

operator -(byref l as vec2) as vec2
    return vec2(-l.x, -l.y)
end operator
operator +(byref l as vec2, byref r as vec2) as vec2
    return vec2(l.x+r.x, l.y+r.y)
end operator
operator +(byref l as vec2, byref r as single) as vec2
    return vec2(l.x+r, l.y+r)
end operator
operator +(byref l as single, byref r as vec2) as vec2
    return vec2(r.x+l, r.y+l)
end operator

operator -(byref l as vec2, byref r as vec2) as vec2
    return vec2(l.x-r.x, l.y-r.y)
end operator
operator -(byref l as vec2, byref r as single) as vec2
    return vec2(l.x-r, l.y-r)
end operator
operator -(byref l as single, byref r as vec2) as vec2
    return vec2(r.x-l, r.y-l)
end operator


operator *(byref l as vec2, byref r as vec2) as vec2
    return vec2(l.x*r.x, l.y*r.y)
end operator
operator *(byref l as vec2, byref r as single) as vec2
    return vec2(l.x*r, l.y*r)
end operator
operator *(byref l as single, byref r as vec2) as vec2
    return vec2(l*r.x, l*r.y)
end operator
operator /(byref l as vec2, byref r as vec2) as vec2
    return vec2(l.x/r.x, l.y/r.y)
end operator

operator =(byref l as vec2,byref r as vec2) as integer 
    if (l.x xor r.x) or (l.y xor r.y) then return 0
    return -1
end operator
operator <>(byref l as vec2,byref r as vec2) as integer
    if (l.x xor r.x) or (l.y xor r.y) then return -1
    return 0
end operator

'   ########
'  # vec3 #
' ########

type vec3
    declare constructor
    declare constructor(pxyz as single)
    declare constructor(px as single, py as single, pz as single)
    declare constructor(byref v2 as vec2, pz as single)
    declare constructor(px as single, byref v2 as vec2)
    declare constructor(byref v3 as vec3)
    
    declare operator let(pxyz as single)
    declare operator let(byref p as vec2)
    declare operator let(byref p as vec3)

    declare operator cast as string
    declare operator cast as ulong

    declare operator +=(v as single)
    declare operator -=(v as single)
    declare operator *=(v as single)
    declare operator /=(v as single)
  
    declare operator +=(byref v3 as vec3)
    declare operator -=(byref v3 as vec3)
    declare operator *=(byref v3 as vec3)
    declare operator /=(byref v3 as vec3)

    declare function xx as vec2
    declare function xy as vec2
  
    declare function xz as vec2
    declare function yx as vec2
    declare function yy as vec2
    declare function yz as vec2
  
    declare function zx as vec2
    declare function zy as vec2
    declare function zz as vec2

    declare function xxx as vec3
    declare function xxy as vec3
    declare function xxz as vec3
    declare function xyx as vec3
    declare function xyy as vec3
    declare function xyz as vec3
    declare function xzx as vec3
    declare function xzy as vec3
    declare function xzz as vec3
  
    declare function yxx as vec3
    declare function yxy as vec3
    declare function yxz as vec3
    declare function yyx as vec3
    declare function yyy as vec3
    declare function yyz as vec3
    declare function yzx as vec3
    declare function yzy as vec3
    declare function yzz as vec3
  
    declare function zxx as vec3
    declare function zxy as vec3
    declare function zxz as vec3
    declare function zyx as vec3
    declare function zyy as vec3
    declare function zyz as vec3
    declare function zzx as vec3
    declare function zzy as vec3
    declare function zzz as vec3

    declare function rgb as vec3
    
    union : as single x,r,s : end union
    union : as single y,g,t : end union
    union : as single z,b,p : end union
end type
constructor vec3
end constructor
constructor vec3(pxyz as single)
    x=pxyz : y=pxyz : z=pxyz
end constructor
constructor vec3(px as single, py as single, pz as single)
    x=px : y=py : z=pz
end constructor
constructor vec3(byref v2 as vec2,pz as single)
    x=v2.x : y=v2.y : z=pz
end constructor
constructor vec3(px as single,byref v2 as vec2)
    x=px : y=v2.x : z=v2.y
end constructor
constructor vec3(byref v3 as vec3)
    x=v3.x : y=v3.y :z = v3.z
end constructor

operator vec3.let(pxyz as single)
    x=pxyz:y=pxyz:z=pxyz
end operator
operator vec3.let(byref p as vec2)
    x=p.x:y=p.y:z=1
end operator
operator vec3.let(byref p as vec3)
    x=p.x:y=p.y:z=p.z
end operator

operator vec3.cast () as string
    return "(" + str(x) + ", " + str(y) + ", " + str(z) + ")"
end operator

operator vec3.cast as ulong
    dim as ulong t = any
    dim as ulong a = 255
    #macro clip(v)  
        a shl = 8
        if v < 0 then 
        elseif v > 1 then
            a or = 255
        else
            t = v * 255
            a or = t
        end if  
    #endmacro
    clip(x)
    clip(y)
    clip(z)  
    #undef clip
    return a
end operator

operator vec3.+=(v as single)
    x+=v : y+=v : z+=v
end operator
operator vec3.-=(v as single)
    x-=v : y-=v : z-=v
end operator
operator vec3.*=(v as single)
    x*=v : y*=v : z*=v
end operator
operator vec3./=(v as single)
    x/=v : y/=v : z/=v
end operator  

operator vec3.+=(byref v3 as vec3)
    x+=v3.x : y+=v3.y : z+=v3.z
end operator
operator vec3.-=(byref v3 as vec3)
    x-=v3.x : y-=v3.y : z-=v3.z
end operator
operator vec3.*=(byref v3 as vec3)
    x*=v3.x : y*=v3.y : z*=v3.z
end operator
operator vec3./=(byref v3 as vec3)
    x/=v3.x : y/=v3.y : z/=v3.z
end operator

function vec3.xx as vec2
    return vec2(x,x)
end function 
function vec3.xy as vec2
    return vec2(x,y)
end function 
function vec3.xz as vec2
    return vec2(x,z)
end function 
function vec3.yx as vec2
    return vec2(y,x)
end function 
function vec3.yy as vec2
    return vec2(y,y)
end function 
function vec3.yz as vec2
    return vec2(y,z)
end function 
function vec3.zx as vec2
    return vec2(z,x)
end function 
function vec3.zy as vec2
    return vec2(z,y)
end function 
function vec3.zz as vec2
    return vec2(z,z)
end function 

function vec3.xxx as vec3
    return vec3(x,x,x)
end function
function vec3.xxy as vec3
    return vec3(x,x,y)
end function
function vec3.xxz as vec3
    return vec3(x,x,z)
end function
function vec3.xyx as vec3
    return vec3(x,y,x)
end function
function vec3.xyy as vec3
    return vec3(x,y,y)
end function
function vec3.xyz as vec3
    return vec3(x,y,z)
end function
function vec3.xzx as vec3
    return vec3(x,z,x)
end function
function vec3.xzy as vec3
    return vec3(x,z,y)
end function
function vec3.xzz as vec3
    return vec3(x,z,z)
end function

function vec3.yxx as vec3
    return vec3(y,x,x)
end function
function vec3.yxy as vec3
    return vec3(y,x,y)
end function
function vec3.yxz as vec3
    return vec3(y,x,z)
end function
function vec3.yyx as vec3
    return vec3(y,y,x)
end function
function vec3.yyy as vec3
    return vec3(y,y,y)
end function
function vec3.yyz as vec3
    return vec3(y,y,z)
end function
function vec3.yzx as vec3
    return vec3(y,z,x)
end function
function vec3.yzy as vec3
    return vec3(y,z,y)
end function
function vec3.yzz as vec3
    return vec3(y,z,z)
end function

function vec3.zxx as vec3
    return vec3(z,x,x)
end function
function vec3.zxy as vec3
    return vec3(z,x,y)
end function
function vec3.zxz as vec3
    return vec3(z,x,z)
end function
function vec3.zyx as vec3
    return vec3(z,y,x)
end function
function vec3.zyy as vec3
    return vec3(z,y,y)
end function
function vec3.zyz as vec3
    return vec3(z,y,z)
end function
function vec3.zzx as vec3
    return vec3(z,z,x)
end function
function vec3.zzy as vec3
    return vec3(z,z,y)
end function
function vec3.zzz as vec3
    return vec3(z,z,z)
end function

function vec3.rgb as vec3
    return vec3(x,y,z)
end function

operator -(byref l as vec3) as vec3
    return vec3(-l.x, -l.y, -l.z)
end operator

operator +(byref l as vec3, r as single) as vec3
    return vec3(l.x+r, l.y+r, l.z+r)
end operator
operator +(l as single, byref r as vec3) as vec3
    return vec3(r.x+l, r.y+l, r.z+l)
end operator
operator -(byref l as vec3, r as single) as vec3
    return vec3(l.x-r, l.y-r, l.z-r)
end operator
operator -(l as single, byref r as vec3) as vec3
    return vec3(r.x-l, r.y-l, r.z-l)
end operator
operator *(byref l as vec3, r as single) as vec3
    return vec3(l.x*r, l.y*r, l.z*r)
end operator
operator *(l as single, byref r as vec3) as vec3
    return vec3(r.x*l, r.y*l, r.z*l)
end operator
operator /(byref l as vec3, r as single) as vec3
    return vec3(l.x/r, l.y/r, l.z/r)
end operator
operator /(l as single, byref r as vec3) as vec3
    return vec3(r.x/l, r.y/l, r.z/l)
end operator

operator +(byref l as vec3, byref r as vec3) as vec3
    return vec3(l.x+r.x, l.y+r.y, l.z+r.z)
end operator
operator -(byref l as vec3,byref r as vec3) as vec3
    return vec3(l.x-r.x, l.y-r.y, l.z-r.z)
end operator
operator *(byref l as vec3, byref r as vec3) as vec3
    return vec3(l.x*r.x, l.y*r.y, l.z*r.z)
end operator
operator /(byref l as vec3, byref r as vec3) as vec3
    return vec3(l.x/r.x, l.y/r.y, l.z/r.z)
end operator

operator =(byref l as vec3, byref r as vec3) as integer 
    if (l.x xor r.x) or (l.y xor r.y) or (l.z xor r.z) then return 0
    return -1
end operator
operator <>(byref l as vec3, byref r as vec3) as integer
    if (l.x xor r.x) or (l.y xor r.y) or (l.z xor r.z) then return -1
    return 0
end operator

'   ########
'  # vec4 #
' ########

type vec4
    declare constructor
    declare constructor(pxyz as single, pw as single=1)
    declare constructor(px as single, py as single, pz as single, pw as single=1)
    declare constructor(byref v1 as vec2, pz as single, pw as single)
    declare constructor(byref v1 as vec2, byref v2 as vec2)
    declare constructor(byref v3 as vec3, pw as single=1)
    declare constructor(px as single, byref v3 as vec3)
    declare constructor(byref v4 as vec4)

    declare operator let(pxyzw as single)
    declare operator let(byref p as vec2)
    declare operator let(byref p as vec3)
    declare operator let(byref p as vec4)
    
    declare operator cast as string
    declare operator cast as ulong

    declare operator +=(v as single)
    declare operator -=(v as single)
    declare operator *=(v as single)
    declare operator /=(v as single)
  
    declare operator +=(byref v3 as vec3)
    declare operator -=(byref v3 as vec3)
    declare operator *=(byref v3 as vec3)
    declare operator /=(byref v3 as vec3)
  
    declare operator +=(byref v4 as vec4)
    declare operator -=(byref v4 as vec4)
    declare operator *=(byref v4 as vec4)
    declare operator /=(byref v4 as vec4)

    declare function xx as vec2
    declare function xy as vec2
  
    declare function xz as vec2
    declare function yx as vec2
    declare function yy as vec2
    declare function yz as vec2
  
    declare function zx as vec2
    declare function zy as vec2
    declare function zz as vec2

    declare function xxx as vec3
    declare function xxy as vec3
    declare function xxz as vec3
    declare function xyx as vec3
    declare function xyy as vec3
    declare function xyz as vec3
    declare function xzx as vec3
    declare function xzy as vec3
    declare function xzz as vec3
  
    declare function yxx as vec3
    declare function yxy as vec3
    declare function yxz as vec3
    declare function yyx as vec3
    declare function yyy as vec3
    declare function yyz as vec3
    declare function yzx as vec3
    declare function yzy as vec3
    declare function yzz as vec3
  
    declare function zxx as vec3
    declare function zxy as vec3
    declare function zxz as vec3
    declare function zyx as vec3
    declare function zyy as vec3
    declare function zyz as vec3
    declare function zzx as vec3
    declare function zzy as vec3
    declare function zzz as vec3

    declare function rgb  as vec3
    declare function rgba as vec4

    union : as single x,r,s : end union
    union : as single y,g,t : end union
    union : as single z,b,p : end union
    union : as single w,a,q : end union
end type  

constructor vec4
    w=1
end constructor
constructor vec4(pxyz as single, pw as single)
    x=pxyz: y=pxyz : z=pxyz : w=pw
end constructor
constructor vec4(px as single, py as single, pz as single, pw as single)
    x=px : y=py : z=pz : w=pw
end constructor
constructor vec4(byref v1 as vec2, pz as single, pw as single)
    x=v1.x : y=v1.y : z=pz : w=pw
end constructor
constructor vec4(byref v1 as vec2, byref v2 as vec2)
    x=v1.x : y= v1.y : z=v2.x : w=v2.y
end constructor
constructor vec4(byref v3 as vec3, pw as single)
    x=v3.x : y=v3.y : z=v3.z : w=pw
end constructor
constructor vec4(px as single, byref v3 as vec3)
    x=px : y= v3.x : z=v3.y : w=v3.z
end constructor
constructor vec4(byref v4 as vec4)
    x=v4.x : y=v4.y : z=v4.z : w=v4.w
end constructor

operator vec4.let(pxyzw as single)
    x=pxyzw: y=pxyzw : z=pxyzw : w=pxyzw
end operator
operator vec4.let(byref p as vec2)
    x=p.x:y=p.y:z=1:w=1
end operator
operator vec4.let(byref p as vec3)
    x=p.x:y=p.y:z=p.z:w=1
end operator
operator vec4.let(p as vec4)
    x=p.x:y=p.y:z=p.z:w=p.w
end operator
operator vec4.cast () as string
    return "(" + str(x) + ", " + str(y) + ", " + str(z) + ", " + str(w) + ")"
end operator

operator vec4.cast as ulong
    dim as ulong c
    #macro clip255(v)  
        c shl = 8
        if v < 1/255 then
        elseif v > 1 then
        c or = 255
        else
        c or = v * 255
        end if
    #endmacro
    clip255(w)
    clip255(x)
    clip255(y)
    clip255(z)
    #undef clip255
    return c
end operator

operator vec4.+=(v as single)
    x+=v : y+=v : z+=v : w+=v
end operator
operator vec4.-=(v as single)
    x-=v : y-=v : z-=v : w-=v
end operator
operator vec4.*=(v as single)
    x*=v : y*=v : z*=v : w*=v
end operator
operator vec4./=(v as single)
    x/=v : y/=v : z/=v : w/=v
end operator  

operator vec4.+=(byref v3 as vec3)
    x+=v3.x : y+=v3.y : z+=v3.z
end operator
operator vec4.-=(byref v3 as vec3)
    x-=v3.x : y-=v3.y : z-=v3.z
end operator
operator vec4.*=(byref v3 as vec3)
    x*=v3.x : y*=v3.y : z*=v3.z
end operator
operator vec4./=(byref v3 as vec3)
    x/=v3.x : y/=v3.y : z/=v3.z
end operator

operator vec4.+=(byref v4 as vec4)
    x+=v4.x : y+=v4.y : z+=v4.z : w+=v4.w
end operator
operator vec4.-=(byref v4 as vec4)
    x-=v4.x : y-=v4.y : z-=v4.z : w-=v4.w
end operator
operator vec4.*=(byref v4 as vec4)
    x*=v4.x : y*=v4.y : z*=v4.z : w*=v4.w
end operator
operator vec4./=(byref v4 as vec4)
    x/=v4.x : y/=v4.y : z/=v4.z : w/=v4.w
end operator

function vec4.xx as vec2
    return vec2(x,x)
end function 
function vec4.xy as vec2
    return vec2(x,y)
end function 
function vec4.xz as vec2
    return vec2(y,z)
end function 
function vec4.yx as vec2
    return vec2(y,x)
end function 
function vec4.yy as vec2
    return vec2(y,y)
end function 
function vec4.yz as vec2
    return vec2(y,z)
end function 
function vec4.zx as vec2
    return vec2(z,x)
end function 
function vec4.zy as vec2
    return vec2(z,y)
end function 
function vec4.zz as vec2
    return vec2(z,z)
end function 

function vec4.xxx as vec3
    return vec3(x,x,x)
end function
function vec4.xxy as vec3
    return vec3(x,x,y)
end function
function vec4.xxz as vec3
    return vec3(x,x,z)
end function
function vec4.xyx as vec3
    return vec3(x,y,x)
end function
function vec4.xyy as vec3
    return vec3(x,y,y)
end function
function vec4.xyz as vec3
    return vec3(x,y,z)
end function
function vec4.xzx as vec3
    return vec3(x,z,x)
end function
function vec4.xzy as vec3
    return vec3(x,z,y)
end function
function vec4.xzz as vec3
    return vec3(x,z,z)
end function

function vec4.yxx as vec3
    return vec3(y,x,x)
end function
function vec4.yxy as vec3
    return vec3(y,x,y)
end function
function vec4.yxz as vec3
    return vec3(y,x,z)
end function
function vec4.yyx as vec3
    return vec3(y,y,x)
end function
function vec4.yyy as vec3
    return vec3(y,y,y)
end function
function vec4.yyz as vec3
    return vec3(y,y,z)
end function
function vec4.yzx as vec3
    return vec3(y,z,x)
end function
function vec4.yzy as vec3
    return vec3(y,z,y)
end function
function vec4.yzz as vec3 
    return vec3(y,z,z)
end function

function vec4.zxx as vec3
    return vec3(z,x,x)
end function
function vec4.zxy as vec3
    return vec3(z,x,y)
end function
function vec4.zxz as vec3
    return vec3(z,x,z)
end function
function vec4.zyx as vec3
    return vec3(z,y,x)
end function
function vec4.zyy as vec3
    return vec3(z,y,y)
end function
function vec4.zyz as vec3
    return vec3(z,y,z)
end function
function vec4.zzx as vec3
    return vec3(z,z,x)
end function
function vec4.zzy as vec3
    return vec3(z,z,y)
end function
function vec4.zzz as vec3
    return vec3(z,z,z)
end function

function vec4.rgb as vec3
    return vec3(x,y,z)
end function  
function vec4.rgba as vec4
    return vec4(x,y,z,w)
end function  

operator -(byref l as vec4) as vec4
    return vec4(-l.x, -l.y, -l.z, -l.w)
end operator
operator +(byref l as vec4, byref r as vec4) as vec4
    return vec4(l.x+r.x, l.y+r.y, l.z+r.z, l.w+r.w)
end operator
operator -(byref l as vec4, byref r as vec4) as vec4
    return vec4(l.x-r.x, l.y-r.y, l.z-r.z, l.w-r.w)
end operator
operator *(byref l as vec4, byref r as vec4) as vec4
    return vec4(l.x*r.x, l.y*r.y, l.z*r.z, l.w*r.w)
end operator
operator /(byref l as vec4, byref r as vec4) as vec4
    return vec4(l.x/r.x, l.y/r.y, l.z/r.z, l.w/r.w)
end operator

' vec4 single
operator +(byref l as vec4, r as single) as vec4
    return vec4(l.x+r, l.y+r, l.z+r, l.w+r)
end operator
operator +(l as single, byref r as vec4) as vec4
    return vec4(r.x+l, r.y+l, r.z+l, r.w+l)
end operator

operator -(byref l as vec4, r as single) as vec4
    return vec4(l.x-r, l.y-r, l.z-r, l.w-r)
end operator
operator -(l as single, byref r as vec4) as vec4
    return vec4(r.x-l, r.y-l, r.z-l, r.w-l)
end operator

operator *(byref l as vec4, r as single) as vec4
    return vec4(l.x*r, l.y*r, l.z*r, l.w*r)
end operator
operator *(l as single, byref r as vec4) as vec4
    return vec4(l*r.x, l*r.y, l*r.z, l*r.w)
end operator

operator /(byref l as vec4, r as single) as vec4
    return vec4(l.x/r, l.y/r, l.z/r, l.w/r)
end operator
operator /(l as single, byref r as vec4) as vec4
    return vec4(r.x/l, r.y/l, r.z/l, r.w/l)
end operator


operator +(byref l as vec4, byref r as vec3) as vec4
    return vec4(l.x+r.x, l.y+r.y, l.z+r.z, l.w)
end operator
operator +(byref l as vec3, byref r as vec4) as vec4
    return vec4(l.x+r.x, l.y+r.y, l.z+r.z)
end operator

operator -(byref l as vec4, byref r as vec3) as vec4
    return vec4(l.x-r.x, l.y-r.y, l.z-r.z, l.w)
end operator
operator -(byref l as vec3, byref r as vec4) as vec4
    return vec4(l.x-r.x, l.y-r.y, l.z-r.z)
end operator

operator *(byref l as vec4, byref r as vec3) as vec4
    return vec4(l.x*r.x, l.y*r.y, l.z*r.z, l.w)
end operator
operator *(byref l as vec3, byref r as vec4) as vec4
    return vec4(l.x*r.x, l.y*r.y, l.z*r.z)
end operator

operator /(byref l as vec4, byref r as vec3) as vec4
    return vec4(l.x/r.x, l.y/r.y, l.z/r.z, l.w)
end operator
operator /(byref l as vec3, byref r as vec4) as vec4
    return vec4(l.x/r.x, l.y/r.y, l.z/r.z)
end operator

operator =(byref l as vec4,byref r as vec4) as integer 
    if (l.x xor r.x) or (l.y xor r.y) or (l.z xor r.z) or (l.w xor r.w) then return 0
    return -1
end operator
operator <>(byref l as vec4,byref r as vec4) as integer
    if (l.x xor r.x) or (l.y xor r.y) or (l.z xor r.z) or (l.w xor r.w) then return -1
    return 0
end operator

#include once "vecn_functions.bi"
Last edited by ShawnLG on Sep 25, 2019 5:17, edited 1 time in total.
ShawnLG
Posts: 142
Joined: Dec 25, 2008 20:21

Re: Raymarching Shadertoy demo meets multicore

Post by ShawnLG »

vecn_functions.bi

Code: Select all

'Original glslstyle.bi by D.J. Peters.
'Edited by ShawnLG.
'Cleaned up source.
'Fix bugs.
'Added features for better compatibility with freebasic.
'Seperated datatypes into their own .bi files.



'Functions used for vec# data types

Enum ePlaneSide
    OnPlane
    FrontSide
    BackSide
end enum
type plane
    declare constructor
    declare constructor (byref normal as vec3,byref v as vec3)
    declare function getDistance(byref v as vec3) as single 
    declare function getSide(byref v as vec3) as ePlaneSide
    declare function intersect(byref rayOrigin as vec3,byref rayDirection as vec3,byref t as single) as boolean
    as vec3 n = any
    as single d = any
end type
constructor plane
    n.x=0 : n.y=1 : n.z=0 : d=0
end constructor
constructor plane(byref normal as vec3, byref v as vec3)
    n=normal : d=-(n.x*v.x + n.y*v.y + n.y*v.x)
end constructor
function plane.getDistance(byref v as vec3) as single
    return n.x*v.x + n.y*v.y + n.y*v.x + d
end function
function plane.getSide(byref v as vec3) as ePlaneSide
    dim as single dist = n.x*v.x + n.y*v.y + n.y*v.x + d
    if (dist = 0) then return OnPlane
    if (dist < 0) then return BackSide
    return FrontSide
end function
function plane.intersect(byref rayOrigin as vec3,byref rayDirection as vec3,byref resultT as single) as boolean
    dim as single denom = n.x*rayDirection.x + n.y*rayDirection.y + n.y*rayDirection.x
    if fabs(denom) < 0.001 then return false
    dim as vec3 planeCenter = vec3(n.x*d,n.y*d,n.z*d)
    planeCenter.x-=rayOrigin.x
    planeCenter.y-=rayOrigin.y
    planeCenter.z-=rayOrigin.z
    dim as single t = (planeCenter.x*n.x + planeCenter.y*n.y + planeCenter.z*n.z) / denom
    if t < 0.001 then return false
    resultT = t
    return true
end function



' OpenGL shader language http://www.shaderific.com/glsl-functions/

' The radians function converts degrees to radians. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector all components are converted from degrees to radians separately.
function radiance overload (deg as single) as single
    return deg*Deg2Rad
end function
function radiance (byref v as vec2) as vec2
    return vec2(v.x*Deg2Rad,v.y*Deg2Rad)
end function
function radiance (byref v as vec3) as vec3
    return vec3(v.x*Deg2Rad,v.y*Deg2Rad,v.y*Deg2Rad)
end function
function radiance (byref v as vec4) as vec4
    return vec4(v.x*Deg2Rad,v.y*Deg2Rad,v.y*Deg2Rad,v.w*Deg2Rad)
end function

' The degrees function converts radians to degrees.
' The input parameter can be a singleing scalar or a single vector.
' In case of a single vector every component is converted from radians to degrees separately.
function degrees overload (rad as single) as single
    return rad*Rad2Deg
end function
function degrees (byref v as vec2) as vec2
    return vec2(v.x*Rad2Deg,v.y*Rad2Deg)
end function
function degrees (byref v as vec3) as vec3
    return vec3(v.x*Rad2Deg,v.y*Rad2Deg,v.y*Rad2Deg)
end function
function degrees (byref v as vec4) as vec4
    return vec4(v.x*Rad2Deg,v.y*Rad2Deg,v.y*Rad2Deg,v.w*Rad2Deg)
end function

' The sin function returns the sine of an angle in radians. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the sine is calculated separately for every component.
operator sin(byref v as vec2) as vec2
    return vec2(sinf(v.x),sinf(v.y))
end operator
operator sin(byref v as vec3) as vec3
    return vec3(sinf(v.x),sinf(v.y),sinf(v.z))
end operator
operator sin(byref v as vec4) as vec4
    return vec4(sinf(v.x),sinf(v.y),sinf(v.z),sinf(v.w))
end operator

' The cos function returns the cosine of an angle in radians. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the cosine is calculated separately for every component.
operator cos(byref v as vec2) as vec2
    return vec2(cosf(v.x),cosf(v.y))
end operator
operator cos(byref v as vec3) as vec3
    return vec3(cosf(v.x),cosf(v.y),cosf(v.z))
end operator
operator cos(byref v as vec4) as vec4
    return vec4(cosf(v.x),cosf(v.y),cosf(v.z),cosf(v.w))
end operator

' The tan function returns the tangent of an angle in radians. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the tangent is calculated separately for every component.
operator tan(byref v as vec2) as vec2
    return vec2(tanf(v.x),tanf(v.y))
end operator
operator tan(byref v as vec3) as vec3
    return vec3(tanf(v.x),tan(v.y),tanf(v.z))
end operator
operator tan(byref v as vec4) as vec4
    return vec4(tanf(v.x),tanf(v.y),tanf(v.z),tanf(v.w))
end operator


' The asin function returns the arcsine of an angle in radians. 
' It is the inverse function of sine. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the arcsine is calculated separately for every component.
operator asin(byref v as vec2) as vec2
    return vec2(asinf(v.x),asinf(v.y))
end operator
operator asin(byref v as vec3) as vec3
    return vec3(asinf(v.x),asinf(v.y),asinf(v.z))
end operator
operator asin(byref v as vec4) as vec4
    return vec4(asinf(v.x),asinf(v.y),asinf(v.z),asinf(v.w))
end operator

' The acos function returns the arccosine of an angle in radians. 
' It is the inverse function of cosine. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the arccosine is calculated separately for every component.
operator acos(byref v as vec2) as vec2
    return vec2(acosf(v.x),acosf(v.y))
end operator
operator acos(byref v as vec3) as vec3
    return vec3(acosf(v.x),acosf(v.y),acosf(v.z))
end operator
operator acos(byref v as vec4) as vec4
    return vec4(acosf(v.x),acosf(v.y),acosf(v.z),acosf(v.w))
end operator

' The atan function returns the arctangent of an angle in radians. 
' It is the inverse function of tangent. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the arctangent is calculated separately for every component.
function atan overload(x as single,y as single) as single
    return atan2f(x,y)
end function
function atan(byref x as vec2,byref y as vec2) as vec2
    return vec2(atan2f(x.x,y.x),atan2f(x.y,y.y))
end function
function atan(byref x as vec3,byref y as vec3) as vec3
    return vec3(atan2f(x.x,y.x),atan2f(x.y,y.y),atan2f(x.z,y.z))
end function
function atan(byref x as vec4,byref y as vec4) as vec4
    return vec4(atan2f(x.x,y.x),atan2f(x.y,y.y),atan2f(x.z,y.z),atan2f(x.w,y.w))
end function

' The pow function returns x raised to the power of y. 
' The input parameters can be singleing scalars or single vectors. 
' In case of single vectors the operation is done component-wise.
function pow overload(a as single, b as single) as single
    return powf(a,b)
end function
function pow (byref a as vec2, byref b as vec2) as vec2
    return vec2(powf(a.x,b.x),powf(a.y,b.y))
end function
function pow (byref a as vec3, byref b as vec3) as vec3
    return vec3(powf(a.x,b.x),powf(a.y,b.y),powf(a.z,b.z))
end function
function pow (byref a as vec4, byref b as vec4) as vec4
    return vec4(powf(a.x,b.x),powf(a.y,b.y),powf(a.z,b.z),powf(a.w,b.w))
end function

' The exp function returns the constant e raised to the power of x. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the operation is done component-wise.
function exp overload(a as single) as single
    return expf(a)
end function
function exp(byref a as vec2) as vec2
    return vec2(expf(a.x),expf(a.y))
end function
function exp(byref a as vec3) as vec3
    return vec3(expf(a.x),expf(a.y),expf(a.z))
end function
function exp(byref a as vec4) as vec4
    return vec4(expf(a.x),expf(a.y),expf(a.z),expf(a.w))
end function

' The log function returns the power to which the constant e has to be raised to produce x. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the operation is done component-wise.
function log overload(a as single) as single
    return logf(a)
end function
function log(byref a as vec2) as vec2
    return vec2(logf(a.x),logf(a.y))
end function
function log(byref a as vec3) as vec3
    return vec3(logf(a.x),logf(a.y),logf(a.z))
end function
function log(byref a as vec4) as vec4
    return vec4(logf(a.x),logf(a.y),logf(a.z),logf(a.w))
end function

' The exp2 function returns 2 raised to the power of x. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the operation is done component-wise.
function exp2 overload(byref a as single) as single
    return exp2f(a)
end function
function exp2(byref a as vec2) as vec2
    return vec2(exp2f(a.x),exp2f(a.y))
end function
function exp2(byref a as vec3) as vec3
    return vec3(exp2f(a.x),exp2f(a.y),exp2f(a.z))
end function
function exp2(byref a as vec4) as vec4
    return vec4(exp2f(a.x),exp2f(a.y),exp2f(a.z),exp2f(a.w))
end function

' The log2 function returns the power to which 2 has to be raised to produce x. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the operation is done component-wise.
function log2 overload(a as single) as single
    return log2f(a)
end function
function log2(byref a as vec2) as vec2
    return vec2(log2f(a.x),log2f(a.y))
end function
function log2(byref a as vec3) as vec3
    return vec3(log2f(a.x),log2f(a.y),logf(a.z))
end function
function log2(byref a as vec4) as vec4
    return vec4(log2f(a.x),log2f(a.y),log2f(a.z),log2f(a.w))
end function

' The sqrt function returns the square root of x. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the operation is done component-wise.
function sqrt overload(a as single) as single
    return sqrtf(a)
end function
function sqrt(byref a as vec2) as vec2
    return vec2(sqrtf(a.x),sqrtf(a.y))
end function
function sqrt(byref a as vec3) as vec3
    return vec3(sqrtf(a.x),sqrtf(a.y),sqrtf(a.z))
end function
function sqrt(byref a as vec4) as vec4
    return vec4(sqrtf(a.x),sqrtf(a.y),sqrtf(a.z),sqrtf(a.w))
end function

' The inversesqrt function returns the inverse square root of x, i.e. the reciprocal of the square root. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the operation is done component-wise.
function inversesqrt overload(a as single) as single
    return 1.0/sqrtf(a)
end function
function inversesqrt(byref a as vec2) as vec2
    return vec2(1.0/sqrtf(a.x),1.0/sqrtf(a.y))
end function
function inversesqrt(byref a as vec3) as vec3
    return vec3(1.0/sqrtf(a.x),1.0/sqrtf(a.y),1.0/sqrtf(a.z))
end function
function inversesqrt(byref a as vec4) as vec4
    return vec4(1.0/sqrtf(a.x),1.0/sqrtf(a.y),1.0/sqrtf(a.z),1.0/sqrtf(a.w))
end function

' The abs function returns the absolute value of x, i.e. x when x is positive or zero and -x for negative x. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the operation is done component-wise.
'function abs overload (v as single) as single

operator abs(byref v as const vec2) as vec2
    return vec2(iif(v.x<0,-v.x,v.x),iif(v.y<0,-v.y,v.y))
end operator
operator abs(byref v as const vec3) as vec3
    return vec3(iif(v.x<0,-v.x,v.x),iif(v.y<0,-v.y,v.y),iif(v.z<0,-v.z,v.z))
end operator
operator abs(byref v as const vec4) as vec4
    return vec4(iif(v.x<0,-v.x,v.x),iif(v.y<0,-v.y,v.y),iif(v.z<0,-v.z,v.z),iif(v.w<0,-v.w,v.w))
end operator

' The sign function returns 1.0 when x is positive, 0.0 when x is zero and -1.0 when x is negative. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the operation is done component-wise.
function sign overload(a as single) as single
    return iif(a>0,1,iif(a<0,-1,0))
end function
function sign(byref a as vec2) as vec2
    return vec2(iif(a.x>0,1,iif(a.x<0,-1,0)), _
                iif(a.y>0,1,iif(a.y<0,-1,0)))
end function
function sign(byref a as vec3) as vec3
    return vec3(iif(a.x>0,1,iif(a.x<0,-1,0)), _
                iif(a.y>0,1,iif(a.y<0,-1,0)), _
                iif(a.z>0,1,iif(a.z<0,-1,0)))
end function
function sign(byref a as vec4) as vec4
    return vec4(iif(a.x>0,1,iif(a.x<0,-1,0)), _
                iif(a.y>0,1,iif(a.y<0,-1,0)), _
                iif(a.z>0,1,iif(a.z<0,-1,0)), _
                iif(a.w>0,1,iif(a.w<0,-1,0)))
end function

' The floor function returns the largest integer number that is smaller or equal to x. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the operation is done component-wise.
' Side note: The return value is of type singleing scalar or single vector although the result of the operation is an integer.
function floor overload(a as single) as single
    return floorf(a)
end function
function floor(byref a as vec2) as vec2
    return vec2(floorf(a.x),floorf(a.y))
end function
function floor(byref a as vec3) as vec3
    return vec3(floorf(a.x),floorf(a.y),floorf(a.z))
end function
function floor(byref a as vec4) as vec4
    return vec4(floorf(a.x),floorf(a.y),floorf(a.z),floorf(a.w))
end function

' The ceiling function returns the smallest number that is larger or equal to x. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the operation is done component-wise.
' Side note: The return value is of type singleing scalar or single vector although the result of the operation is an integer.
function ceil overload(a as single) as single
    return ceilf(a)
end function
function ceil(byref a as vec2) as vec2
    return vec2(ceilf(a.x),ceilf(a.y))
end function
function ceil(byref a as vec3) as vec3
    return vec3(ceilf(a.x),ceilf(a.y),ceilf(a.z))
end function
function ceil(byref a as vec4) as vec4
    return vec4(ceilf(a.x),ceilf(a.y),ceilf(a.z),ceilf(a.w))
end function

' The fract function returns the fractional part of x, i.e. x minus floor(x). 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a single vector the operation is done component-wise.
function fract overload (x as single) as single
    return x-floor(x)
end function
function fract (byref x as vec2) as vec2
    return vec2(x.x-floor(x.x), x.y-floor(x.y))
end function
function fract (byref x as vec3) as vec3
    return vec3(x.x-floor(x.x), x.y-floor(x.y), x.z-floor(x.z))
end function
function fract (byref x as vec4) as vec4
    return vec4(x.x-floor(x.x), x.y-floor(x.y), x.z-floor(x.z), x.w-floor(x.w))
end function

' The modulo function returns x minus the product of y and floor(x/y). 
' The input parameters can be singleing scalars or single vectors. 
' In case of single vectors the operation is done component-wise.
' Side note: If x and y are integers the return value is the remainder of the division of x by y as expected.
' There is also a variation of the mod function where the second parameter is always a singleing scalar.
function modulo overload (x as integer,y as integer) as integer
    return x-y*(x\y)
end function
function modulo (x as single,y as single) as single
    return x-y*floor(x/y)
end function
function modulo (byref x as vec2,byref y as vec2) as vec2
    return vec2(x.x-y.x*floor(x.x/y.x), x.y-y.y*floor(x.y/y.y))
end function
function modulo (byref x as vec3,byref y as vec3) as vec3
    return vec3(x.x-y.x*floor(x.x/y.x), x.y-y.y*floor(x.y/y.y), x.z-y.z*floor(x.z/y.z))
end function
function modulo (byref x as vec4,byref y as vec4) as vec4
    return vec4(x.x-y.x*floor(x.x/y.x), x.y-y.y*floor(x.y/y.y), x.z-y.z*floor(x.z/y.z), x.w-y.w*floor(x.w/y.w))
end function

' The min function returns the smaller of the two arguments. 
' The input parameters can be singleing scalars or single vectors. 
' In case of single vectors the operation is done component-wise.
function min overload(a as single, b as single) as single
    return iif(a<b,a,b)
end function
function min (byref a as vec2, byref b as vec2) as vec2
    return vec2(iif(a.x<b.x,a.x,b.x),iif(a.y<b.y,a.y,b.y))
end function
function min (byref a as vec3, byref b as vec3) as vec3
    return vec3(iif(a.x<b.x,a.x,b.x),iif(a.y<b.y,a.y,b.y),iif(a.z<b.z,a.z,b.z))
end function
function min (byref a as vec4, byref b as vec4) as vec4
    return vec4(iif(a.x<b.x,a.x,b.x),iif(a.y<b.y,a.y,b.y),iif(a.z<b.z,a.z,b.z),iif(a.w<b.w,a.w,b.w))
end function
' There is also a variation of the min function where the second parameter is always a singleing scalar.
function min (byref a as vec2, byref b as single) as vec2
    return vec2(iif(a.x<b,a.x,b),iif(a.y<b,a.y,b))
end function
function min (byref a as vec3, byref b as single) as vec3
    return vec3(iif(a.x<b,a.x,b),iif(a.y<b,a.y,b),iif(a.z<b,a.z,b))
end function
function min (byref a as vec4, byref b as single) as vec4
    return vec4(iif(a.x<b,a.x,b),iif(a.y<b,a.y,b),iif(a.z<b,a.z,b),iif(a.w<b,a.w,b))
end function

' The max function returns the larger of the two arguments. 
' The input parameters can be singleing scalars or single vectors. 
' In case of single vectors the operation is done component-wise.
function max overload(a as single, b as single) as single
    return iif(a>b,a,b)
end function
function max (byref a as vec2, byref b as vec2) as vec2
    return vec2(iif(a.x>b.x,a.x,b.x),iif(a.y>b.y,a.y,b.y))
end function
function max (byref a as vec3, byref b as vec3) as vec3
    return vec3(iif(a.x>b.x,a.x,b.x),iif(a.y>b.y,a.y,b.y),iif(a.z>b.z,a.z,b.z))
end function
function max (byref a as vec4, byref b as vec4) as vec4
    return vec4(iif(a.x>b.x,a.x,b.x),iif(a.y>b.y,a.y,b.y),iif(a.z>b.z,a.z,b.z),iif(a.w>b.w,a.w,b.w))
end function
' There is also a variation of the max function where the second parameter is always a singleing scalar.
function max (byref a as vec2, byref b as single) as vec2
    return vec2(iif(a.x>b,a.x,b),iif(a.y>b,a.y,b))
end function
function max (byref a as vec3, byref b as single) as vec3
    return vec3(iif(a.x>b,a.x,b),iif(a.y>b,a.y,b),iif(a.z>b,a.z,b))
end function
function max (byref a as vec4, byref b as single) as vec4
    return vec4(iif(a.x>b,a.x,b),iif(a.y>b,a.y,b),iif(a.z>b,a.z,b),iif(a.w>b,a.w,b))
end function

' The clamp function returns x if it is larger than minVal and smaller than maxVal. 
' In case x is smaller than minVal, minVal is returned. 
' If x is larger than maxVal, maxVal is returned. 
' The input parameters can be singleing scalars or single vectors. 
' In case of single vectors the operation is done component-wise.
function clamp overload(a as single, b as single, c as single) as single
    return iif(a<b,b,iif(a>c,c,a))
end function
function clamp (byref a as vec2, byref b as vec2, byref c as vec2) as vec2
    return vec2(iif(a.x<b.x,b.x,iif(a.x>c.x,c.x,a.x)), _
                iif(a.y<b.y,b.y,iif(a.y>c.y,c.y,a.y)))
end function
function clamp (byref a as vec3, byref b as vec3, byref c as vec3) as vec3
    return vec3(iif(a.x<b.x,b.x,iif(a.x>c.x,c.x,a.x)), _
                iif(a.y<b.y,b.y,iif(a.y>c.y,c.y,a.y)), _
                iif(a.z<b.z,b.z,iif(a.z>c.z,c.z,a.z)))
end function
function clamp (byref a as vec4, byref b as vec4, byref c as vec4) as vec4
    return vec4(iif(a.x<b.x,b.x,iif(a.x>c.x,c.x,a.x)), _
                iif(a.y<b.y,b.y,iif(a.y>c.y,c.y,a.y)), _
                iif(a.z<b.z,b.z,iif(a.z>c.z,c.z,a.z)),_
                iif(a.w<b.w,b.w,iif(a.z>c.w,c.w,a.w)))
end function
' There is also a variation of the clamp function where the second and third parameters are always a singleing scalars.
function clamp (byref a as vec2, b as single, c as single) as vec2
    return vec2(iif(a.x<b,b,iif(a.x>c,c,a.x)), _
                iif(a.y<b,b,iif(a.y>c,c,a.y)))
end function
function clamp (byref a as vec3, b as single, c as single) as vec3
    return vec3(iif(a.x<b,b,iif(a.x>c,c,a.x)), _
                iif(a.y<b,b,iif(a.y>c,c,a.y)), _
                iif(a.z<b,b,iif(a.z>c,c,a.z)))
end function
function clamp (byref a as vec4, b as single, c as single) as vec4
    return vec4(iif(a.x<b,b,iif(a.x>c,c,a.x)), _
                iif(a.y<b,b,iif(a.y>c,c,a.y)), _
                iif(a.z<b,b,iif(a.z>c,c,a.z)),_
                iif(a.w<b,b,iif(a.z>c,c,a.w)))
end function

' The mix function returns the linear blend of x and y, i.e. the product of x and (1 - a) plus the product of y and a. 
' The input parameters can be singleing scalars or single vectors. 
' In case of single vectors the operation is done component-wise.
function mix overload(a as single, b as single, c as single) as single
    return a * (1-c) + b*c
end function
function mix (byref a as vec2, byref b as vec2, byref c as vec2) as vec2
    return vec2(a.x * (1-c.x) + b.x*c.x, _
                a.y * (1-c.y) + b.y*c.y)
end function
function mix (byref a as vec3, byref b as vec3, byref c as vec3) as vec3
    return vec3(a.x * (1-c.x) + b.x*c.x, _
                a.y * (1-c.y) + b.y*c.y, _
                a.z * (1-c.z) + b.z*c.z)
end function
function mix (byref a as vec4, byref b as vec4, byref c as vec4) as vec4
    return vec4(a.x * (1-c.x) + b.x*c.x, _
                a.y * (1-c.y) + b.y*c.y, _
                a.z * (1-c.z) + b.z*c.z, _
                a.w * (1-c.w) + b.w*c.w)
end function
' There is also a variation of the mix function where the third parameter is always a singleing scalar.
function mix (byref a as vec2, byref b as vec2, c as single) as vec2
    return vec2(a.x * (1-c) + b.x*c, _
                a.y * (1-c) + b.y*c)
end function
function mix (byref a as vec3, byref b as vec3, c as single) as vec3
    return vec3(a.x * (1-c) + b.x*c, _
                a.y * (1-c) + b.y*c, _
                a.z * (1-c) + b.z*c)
end function
function mix (byref a as vec4, byref b as vec4, c as single) as vec4
    return vec4(a.x * (1-c) + b.x*c, _
                a.y * (1-c) + b.y*c, _
                a.z * (1-c) + b.z*c, _
                a.w * (1-c) + b.w*c)
end function


' The step (renamed step_) function returns 0.0 if x is smaller then edge and otherwise 1.0. 
' The input parameters can be singleing scalars or single vectors. 
' In case of single vectors the operation is done component-wise.
function step_ overload(edge as single, x as single) as single
    return iif(x<edge,0,1)
end function
function step_ (byref edge as vec2, byref x as vec2) as vec2
    return vec2(iif(x.x<edge.x,0,1), _
                iif(x.y<edge.y,0,1))
end function
function step_ (byref edge as vec3, byref x as vec3) as vec3
    return vec3(iif(x.x<edge.x,0,1), _
                iif(x.y<edge.y,0,1), _
                iif(x.z<edge.z,0,1))
end function
function step_ (byref edge as vec4, byref x as vec4) as vec4
    return vec4(iif(x.x<edge.x,0,1), _
                iif(x.y<edge.y,0,1), _
                iif(x.z<edge.z,0,1), _
                iif(x.w<edge.w,0,1))
end function
' There is also a variation of the step function where the edge parameter is always a singleing scalar.
function step_ (edge as single, byref x as vec2) as vec2
    return vec2(iif(x.x<edge,0,1), _
                iif(x.y<edge,0,1))
end function
function step_ (edge as single, byref x as vec3) as vec3
    return vec3(iif(x.x<edge,0,1), _
                iif(x.y<edge,0,1), _
                iif(x.z<edge,0,1))
end function
function step_ (edge as single, byref x as vec4) as vec4
    return vec4(iif(x.x<edge,0,1), _
                iif(x.y<edge,0,1), _
                iif(x.z<edge,0,1), _
                iif(x.w<edge,0,1))
end function

' The smoothstep function returns 0.0 if x is smaller then edge0 and 1.0 if x is larger than edge1. 
' Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomirals. 
' The input parameters can be singleing scalars or single vectors. 
' In case of single vectors the operation is done component-wise.
function smoothstep overload (edge0 as single, edge1 as single, x as single) as single
    if x<edge0 then return 0
    if x>edge1 then return 1
    dim as single t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0)
    return t * t * (3.0 - 2.0 * t)
end function
function smoothstep (byref edge0 as vec2, byref edge1 as vec2, byref x as vec2) as vec2
    return vec2(smoothstep(edge0.x,edge1.x,x.x), _
                smoothstep(edge0.y,edge1.y,x.y))
end function
function smoothstep (byref edge0 as vec3, byref edge1 as vec3, byref x as vec3) as vec3
    return vec3(smoothstep(edge0.x,edge1.x,x.x), _
                smoothstep(edge0.y,edge1.y,x.y), _
                smoothstep(edge0.z,edge1.z,x.z))
end function
function smoothstep (byref edge0 as vec4, byref edge1 as vec4, byref x as vec4) as vec4
    return vec4(smoothstep(edge0.x,edge1.x,x.x), _
                smoothstep(edge0.y,edge1.y,x.y), _
                smoothstep(edge0.z,edge1.z,x.z), _
                smoothstep(edge0.w,edge1.w,x.w))
end function
' There is also a variation of the smoothstep function where the edge0 and edge1 parameters are always singleing scalars.
function smoothstep (edge0 as single, edge1 as single, byref x as vec2) as vec2
    return vec2(smoothstep(edge0,edge1,x.x), _
                smoothstep(edge0,edge1,x.y))
end function
function smoothstep (edge0 as single, edge1 as single, byref x as vec3) as vec3
    return vec3(smoothstep(edge0,edge1,x.x), _
                smoothstep(edge0,edge1,x.y), _
                smoothstep(edge0,edge1,x.z))
end function
function smoothstep (edge0 as single, edge1 as single, byref x as vec4) as vec4
    return vec4(smoothstep(edge0,edge1,x.x), _
                smoothstep(edge0,edge1,x.y), _
                smoothstep(edge0,edge1,x.z), _
                smoothstep(edge0,edge1,x.w))
end function

'Returns the length squared of a vector or the dot product with it's self.
function length2 overload(a as const single) as single
    return iif(a<0,-a,a)
end function
function length2 (byref v as const vec2) as single
    return v.x*v.x + v.y*v.y
end function
function length2 (byref v as const vec3) as single
    return v.x*v.x + v.y*v.y + v.z*v.z
end function
function length2 (byref v as const vec4) as single
    return v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w
end function
' The length function returns the length of a vector defined by the Euclidean norm, 
' i.e. the square root of the sum of the squared components. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a singleing scalar the length function is trivial and returns the absolute value.
function length overload(a as const single) as single
    return iif(a<0,-a,a)
end function
function length (byref v as const vec2) as single
    return sqrtf(v.x*v.x + v.y*v.y)
end function
function length (byref v as const vec3) as single
    return sqrtf(v.x*v.x + v.y*v.y + v.z*v.z)
end function
function length (byref v as const vec4) as single
    return sqrtf(v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w)
end function

' The distance function returns the distance between two points. 
' The distance of two points is the length of the vector d = a - b, that starts at b and points to a. 
' The input parameters can be singleing scalars or single vectors. 
' In case of singleing scalars the distance function is trivial and returns the absolute value of d.
function distance overload (a as single, b as single) as single
    dim as single d=a-b : return iif(a<0,-a,a)
end function
function distance (byref a as vec2, byref b as vec2) as single
    dim as single x=a.x-b.x
    dim as single y=a.y-b.y
    dim as single d = x*x+y*y
    if d=0 then return 0
    return sqrtf(d)
end function
function distance (byref a as vec3, byref b as vec3) as single
    dim as single x=a.x-b.x
    dim as single y=a.y-b.y
    dim as single z=a.z-b.z
    dim as single d = x*x+y*y+z*z
    if d=0 then return 0
    return sqrtf(d)
end function
function distance (byref a as vec4, byref b as vec4) as single
    dim as single x=a.x-b.x
    dim as single y=a.y-b.y
    dim as single z=a.z-b.z
    dim as single w=a.w-b.w
    dim as single d = x*x+y*y+z*z+w*w
    if d=0 then return 0
    return sqrtf(d)
end function

' The dot function returns the dot product of the two input parameters, i.e. the sum of the component-wise products. 
' If a and b are the same the square root of the dot product is equivalent to the length of the vector. 
' The input parameters can be singleing scalars or single vectors. 
' In case of singleing scalars the dot function is trivial and returns the product of a and b.
function dot overload(a as single, b as single) as single
    return a*b
end function
function dot (byref a as vec2, byref b as vec2) as single
    return a.x*b.x + a.y*b.y
end function
function dot (byref a as vec3, byref b as vec3) as single
    return a.x*b.x + a.y*b.y + a.z*b.z
end function
function dot (byref a as vec4, byref b as vec4) as single
    return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w
end function

' The cross function returns the cross product of the two input parameters, 
' i.e. a vector that is perpendicular to the plane containing a and b and has a magnitude 
' that is equal to the area of the parallelogram that a and b span. 
' The input parameters can only be 3-component singleing vectors. 
' The cross product is equivalent to the product of the length of the vectors 
' times the sinus of the(smaller) angle between a and b.
function cross(byref a as vec3, byref b as vec3) as vec3
    return vec3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x)
end function

' The normalize function returns a vector with length 1.0 that is parallel to a, i.e. a divided by its length. 
' The input parameter can be a singleing scalar or a single vector. 
' In case of a singleing scalar the normalize function is trivial and returns 1.0.
function normalize overload (v as single) as single
    return 1
end function
function normalize (byref v as vec2) as vec2
    dim as single d = v.x*v.x + v.y*v.y
    if d then d=1.0/sqrtf(d)
    return vec2(v.x*d,v.y*d)
end function
function normalize (byref v as vec3) as vec3
    dim as single d = v.x*v.x + v.y*v.y + v.z*v.z
    if d then d=1.0/sqrtf(d)
    return vec3(v.x*d,v.y*d,v.z*d)
end function
function normalize (byref v as vec4) as vec4
    dim as single d = v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w
    if d then d=1.0/sqrtf(d)
    return vec4(v.x*d,v.y*d,v.z*d,v.w*d)
end function

' The faceforward function returns a vector that points in the same direction as a reference vector. 
' The function has three input parameters of the type singleing scalar or single vector: 
' N, the vector to orient, I, the incident vector, and Nref, the reference vector. 
' If the dot product of I and Nref is smaller than zero the return value is N. Otherwise -N is returned.
function faceforward overload(N as single, I as single, Nref as single) as single
    dim as single d=I*Nref
    if d<0 then return N else return -N
end function
function faceforward (byref N as vec2, byref I as vec2, byref Nref as vec2) as vec2
    dim as single d=I.x*Nref.x + I.y*Nref.y 
    if d<0 then return N else return -N
end function
function faceforward (byref N as vec3, byref I as vec3, byref Nref as vec3) as vec3
    dim as single d=I.x*Nref.x + I.y*Nref.y + I.z*Nref.z
    if d<0 then return N else return -N
end function
function faceforward (byref N as vec4, byref I as vec4, byref Nref as vec4) as vec4
    dim as single d=I.x*Nref.x + I.y*Nref.y + I.z*Nref.z + I.w*Nref.w
    if d<0 then return N else return -N
end function

' The reflect function returns a vector that points in the direction of reflection. 
' The function has two input parameters of the type singleing scalar or single vector: 
' I, the incident vector, and N, the normal vector of the reflecting surface.
' Side note: To obtain the desired result the vector N has to be normalized. 
' The reflection vector always has the same length as the incident vector. 
' From this it follows that the reflection vector is normalized if N and I are both normalized. 
function reflect overload(I as single, N as single) as single
    dim as single d=2*(I*N) : return i-n*d
end function
function reflect (byref I as vec2, byref N as vec2) as vec2
    dim as single d = 2 * (I.x*N.x + I.y*N.y)
    return vec2(i.x-n.x*d,i.y-n.y*d)
end function
function reflect (byref I as vec3, byref N as vec3) as vec3
    dim as single d = 2 * (I.x*N.x + I.y*N.y + I.z*N.z)
    return vec3(i.x-n.x*d,i.y-n.y*d,i.z-n.z*d)
end function
function reflect (byref I as vec4, byref N as vec4) as vec4
    dim as single d = 2 * (I.x*N.x + I.y*N.y + I.z*N.z + I.w*N.w)
    return vec4(i.x-n.x*d,i.y-n.y*d,i.z-n.z*d,i.w-n.w*d)
end function

' The refract function returns a vector that points in the direction of refraction. 
' The function has two input parameters of the type singleing scalar or single vector 
' and one input parameter of the type singleing scalar: 
' I, the incident vector, N, the normal vector of the refracting surface, 
' and eta, the ratio of indices of refraction.
' Side note: To obtain the desired result the vectors I and N have to be normalized.
function refract overload (byref I as vec2, byref N as vec2, eta as single) as vec2
    dim as vec2 R
    dim as single dotNI = I.x*N.x + I.y*N.y
    dim as single k = 1.0 - eta * eta * (1.0 - dotNI*dotNI)
    if (k<0.0) then 
        return R
    elseif (k=0.0) then
        R = eta*I - eta*dotNI*N
    else
    k=sqrt(k)
        R = eta*I - (eta*dotNI + k)*N
    end if
    return R
end function
function refract ( byref I as vec3, byref N as vec3, eta as single) as vec3
    dim as vec3 R
    dim as single dotNI = I.x*N.x + I.y*N.y + I.z*N.z
    dim as single k = 1.0 - eta * eta * (1.0 - dotNI*dotNI)
    if (k<0.0) then 
        return R
    elseif (k=0.0) then
    R = eta*I - eta*dotNI*N
    else
        k=sqrt(k)
        R = eta*I - (eta*dotNI + k)*N
    end if
    return R
end function
function refract ( I as vec4, N as vec4, eta as single) as vec4
    dim as vec4 R
    dim as single dotNI = I.x*N.x + I.y*N.y + I.z*N.z + I.w*N.w
    dim as single k = 1.0 - eta * eta * (1.0 - dotNI*dotNI)
    if (k<0.0) then 
        return R
    elseif (k=0.0) then
        R = eta*I - eta*dotNI*N
    else
        k=sqrt(k)
        R = eta*I - (eta*dotNI + k)*N
    end if
    return R
end function


raymarchingthreads.bas

Code: Select all

#include "matn.bi"
'original glslstyle.bi is broken. Incurrect matrix multiplications.

' this uniform's vars are global for the fragment shader
dim shared as single iGlobalTime ' shader playback time (in seconds)
dim shared as vec3  iResolution ' viewport resolution (in pixels)
dim shared as vec4  iMouse      ' mouse pixel coords. xy: current (if MLB down), zw: click

' #################
' # shadertoy.com #
' #################
' Created by inigo quilez - iq/2013
' License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

' A list of usefull distance function to simple primitives, and an example on how to
' do some interesting boolean operations, repetition and displacement.
'
' More info here: http:'www.iquilezles.org/www/articles/distfunctions/distfunctions.htm

'Translated to FreeBASIC by D.J. Peters
'Quad threaded added by ShawnLG

const as integer SHADOW_SETPS = 16 ' 16 how many soft shadow steps
const as integer AO_STEPS     =  5 '  5 how many ambient occlusion steps

function length6(p as vec2) as single
  p = p*p*p  : p = p*p
  return pow( p.x + p.y, 1.0/6.0 )
end function

function length8(p as vec2) as single
  p = p*p: p = p*p: p = p*p
  return pow( p.x + p.y, 1.0/8.0 )
end function

function sdPlane(p as vec3) as single
  return p.y
end function

function sdSphere(p as vec3, s as single) as single
  return length(p) - s
end function

function sdBox(p as vec3, b as vec3) as single
  dim as vec3 d = abs(p) - b
  return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0))
end function

function sdEllipsoid(p as vec3, r as vec3) as single
  return (length( p/r ) - 1.0) * min(min(r.x,r.y),r.z)
end function

function udRoundBox(p as vec3, b as vec3, r as single) as single
  return length(max(abs(p)-b,0.0))-r
end function

function sdTorus(p as vec3, t as vec2) as single
  return length( vec2(length(p.xz)-t.x,p.y) )-t.y
end function

function sdTorus82(p as vec3, t as vec2) as single
  dim as vec2 q = vec2(length(p.xz)-t.x,p.y)
  return length8(q)-t.y
end function

function sdTorus88(p as vec3, t as vec2) as single
  dim as vec2 q = vec2(length8(p.xz)-t.x,p.y)
  return length8(q)-t.y
end function

function sdHexPrism(p as vec3, h as vec2) as single
  dim as vec3 q  = abs(p)
  dim as single d1 = q.z-h.y
  dim as single d2 = max((q.x*0.866025+q.y*0.5),q.y)-h.x
  return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.)
end function

function sdCapsule(p as vec3, a as vec3, b as vec3, r as single) as single
  dim as vec3 pa = p-a, ba = b-a
  dim as single h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 )
  return length( pa - ba*h ) - r
end function

function sdTriPrism(p as vec3, h as vec2) as single
  dim as vec3  q  = abs(p)
  dim as single d1 = q.z-h.y
  dim as single d2 = max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5
  return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.)
end function

function sdCylinder(p as vec3, h as vec2) as single
  dim as vec2 d = abs(vec2(length(p.xz),p.y)) - h
  return min(max(d.x,d.y),0.0) + length(max(d,0.0))
end function

function sdCylinder6(p as vec3, h as vec2) as single
  return max( length6(p.xz)-h.x, abs(p.y)-h.y )
end function

function sdCone(p as vec3, c as vec3) as single
  dim as vec2  q  = vec2( length(p.xz), p.y )
  dim as single d1 = -q.y-c.z
  dim as single d2 = max( dot(q,c.xy), q.y)
  return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.0)
end function

function _sdCone(p as vec3, c as vec3) as single
  dim as vec2 q = vec2( length(p.xz), p.y )
  dim as vec2 v = vec2( c.z * c.y/c.x, -c.z )
  dim as vec2 w = v - q
  dim as vec2 vv = vec2( dot(v,v), v.x*v.x )
  dim as vec2 qv = vec2( dot(v,w), v.x*w.x )
  dim as vec2 d = max(qv,0.0)*qv/vv
  return sqrt( dot(w,w) - max(d.x,d.y) ) * sign(max(q.y*v.x-q.x*v.y,w.y))
end function

function sdConeHQ(p as vec3, c as vec3) as single
  dim as vec2 q = vec2( length(p.xz), p.y )
  dim as vec2 v = vec2( c.z*c.y/c.x, -c.z )
  dim as single vvb = dot( v, v )
  dim as single qvb = dot( v, v-q )
  dim as single vvx = v.x*v.x
  dim as single qvx = v.x*(v.x-q.x)
  dim as single hb = clamp( qvb, 0.0, vvb )
  dim as single hx = clamp( qvx, 0.0, vvx )
  dim as vec2 d1 = vec2( hb*(hb-2.0*qvb)/vvb, q.x*v.y-q.y*v.x )
  dim as vec2 d2 = vec2( hx*(hx-2.0*qvx)/vvx,     q.y-v.y )
  dim as vec2 d = min( d1, d2 )
  return -sqrt( dot(v-q,v-q) + d.x ) * sign(d.y)
end function

function sdConeSection(p as vec3, h as single, r1 as single, r2 as single) as single
  dim as single d1 = -p.y - h
  dim as single q  =  p.y - h
  dim as single si = 0.5*(r1-r2)/h
  dim as single d2 = max( sqrt( dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q )
  return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.)
end function

function sdWobbleCube( p as vec3, s as single) as single
  ' Modified cube
  return max (max(abs(p.x)-s + sin(p.y*10.0)*0.05 , abs(p.y)-s) , abs(p.z)-s )
end function
#define dot2(a) dot((a),(a))


function udTriangle(p as vec3, a as vec3, b as vec3, c as vec3) as single
  dim as vec3 ba = b - a
  dim as vec3 cb = c - b
  dim as vec3 ac = a - c

  dim as vec3 pa = p - a
  dim as vec3 pb = p - b
  dim as vec3 pc = p - c
  dim as vec3 nor = cross( ba, ac )
  'windowtitle "" & nor.x & "," & nor.y & "," & nor.z
  return sqrt( iif(sign(dot(cross(ba,nor),pa)) _
                  + sign(dot(cross(cb,nor),pb)) _
                  + sign(dot(cross(ac,nor),pc))<2.0, min( min( _
    dot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa), _
    dot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb)), _
    dot2(ac*clamp(dot(ac,pc)/dot2(ac),0.0,1.0)-pc)),  dot(nor,pa)*dot(nor,pa)/dot2(nor)) )
end function

function udQuad(p as vec3, a as vec3, b as vec3, c as vec3, d as vec3) as single
  dim as vec3 ba = b - a
  dim as vec3 pa = p - a
  dim as vec3 cb = c - b
  dim as vec3 pb = p - b
  dim as vec3 dc = d - c
  dim as vec3 pc = p - c
  dim as vec3 ad = a - d
  dim as vec3 pd = p - d
  dim as vec3 nor = cross( ba, ad )
  dim as single s = sign(dot(cross(ba,nor),pa)) _
                + sign(dot(cross(cb,nor),pb)) _
                + sign(dot(cross(dc,nor),pc)) _
                + sign(dot(cross(ad,nor),pd))
  if( s<3.0) then return sqrt(min( min( min( _
    dot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa), _
    dot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb)), _
    dot2(dc*clamp(dot(dc,pc)/dot2(dc),0.0,1.0)-pc)), _
    dot2(ad*clamp(dot(ad,pd)/dot2(ad),0.0,1.0)-pd)))

  return sqrt(dot(nor,pa)*dot(nor,pa)/dot2(nor))
end function

' operator subtract
function opS(d1 as single, d2 as single) as single
  return max(-d2,d1)
end function

' operator union
function opU(d1 as vec2, d2 as vec2) as vec2
  return iif(d1.x<d2.x,d1,d2)
end function

' operator intersect
function opI(d1 as single, d2 as single ) as single
  return max(d1,d2)
end function

' operator repeat
function opRep(p as vec3, c as vec3) as vec3
  return modulo(p,c)-c*.5
end function

' exponential smooth min
function ExpSmin(a as single, b as single, k as single=32) as single
  dim as single res = Exp( -k*a ) + Exp( -k*b )
  return -Log(res)/k
end function

' polynomial smooth min
function PolySmin(a as single, b as single, k as single=0.1) as single
  dim as single h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 )
  return mix( b, a, h ) - k*h*(1.0-h)
end function

' power smooth min
function PowSmin(a as single, b as single, k as single=8) as single
  a = Pow(a, k)
  b = Pow(b, k)
  return Pow( (a*b)/(a+b), 1.0/k )
end function

function opTwist(p as vec3) as vec3
  dim as single  c = cos(10.0*p.y+10.0)
  dim as single  s = sin(10.0*p.y+10.0)
  dim as mat2  m = mat2(c,-s,s,c)
  return vec3(m*p.xz,p.y)
end function

function map( p as vec3 ) as vec2
  dim as vec2 res = vec2( sdPlane(     p), 1.0 )
   res = opU( res, vec2( sdSphere(    p-vec3( 0.0,0.25, 0.0), .25 ), 46.9 ) )
   res = opU( res, vec2( sdBox(       p-vec3( 1.0,0.25, 0.0), vec3(0.25) ), 3.0 ) )
   res = opU( res, vec2( udRoundBox(  p-vec3( 1.0,0.25, 1.0), vec3(0.15), 0.1 ), 41.0 ) )
   res = opU( res, vec2( sdTorus(     p-vec3( 0.0,0.25, 1.0), vec2(0.20,0.05) ), 25.0 ) )
   res = opU( res, vec2( sdCapsule(   p,vec3(-1.3,0.10,-0.1), vec3(-0.8,0.50,0.2), 0.1  ), 31.9 ) )
   res = opU( res, vec2( sdTriPrism(  p-vec3(-1.0,0.25,-1.0), vec2(0.25,0.05) ),43.5 ) )
   res = opU( res, vec2( sdCylinder(  p-vec3( 1.0,0.30,-1.0), vec2(0.1,0.2) ), 8.0 ) )
   res = opU( res, vec2( sdCone(      p-vec3( 0.0,0.50,-1.0), vec3(0.8,0.6,0.3) ), 55.0 ) )
   res = opU( res, vec2( sdTorus82(   p-vec3( 0.0,0.25, 2.0), vec2(0.20,0.05) ),50.0 ) )
   res = opU( res, vec2( sdTorus88(   p-vec3(-1.0,0.25, 2.0), vec2(0.20,0.05) ),43.0 ) )
   res = opU( res, vec2( sdCylinder6( p-vec3( 1.0,0.30, 2.0), vec2(0.1,0.2) ), 12.0 ) )
   res = opU( res, vec2( sdHexPrism(  p-vec3(-1.0,0.20, 1.0), vec2(0.25,0.05) ),17.0 ) )
   res = opU( res, vec2( opS( _
                         udRoundBox(p-vec3(-2.0,0.2, 1.0), vec3(0.15),0.05), _
                         sdSphere  (p-vec3(-2.0,0.2, 1.0), 0.25)), 13.0 ) )
   res = opU( res, vec2( opS( sdTorus82 (p-vec3(-2.0,0.2, 0.0), vec2(0.20,0.1)), _
                              sdCylinder(opRep(vec3(Atan2(p.x+2.0,p.z)/6.2831, _
                                                    p.y, _
                                                    0.02+0.5*length(p-vec3(-2.0,0.2,0.0))), _
                                               vec3(0.05,1.0,0.05) ), vec2(0.02,0.6))), 51.0 ) )

   res = opU( res, vec2( 0.7*sdSphere(    p-vec3(-2.0,0.25,-1.0), 0.2 ) + _
                    0.03*sin(50.0*p.x)*sin(50.0*p.y)*sin(50.0*p.z), 65.0 ) )
   res = opU( res, vec2( 0.5*sdTorus( opTwist(p-vec3(-2.0,0.25, 2.0)),vec2(0.20,0.05)), 46.7 ) )
   res = opU( res, vec2(sdConeSection( p-vec3( 0.0,0.35,-2.0), 0.15, 0.2, 0.1 ), 13.67 ) )
   res = opU( res, vec2(sdEllipsoid( p-vec3( 1.0,0.35,-2.0), vec3(0.15, 0.2, 0.05) ), 43.17 ) )
  return res
end function

function castRay(ro as vec3, rd as vec3) as vec2
    const as single tmin   =  1.0
    const as single tmax   = 20.0
    const as single precis = 0.002
    dim as single t  = tmin
    dim as single m  = -1.0
    dim as vec2 res=any
    for i as integer = 0 to 50
        res = map(ro+rd*t)
        if(res.x<precis or t > tmax) then
            exit for
        end if
        t += res.x
        m = res.y
    next i
    if(t>tmax) then m = -1.0
    return vec2(t,m)
end function

function softshadow(ro as vec3, rd as vec3, mint as single, tmax as single) as single
  dim as single res = 1.0
  dim as single t = mint
  for i as integer=0 to SHADOW_SETPS-1
    dim as single h = map( ro + rd*t ).x
    res = min( res, 8.0*h/t )
    t += clamp( h, 0.02, 0.10 )
    if( h<0.001 or t>tmax ) then exit for
  next
  return clamp(res,0,1)
end function

function calcNormal(p as vec3) as vec3
  dim as vec3 eps = vec3( 0.001, 0.0, 0.0 )
  dim as vec3 nor = vec3(map(p+eps.xyy).x - map(p-eps.xyy).x,_
                  map(p+eps.yxy).x - map(p-eps.yxy).x,_
                  map(p+eps.yyx).x - map(p-eps.yyx).x )
  return normalize(nor)
end function


function calcAO(p as vec3, nor as vec3) as single
  dim as single occ = 0.0
  dim as single sca = 1.0
  for i as integer=0 to AO_STEPS-1
    dim as single hr = 0.01 + 0.12 * i/AO_STEPS
    dim as vec3 aopos =  nor * hr + p
    dim as single dd = map( aopos ).x
    occ += -(dd-hr)*sca
    sca *= 0.95
  next
  return clamp(1.0 - 3.0*occ, 0.0, 1.0 )
end function



function render(ro as vec3, rd as vec3) as vec3
  dim as vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8
  dim as vec2 res = castRay(ro,rd)
  dim as single t = res.x
  dim as single m = res.y

  if ( m>-0.5 ) then
    dim as vec3 p = ro + t*rd
    dim as vec3 nor = calcNormal( p )
    dim as vec3 ref = reflect( rd, nor )

    ' material       
    col = 0.45 + 0.3*sin( vec3(0.05,0.08,0.10)*(m-1.0) )

    if ( m<1.5 ) then
      dim as single f = modulo( floor(5.0*p.z) + floor(5.0*p.x), 2.0)
      col = 0.4 + 0.1*f*vec3(1.0)
    end if
    ' lighitng
    dim as single occ = calcAO( p, nor )
    dim as vec3  lig = normalize( vec3(-0.6, 0.7, -0.5) )
    dim as single amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 )
    dim as single dif = clamp( dot( nor, lig ), 0.0, 1.0 )
    dim as single bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-p.y,0.0,1.0)
    dim as single dom = smoothstep( -0.1, 0.1, ref.y )
    dim as single fr = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 )
    dim as single spe = pow(clamp( dot( ref, lig ), 0.0, 1.0 ),16.0)
       
    dif *= softshadow( p, lig, 0.02, 2.5 )
    dom *= softshadow( p, ref, 0.02, 2.5 )

    dim as vec3 lin = vec3(0.0)
    lin += 1.20*dif*vec3(1.00,0.85,0.55)
    lin += 1.20*spe*vec3(1.00,0.85,0.55)*dif
    lin += 0.20*amb*vec3(0.50,0.70,1.00)*occ
    lin += 0.30*dom*vec3(0.50,0.70,1.00)*occ
    lin += 0.30*bac*vec3(0.25,0.25,0.25)*occ
    lin += 0.40*fr*vec3(1.00,1.00,1.00)*occ
    col = col*lin

    col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.002*t*t ) )

  end if
  return vec3( clamp(col,0.0,1.0) )
end function




function setCamera(ro as vec3, ta as vec3 , cr as single ) as mat3
  dim as vec3 cw = normalize(ta-ro)
  dim as vec3 cp = vec3(sin(cr), cos(cr),0.0)
  dim as vec3 cu = normalize( cross(cw,cp) )
  dim as vec3 cv = normalize( cross(cu,cw) )
  return mat3( cu, cv, cw )
end function

sub mainImage(byref fragColor as vec4,byref fragCoord as const vec2)
  dim as single rTime = iGlobalTime '*0.01
  dim as vec2 q     = fragCoord/iResolution.xy
  dim as vec2 p     = q*2-1
  ' aspect ratio
  p.x *= iResolution.z '.x/iResolution.y

  ' camera
  dim as vec3 ro = vec3( -0.5+3.5*cos(0.1*rtime + 6.0), 1.0 + 2.0, 0.5 + 3.5*sin(0.1*rtime + 6.0) )
  'dim as vec3 ro = vec3( 2*cos(rTime), 1.0, 2*sin(rTime))
  
  dim as vec3 ta = vec3( -0.5, -0.4, 0.5 )

  ' camera-to-world transformation
  dim as mat3 ca = setCamera( ro, ta, 0.0 )
   
  ' ray direction
  dim as vec3 rd = ca * normalize( vec3(p.xy,2.0) )
  ' render 
  dim as vec3 col = render( ro, rd )
  ' gamma
  fragColor = vec4(pow( col, vec3(0.4545) ))
end sub

' fragment shader main
sub _mainImage(byref fragColor as vec4,byref fragCoord as const vec2)
  dim as vec2 uv = fragcoord
  fragColor = vec4(uv,0.5+0.5*sin(iGlobalTime),1.0)
end sub

'
' main
'
'#define USE_PAGES

dim as integer scr_w,scr_h,frames,mx,my,mb

screeninfo scr_w,scr_h 
'scr_w = scr_W / 4
'scr_h = scr_h / 4
scr_w = 500/2
scr_h = 281/2

screenres  scr_w,scr_h,32


' global shader uniform's
iResolution.x=scr_w
iResolution.y=scr_h
iResolution.z=iResolution.x/iResolution.y


dim as double tFrameStart=0 'tShaderStart

dim as boolean bQuit

Dim shared As Any Ptr backbuffer

backbuffer = ImageCreate(scr_w, scr_h)

Type threadscan
	As Integer yscan
	As Integer xend
	As Integer yend
	as any ptr thread_handle
	Declare Static Sub scanline(param as any Ptr)
End Type
Sub threadscan.scanline(param As Any Ptr)
	Dim as vec2 fragCoord
	dim as vec4 fragColor
	Dim as ulong colour
	dim as threadscan ptr scanparams = cast(threadscan ptr, param)
    For x as Integer = 0 to scanparams->xend
      	fragCoord.x = x
      	fragCoord.y = scanparams->yend - scanparams->yscan
      	mainImage(fragColor, fragCoord)
      	colour = fragColor
      	PSet backbuffer, (x,scanparams->yscan),colour
    Next x
End Sub
Dim As threadscan sthread(scr_w-1)
For y As Integer = 0 To scr_h-1
	sthread(y).xend = scr_w-1
	sthread(y).yend = scr_h-1
Next y
'Main loop
iGlobalTime = Timer()
While bQuit=false
	For y As Integer = 0 To scr_h-1
 		sthread(y).yscan = y
 		sthread(y).thread_handle = threadcreate (ProcPtr(threadscan.scanline), Cast( any ptr, @sthread(y) ) )
	Next y
	For y As Integer = 0 To scr_h-1
 		threadwait(sthread(y).thread_handle)
	Next y

  ScreenLock
  Put (0,0), backbuffer, PSet
  ScreenUnLock
  Sleep 1
  bQuit = iif(asc(inkey())=27,true,false)

  iGlobalTime = Timer()
  Var FPS = 1/(iGlobalTime-tFrameStart)
  windowtitle "time: " & (iGlobalTime-tFrameStart)'str(int(FPS*100)/100)
  tFrameStart=iGlobalTime

  frames+=1
Wend
ImageDestroy(backbuffer)
UPDATE:
raymarchingthreads has been updated. I had to look up on how to pass parameters to threads. No more globals. It now runs threads on every horizontal scan line.
Luxan
Posts: 222
Joined: Feb 18, 2009 12:47
Location: New Zealand

Re: Raymarching Shadertoy demo meets multicore

Post by Luxan »

I ran your code at 640x480 resolution and depth of 32; took a second or so for first frame,
after that rotation, using mouse input, is slower.

What was rendered was good quality, though I have a multi core CPU I don't believe multi threading
is available. I compiled from the command line with the fbc compiler options mentioned.
Post Reply