OpenGL shader language math in FreeBASIC.

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

OpenGL shader language math in FreeBASIC.

Post by D.J.Peters »

OpenGL shader language math.

It's fresh not all tested ATM. :-)

Forum limit 60,000 I can't post it here right klick save as: glslstyle.bi

Joshy

data types: scalar, vec2, vec3, vec4, mat2, mat3, mat4

vector union:
vec2: x,y : s,t
vec3: x,y,z : r.g.b,
vec4: x,y,z,w : r.g.b,a

Swizzling: v2.yx, v2.xx, v3.xyx, v3.xxx, v3.rgb v4.zyx, v4,rgba ...

All math operators are overloaded for scalar, vec2, vec3 and vec4.
+=,-=,*=,/=,+,-,*,/

All math function are overloaded for scalar, vec2, vec3 and vec4.
radians, degrees, sin, cos, tan, asin, acos, atan, pow, exp, log, log2, sqrt
abs, floor, ceil, min, max, clamp, mix, step, smoothstep
length, distance, dot, cross, normalize, faceforward, reflect, refract

added:
boolean: bvec2, bvec3, bvec4
long: ivec2, ivec3, ivec4
matrixCompMult
lessThan, lessThanEqua, greaterThan, greaterThan, greaterThanEqual, equal, notEqual
any, all, not.

NOTE: becouse of the FreeBASIC keywords "step" and "any" the GSL functions with same name are renamed in "step_" and "any_" !
Last edited by D.J.Peters on Oct 12, 2022 19:15, edited 6 times in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: OpenGL shader language math in FreeBASIC.

Post by D.J.Peters »

Premiere first fragment shader runing in FreeBASIC.

Does it makes any sense I don't know but it was fun.

Joshy
Image

FreeBASIC with "glslstyle.bi"

Code: Select all

#include "glslstyle.bi"

' this uniform's vars are global for the fragment shader
dim shared as float 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

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 float
  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 float
  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 float
  return p.y
end function

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

function sdBox(p as vec3, b as vec3) as float
  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 float
  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 float) as float
  return length(max(abs(p)-b,0.0))-r
end function

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

function sdTorus82(p as vec3, t as vec2) as float
  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 float
  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 float
  dim as vec3 q  = abs(p)
  dim as float d1 = q.z-h.y
  dim as float 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 float) as float
  dim as vec3 pa = p-a, ba = b-a
  dim as float 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 float
  dim as vec3  q  = abs(p)
  dim as float d1 = q.z-h.y
  dim as float 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 float
  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 float
  return max( length6(p.xz)-h.x, abs(p.y)-h.y )
end function

function sdCone(p as vec3, c as vec3) as float
  dim as vec2  q  = vec2( length(p.xz), p.y )
  dim as float d1 = -q.y-c.z
  dim as float 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 float
  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 float
  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 float vvb = dot( v, v )
  dim as float qvb = dot( v, v-q )
  dim as float vvx = v.x*v.x
  dim as float qvx = v.x*(v.x-q.x)
  dim as float hb = clamp( qvb, 0.0, vvb )
  dim as float 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 float, r1 as float, r2 as float) as float
  dim as float d1 = -p.y - h
  dim as float q  =  p.y - h
  dim as float si = 0.5*(r1-r2)/h
  dim as float 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 float) as float
  ' 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 dot2(v as vec3) as float
'  return dot(v,v)
'end function

function udTriangle(p as vec3, a as vec3, b as vec3, c as vec3) as float
  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 float
  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 float 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 float, d2 as float) as float
  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 float, d2 as float ) as float
  return max(d1,d2)
end function

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

' exponential smooth min
function ExpSmin(a as float, b as float, k as float=32) as float
  dim as float res = exp( -k*a ) + exp( -k*b )
  return -log(res)/k
end function

' polynomial smooth min
function PolySmin(a as float, b as float, k as float=0.1) as float
  dim as float 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 float, b as float, k as float=8) as float
  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 float  c = cos(10.0*p.y+10.0)
  dim as float  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( udTriangle(  p,vec3(-1,0, 0),vec3(2,0,0),vec3(0,1,0)),  4.9 ) )
   'res = opU( res, vec2( udTriangle(  p,vec3( 0,0,-.5),vec3(0,0,.5),vec3(0,.5,0)),  6.9 ) )

   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(atan(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 float tmin   =  0.1
  const as float tmax   = 20.0
  const as float precis = 0.002
  dim as float t  = tmin
  dim as float m  = -1.0
  dim as vec2 res=any
  do
    res = map( ro + rd * t )
    if (t>tmax ) then exit do
    if (res.x<precis) then exit do
    t+= res.x
    m = res.y
  loop
  res.x=t
  res.y=iif(t>tmax,-1,m)
  return res
end function

function softshadow(ro as vec3, rd as vec3, mint as float, tmax as float) as float
  dim as float res = 1.0
  dim as float t = mint
  for i as integer=0 to SHADOW_SETPS-1
    dim as float 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
  const as float EPS=0.001
  return normalize(vec3(map(vec3(p.x+EPS,p.y,p.z)).x - map(vec3(p.x-EPS,p.y,p.z)).x, _
                         map(vec3(p.x,p.y+EPS,p.z)).x - map(vec3(p.x,p.y-EPS,p.z)).x, _
                         map(vec3(p.x,p.y,p.z+EPS)).x - map(vec3(p.x,p.y,p.z-EPS)).x ))
end function

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

function render(ro as vec3, rd as vec3) as vec3
  dim as vec3 col
  dim as vec2 res = castRay(ro,rd)
  dim as float t = res.x
  dim as float m = res.y

  ' get material
  if (m<0) then
    ' sky
    col = vec3(0.5, 0.6, 1.0) + rd.y*0.8
  else
    dim as vec3 p = ro + t*rd
    dim as vec3 nor
    if (m=1) then
      ' ground plane with checker board
      nor = vec3(0,1,0)
      'col = mod(rfloor(p.x*1) + rfloor(p.z*1),2)*vec3(1)*.4+.1
      col = mod(floor(p.x*1) + floor(p.z*1),2)*vec3(.4)+.1
    else
      ' primitives
      nor = calcNormal( p )
      col = .5 + .5 * sin( vec3(0.05,0.08,0.10)*(m-1.0) )
    end if

    ' lighitng
    dim as vec3 ref      = reflect( rd, nor )
    dim as float occ      = calcAO( p, nor )
    dim as vec3 light    = normalize( vec3(1, 1, -1) )
    dim as float ambient  = clamp( 0.5+0.5*nor.y, 0.0, 1.0 )
    dim as float diffuse  = clamp( dot( nor, light ), 0.0, 1.0 )
    dim as float bac      = clamp( dot( nor, normalize(vec3(-light.x,0.0,-light.z))), 0.0, 1.0 )*clamp( 1.0-p.y,0.0,1.0)
    dim as float dom      = smoothstep( -0.1, 0.1, ref.y )
    dim as float fr       = pow(clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 )
    dim as float specular = pow(clamp( dot( ref, light ), 0.0, 1.0 ),16.0)

    diffuse *= softshadow( p, light, 0.02, 2.5 )
    dom     *= softshadow( p, ref  , 0.02, 2.5 )

    dim as vec3 lin
    lin  = 1.20*diffuse *vec3(1.00,0.85,0.55)
    lin += 1.20*specular*vec3(1.00,0.85,0.55)*diffuse
    lin += 0.20*ambient *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 float ) 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(fragColor as vec4, fragCoord as const vec2)
  dim as float rTime = iGlobalTime '*0.01
  dim as vec2 q     = fragCoord/iResolution.xy
  dim as vec2 p     = q*2-1
  ' aspect ratio
  p.x *= iResolution.x/iResolution.y

  ' camera
  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(fragColor as vec4, fragCoord as const vec2)
  dim as vec2 uv = fragCoord / iResolution.xy
  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*=.5 : scr_h*=.5

scr_w=64*5 : scr_h=48*5

#ifdef USE_PAGES
screenres  scr_w,scr_h,32,2
screenset 1,0
dim as integer scr_pitch
screeninfo ,,,,scr_pitch
scr_pitch shr=2
#else
screenres  scr_w,scr_h,32
#endif

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

dim as vec2 fragCoord
dim as vec4 fragColor
'dim as double tShaderStart=timer()
dim as double tFrameStart=0 'tShaderStart
dim as ulong colour
dim as boolean bQuit
while bQuit=false
  fragCoord.y=scr_h-1 ' OpenGL draws from bottom to top
  #ifdef USE_PAGES
  dim as ulong ptr row = ScreenPtr()
  #endif
  for y as integer= 0 to scr_h-1
    #ifdef USE_PAGES
    dim as ulong ptr pixel=row
    #else
    screenlock
    #endif
    for x as integer=0 to scr_w-1
      fragCoord.x=x
      ' call for every pixel the fragment shader
      mainImage(fragColor, fragCoord)
      colour=fragColor
      #ifdef USE_PAGES
      pixel[x] = colour
      #else
      pset(x,y),colour
      #endif
    next
   
    bQuit = iif(asc(inkey())=27,true,false)
    if bQuit then exit for
   
    ' next row
    #ifdef USE_PAGES
    row+=scr_pitch  : flip
    #else
    screenunlock y,y
    sleep 1
    #endif
    fragCoord.y-=1
   
  next
 
  iGlobalTime+= 1/24 '=timer()
  var FPS = 1/(iGlobalTime-tFrameStart)
  windowtitle "time: " & (iGlobalTime-tFrameStart)'str(int(FPS*100)/100)
  tFrameStart=iGlobalTime

  'iGlobalTime-=tShaderStart
  frames+=1
wend
original fragment shader:

Code: Select all

// 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

// joshy note: no texture sampler

float sdPlane(vec3 p) {
  return p.y;
}

float sdSphere(vec3 p, float s) {
  return length(p)-s;
}

float sdBox(vec3 p, vec3 b) {
  vec3 d = abs(p) - b;
  return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
}

float sdEllipsoid(in vec3 p, in vec3 r) {
  return (length( p/r ) - 1.0) * min(min(r.x,r.y),r.z);
}

float udRoundBox( vec3 p, vec3 b, float r) {
  return length(max(abs(p)-b,0.0))-r;
}

float sdTorus( vec3 p, vec2 t) {
  return length( vec2(length(p.xz)-t.x,p.y) )-t.y;
}

float sdHexPrism( vec3 p, vec2 h) {
  vec3 q = abs(p);
  float d1 = q.z-h.y;
  float 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.);
}

float sdCapsule(vec3 p, vec3 a, vec3 b, float r) {
  vec3 pa = p-a, ba = b-a;
  float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
  return length( pa - ba*h ) - r;
}

float sdTriPrism(vec3 p, vec2 h) {
  vec3 q = abs(p);
  float d1 = q.z-h.y;
  float 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.);
}

float sdCylinder(vec3 p, vec2 h) {
  vec2 d = abs(vec2(length(p.xz),p.y)) - h;
  return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}

float sdCone(in vec3 p, in vec3 c) {
  vec2 q = vec2( length(p.xz), p.y );
  float d1 = -q.y-c.z;
  float d2 = max( dot(q,c.xy), q.y);
  return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}

float sdConeSection( in vec3 p, in float h, in float r1, in float r2) {
  float d1 = -p.y - h;
  float q = p.y - h;
  float si = 0.5*(r1-r2)/h;
  float 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.);
}

float length2(vec2 p) {
  return sqrt(p.x*p.x + p.y*p.y);
}

float length6(vec2 p) {
  p = p*p*p; p = p*p;
  return pow( p.x + p.y, 1.0/6.0 );
}

float length8(vec2 p) {
  p = p*p; 
  p = p*p; 
  p = p*p;
  return pow( p.x + p.y, 1.0/8.0 );
}

float sdTorus82( vec3 p, vec2 t) {
  vec2 q = vec2(length2(p.xz)-t.x,p.y);
  return length8(q)-t.y;
}

float sdTorus88( vec3 p, vec2 t) {
  vec2 q = vec2(length8(p.xz)-t.x,p.y);
  return length8(q)-t.y;
}

float sdCylinder6( vec3 p, vec2 h) {
  return max( length6(p.xz)-h.x, abs(p.y)-h.y );
}

float opS( float d1, float d2 ) {
  return max(-d2,d1);
}

vec2 opU( vec2 d1, vec2 d2) {
  return (d1.x<d2.x) ? d1 : d2;
}

vec3 opRep( vec3 p, vec3 c) {
  return mod(p,c)-0.5*c;
}

vec3 opTwist(vec3 p) {
  float  c = cos(10.0*p.y+10.0);
  float  s = sin(10.0*p.y+10.0);
  mat2   m = mat2(c,-s,s,c);
  return vec3(m*p.xz,p.y);
}

vec2 map(in vec3 pos ) {
  vec2 res;
  res = opU(vec2( sdPlane(     pos), 1.0 ), vec2( sdSphere(    pos-vec3( 0.0,0.25, 0.0), 0.25 ), 46.9 ) );
  res = opU( res, vec2( sdBox(       pos-vec3( 1.0,0.25, 0.0), vec3(0.25) ), 3.0 ) );
  res = opU( res, vec2( udRoundBox(  pos-vec3( 1.0,0.25, 1.0), vec3(0.15), 0.1 ), 41.0 ) );
  res = opU( res, vec2( sdTorus(     pos-vec3( 0.0,0.25, 1.0), vec2(0.20,0.05) ), 25.0 ) );
  res = opU( res, vec2( sdCapsule(   pos,vec3(-1.3,0.10,-0.1), vec3(-0.8,0.50,0.2), 0.1  ), 31.9 ) );
  res = opU( res, vec2( sdTriPrism(  pos-vec3(-1.0,0.25,-1.0), vec2(0.25,0.05) ),43.5 ) );
  res = opU( res, vec2( sdCylinder(  pos-vec3( 1.0,0.30,-1.0), vec2(0.1,0.2) ), 8.0 ) );
  res = opU( res, vec2( sdCone(      pos-vec3( 0.0,0.50,-1.0), vec3(0.8,0.6,0.3) ), 55.0 ) );
  res = opU( res, vec2( sdTorus82(   pos-vec3( 0.0,0.25, 2.0), vec2(0.20,0.05) ),50.0 ) );
  res = opU( res, vec2( sdTorus88(   pos-vec3(-1.0,0.25, 2.0), vec2(0.20,0.05) ),43.0 ) );
  res = opU( res, vec2( sdCylinder6( pos-vec3( 1.0,0.30, 2.0), vec2(0.1,0.2) ), 12.0 ) );
  res = opU( res, vec2( sdHexPrism(  pos-vec3(-1.0,0.20, 1.0), vec2(0.25,0.05) ),17.0 ) );
  res = opU( res, vec2( opS(udRoundBox(pos-vec3(-2.0,0.2, 1.0), vec3(0.15),0.05), sdSphere(pos-vec3(-2.0,0.2, 1.0), 0.25)), 13.0 ) );
  res = opU( res, vec2( opS(sdTorus82(pos-vec3(-2.0,0.2, 0.0), vec2(0.20,0.1)), sdCylinder(opRep( vec3(atan(pos.x+2.0,pos.z)/6.2831, pos.y,0.02+0.5*length(pos-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(    pos-vec3(-2.0,0.25,-1.0), 0.2 ) + 0.03*sin(50.0*pos.x)*sin(50.0*pos.y)*sin(50.0*pos.z), 65.0 ));
  res = opU( res, vec2( 0.5*sdTorus( opTwist(pos-vec3(-2.0,0.25, 2.0)),vec2(0.20,0.05)), 46.7 ) );
  res = opU( res, vec2(sdConeSection( pos-vec3( 0.0,0.35,-2.0), 0.15, 0.2, 0.1 ), 13.67 ) );
  res = opU( res, vec2(sdEllipsoid( pos-vec3( 1.0,0.35,-2.0), vec3(0.15, 0.2, 0.05) ), 43.17 ) );
  return res;
}

vec2 castRay( in vec3 ro, in vec3 rd) {
  float tmin = 1.0;
  float tmax = 20.0;
  float precis = 0.002;
  float t = tmin;
  float m = -1.0;
  for ( int i=0; i<50; i++ ) {
    vec2 res = map( ro+rd*t );
    if( res.x<precis || t>tmax ) break;
    t += res.x;
    m = res.y;
  }
  if( t>tmax ) m=-1.0;
  return vec2( t, m );
}

float softshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax) {
  float res = 1.0;
  float t = mint;
  for (int i=0; i<16; i++) {
    float h = map( ro + rd*t ).x;
    res = min( res, 8.0*h/t );
    t += clamp( h, 0.02, 0.10 );
    if( h<0.001 || t>tmax ) break;
  }
  return clamp( res, 0.0, 1.0 );
}

vec3 calcNormal( in vec3 pos ) {
  vec3 eps = vec3( 0.001, 0.0, 0.0 );
  vec3 nor = vec3(map(pos+eps.xyy).x - map(pos-eps.xyy).x,
                  map(pos+eps.yxy).x - map(pos-eps.yxy).x,
                  map(pos+eps.yyx).x - map(pos-eps.yyx).x );
  return normalize(nor);
}

float calcAO(in vec3 pos, in vec3 nor) {
  float occ = 0.0;
  float sca = 1.0;
  for( int i=0; i<5; i++) {
    float hr = 0.01 + 0.12*float(i)/4.0;
    vec3 aopos =  nor * hr + pos;
    float dd = map( aopos ).x;
    occ += -(dd-hr)*sca;
    sca *= 0.95;
  }
  return clamp( 1.0 - 3.0*occ, 0.0, 1.0 );    
}

vec3 render(in vec3 ro, in vec3 rd) { 
  vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8;
  vec2 res = castRay(ro,rd);
  float t = res.x;
  float m = res.y;

  if ( m>-0.5 ) {
    vec3 pos = ro + t*rd;
    vec3 nor = calcNormal( pos );
    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 ) {
      float f = mod( floor(5.0*pos.z) + floor(5.0*pos.x), 2.0);
      col = 0.4 + 0.1*f*vec3(1.0);
    }
    // lighitng
    float occ = calcAO( pos, nor );
    vec3  lig = normalize( vec3(-0.6, 0.7, -0.5) );
    float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 );
    float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
    float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0);
    float dom = smoothstep( -0.1, 0.1, ref.y );
    float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 );
    float spe = pow(clamp( dot( ref, lig ), 0.0, 1.0 ),16.0);
        
    dif *= softshadow( pos, lig, 0.02, 2.5 );
    dom *= softshadow( pos, ref, 0.02, 2.5 );

    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*fre*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 ) );

  }
  return vec3( clamp(col,0.0,1.0) );
}

mat3 setCamera( in vec3 ro, in vec3 ta, float cr) {
  vec3 cw = normalize(ta-ro);
  vec3 cp = vec3(sin(cr), cos(cr),0.0);
  vec3 cu = normalize( cross(cw,cp) );
  vec3 cv = normalize( cross(cu,cw) );
  return mat3( cu, cv, cw );
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
  vec2 q = fragCoord.xy/iResolution.xy;
  vec2 p = -1.0+2.0*q;
  p.x *= iResolution.x/iResolution.y;
  vec2 mo = iMouse.xy/iResolution.xy;
  float time = 15.0 + iGlobalTime;

  // camera  
  vec3 ro = vec3( -0.5+3.5*cos(0.1*time + 6.0*mo.x), 1.0 + 2.0*mo.y, 0.5 + 3.5*sin(0.1*time + 6.0*mo.x) );
  vec3 ta = vec3( -0.5, -0.4, 0.5 );

  // camera-to-world transformation
  mat3 ca = setCamera( ro, ta, 0.0 );

  // ray direction
  vec3 rd = ca * normalize( vec3(p.xy,2.0) );

  // render  
  vec3 col = render( ro, rd );

  col = pow( col, vec3(0.4545) );
  fragColor=vec4( col, 1.0 );
}

Last edited by D.J.Peters on Oct 12, 2022 19:15, edited 5 times in total.
dafhi
Posts: 1641
Joined: Jun 04, 2005 9:51

Re: OpenGL shader language math in FreeBASIC.

Post by dafhi »

too awesome. I saw this at shadertoy also. When I get the inspiration I will continue my work on path tracer :D
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: OpenGL shader language math in FreeBASIC.

Post by angros47 »

It could be used with OpenB3D, to build callback function for FluidFunction.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: OpenGL shader language math in FreeBASIC.

Post by D.J.Peters »

Code: Select all

#include "glslstyle.bi"

' port of the "Business Card Ray-tracer" as shader

' https://www.shadertoy.com/view/MsX3Wf

dim shared as real 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

const as integer raysPerPixel = 1 ' 64
const as real PI          = 3.14159265359
const as real inv_256     = 0.00390625
const as real PI_2_DIV_64 = 0.09817477042
const as real PI_2_DIV_3  = 2.*PI/3.

function funcT(o as vec3, d as vec3, byref t as single, n as vec3) as integer
  t=1000.0f
  dim as integer m
  dim as real p=-o.z/d.z
  if (.01f<p) then
    t=p
    n=vec3(0,0,1)
    m=1
  end if

  dim as vec2 sphere = vec2(10.0f,2.0f*sinf(iGlobalTime))
  dim as vec3 p2 = o + vec3(-sphere.x,0.,-sphere.y-4.0f)
  dim as real b = dot(p2,d)
  dim as real c = dot(p2,p2) - 1.0f
  dim as real q = b*b-c
  if (q>0.0f) then
    dim as real s=-b-sqrtf(q)
    if (s<t andalso s>0.01f) then
      t=s
      n=normalize(p2+d*t)
      m=2
    end if
  end if
  return m
end function

function funcR(uv as vec2) as real
  return fract(sinf(dot(normalize(uv.xy) ,vec2(12.9898f,78.233f))) * 43758.5453f)
end function


sub mainImage(fragColor as vec4, fragCoord as vec2)
  dim as vec2 uv = fragCoord.xy / iResolution.xy                  ' some optimization here to do
  dim as vec3 g = normalize(vec3(-10.0f,-16.0f,0.0f))             '  Camera direction
  dim as vec3 a = normalize(cross(g,vec3(0.0f,0.0f,1.0f)))*0.002f '  Camera up vector...Seem Z is pointing up :/ WTF !
  dim as vec3 b = normalize(cross(a,g))*0.002f                    '  The right vector, obtained via traditional cross-product
  dim as vec3 c = (a+b) * -256.0f + g                             '  WTF ? See https:' news.ycombinator.com/item?id=6425965 for more.
  ' Reuse the vector class to store not XYZ but a RGB pixel color
  dim as vec3  p = vec3(13.0f,13.0f,13.0f)                        '  Default pixel color is almost pitch black
  dim as real ratio =  64.0f/raysPerPixel

  ' Cast 64 rays per pixel (For blur (stochastic sampling) and soft-shadows.
  for k as integer=1 to raysPerPixel
    dim as real factor = 2.0f*PI/raysPerPixel
    dim as vec2 rand0 = vec2(fabs(cosf(k*factor)),fabs(sinf(k*factor)))
    dim as vec3 t=a*(funcR(uv+0.05f*rand0)-.5f)*99.0f + b*(funcR(0.06f*rand0)-.5)*99.0f
    dim as vec3 o = vec3(17.0f,16.0f,8.0f)+t
    dim as vec3 d = normalize(t*-1.0f + (a*(funcR(0.07f*rand0)+fragCoord.x) + b*(fragCoord.y+funcR(0.08f*rand0))+c)*16.0f)
    dim as vec3 cumulated_color = vec3(0.0f)
    dim as real   ts = any
    dim as vec3    ns = any
    dim as integer ms = funcT(o,d,ts,ns)
    dim as real attenuationFactor = 1.0f

    for i as integer = 0 to 1 ' Max recursivity - 3 bounces 
      dim as real fs = i
      if (0=ms) then
       ' No sphere found and the ray goes upward: Generate a sky color 
        cumulated_color= cumulated_color + attenuationFactor * vec3(0.7f,0.6f,1.0f)*pow(1.-d.z,4.0f)
        attenuationFactor = 0.0f
      end if
      ' A sphere was maybe hit.
      dim as vec2 rand0 = vec2(fabs(cosf(fs*PI_2_DIV_3)),fabs(sinf(fs*PI_2_DIV_3)))
      '  h = intersection coordinate
      dim as vec3 hs = o + d*ts
      '  'l' = direction to light (with random delta for soft-shadows).
      dim as vec3 ls = normalize(vec3(9.0f+funcR(uv+0.05f*rand0),9.0f+funcR(0.06f*rand0),16.0f)+hs*-1.0f)
      '  r = The half-vector
      dim as vec3 rs = d+ns*(dot(ns,d)*-2.0f)

      ' Calculated the lambertian factor
      dim as real bs=dot(ls,ns)

      ' Calculate illumination factor (lambertian coefficient > 0 or in shadow)?
      if (bs<0.0f orelse funcT(hs,ls,ts,ns) <>0) then bs=0.0f

      '  Calculate the color 'p' with diffuse and specular component
      dim as real ps
      if (bs <> 0.0f) then ps = pow(dot(ls,rs),99.0f)
     
      if (ms=1) then
        hs=hs*0.2f ' No sphere was hit and the ray was going downward: Generate a floor color
        dim as real cond = ceil(hs.x + iGlobalTime) + ceil(hs.y+iGlobalTime)
        ' if odd
        if (fract(cond/2.0f) = 0.0f) then
          cumulated_color = cumulated_color + attenuationFactor * vec3(3.0f,1.0f,1.0f) * (bs*0.2f+0.1f)
        else
          cumulated_color = cumulated_color + attenuationFactor * vec3(3.0f,3.0f,3.0f) * (bs*0.2f+0.1f)
        end if
        attenuationFactor = 0.0f
      end if
      cumulated_color += attenuationFactor*vec3(ps)
      attenuationFactor *= 0.5f
      o = hs
      d = rs
      ms=funcT(hs,rs,ts,ns)
    next

    p= (ratio*cumulated_color*3.5f + p)
  next
 
  fragColor = vec4(inv_256*p, 1.0f)
end sub

'
' main
'
dim as vec2 fragCoord
dim as vec4 fragColor

screenres 320,320/16*9,32


dim as integer scr_w,scr_h,scr_pitch,frames,mx,my,mb,fps
screeninfo scr_w,scr_h,,,scr_pitch
scr_pitch shr=2
iResolution.x=scr_w
iResolution.y=scr_h
dim as double tLast=timer()
while inkey()=""
  screenlock
  dim as ulong ptr row=screenptr()
  for y as integer= scr_h-1 to 0 step -1
    fragCoord.y=y
    dim as ulong ptr pixel=row
    for x as integer=0 to scr_w-1
      fragCoord.x=x
      mainImage(fragColor, fragCoord)
      pixel[x] = fragColor
    next
    row+=scr_pitch
  next
  screenunlock
  sleep 1
  frames+=1
  iGlobalTime+=1/3
  if mod(frames,10) = 0 then
    var tNow=Timer()
    fps = 10/(tNow-tLast)
    windowtitle "fps: " & fps
    tLast=tNow
  end if
wend
Last edited by D.J.Peters on Aug 02, 2019 21:42, edited 2 times in total.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: OpenGL shader language math in FreeBASIC.

Post by Tourist Trap »

For me it renders quite slowly... But anyway thanks it's great to have a home 3D renderer.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: OpenGL shader language math in FreeBASIC.

Post by D.J.Peters »

Tourist Trap wrote:For me it renders quite slowly...
That's normal the "shader" runs on the CPU in FreeBASIC :-)

You know what GLSL is ?

Joshy
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: OpenGL shader language math in FreeBASIC.

Post by Tourist Trap »

D.J.Peters wrote:You know what GLSL is ?
Not really. But it's absolutey ok, rendering a single scene is already very great.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: OpenGL shader language math in FreeBASIC.

Post by D.J.Peters »

@Tourist Trap if you never saw it on GPU before here is it.

Joshy

Code: Select all

dim as string CODE
CODE  = !"// Created by inigo quilez - iq/2013\n"
CODE &= !"// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.\n"

CODE &= !"// A list of usefull distance function to simple primitives, and an example on how to \n"
CODE &= !"// do some interesting boolean operations, repetition and displacement.\n"

CODE &= !"// More info here: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\n"

CODE &= !"// joshy note: no texture sampler\n"

CODE &= !"float sdPlane(vec3 p) {\n"
CODE &= !"  return p.y;\n"
CODE &= !"}\n"

CODE &= !"float sdSphere(vec3 p, float s) {\n"
CODE &= !"  return length(p)-s;\n"
CODE &= !"}\n"

CODE &= !"float sdBox(vec3 p, vec3 b) {\n"
CODE &= !"  vec3 d = abs(p) - b;\n"
CODE &= !"  return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));\n"
CODE &= !"}\n"

CODE &= !"float sdEllipsoid(in vec3 p, in vec3 r) {\n"
CODE &= !"  return (length( p/r ) - 1.0) * min(min(r.x,r.y),r.z);\n"
CODE &= !"}\n"

CODE &= !"float udRoundBox( vec3 p, vec3 b, float r) {\n"
CODE &= !"  return length(max(abs(p)-b,0.0))-r;\n"
CODE &= !"}\n"

CODE &= !"float sdTorus( vec3 p, vec2 t) {\n"
CODE &= !"  return length( vec2(length(p.xz)-t.x,p.y) )-t.y;\n"
CODE &= !"}\n"

CODE &= !"float sdHexPrism( vec3 p, vec2 h) {\n"
CODE &= !"  vec3 q = abs(p);\n"
CODE &= !"  float d1 = q.z-h.y;\n"
CODE &= !"  float d2 = max((q.x*0.866025+q.y*0.5),q.y)-h.x;\n"
CODE &= !"  return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);\n"
CODE &= !"}\n"

CODE &= !"float sdCapsule(vec3 p, vec3 a, vec3 b, float r) {\n"
CODE &= !"  vec3 pa = p-a, ba = b-a;\n"
CODE &= !"  float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
CODE &= !"  return length( pa - ba*h ) - r;\n"
CODE &= !"}\n"

CODE &= !"float sdTriPrism(vec3 p, vec2 h) {\n"
CODE &= !"  vec3 q = abs(p);\n"
CODE &= !"  float d1 = q.z-h.y;\n"
CODE &= !"  float d2 = max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5;\n"
CODE &= !"  return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);\n"
CODE &= !"}\n"

CODE &= !"float sdCylinder(vec3 p, vec2 h) {\n"
CODE &= !"  vec2 d = abs(vec2(length(p.xz),p.y)) - h;\n"
CODE &= !"  return min(max(d.x,d.y),0.0) + length(max(d,0.0));\n"
CODE &= !"}\n"

CODE &= !"float sdCone(in vec3 p, in vec3 c) {\n"
CODE &= !"  vec2 q = vec2( length(p.xz), p.y );\n"
CODE &= !"  float d1 = -q.y-c.z;\n"
CODE &= !"  float d2 = max( dot(q,c.xy), q.y);\n"
CODE &= !"  return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);\n"
CODE &= !"}\n"

CODE &= !"float sdConeSection( in vec3 p, in float h, in float r1, in float r2) {\n"
CODE &= !"  float d1 = -p.y - h;\n"
CODE &= !"  float q = p.y - h;\n"
CODE &= !"  float si = 0.5*(r1-r2)/h;\n"
CODE &= !"  float d2 = max( sqrt( dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q );\n"
CODE &= !"  return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);\n"
CODE &= !"}\n"

CODE &= !"float length2(vec2 p) {\n"
CODE &= !"  return sqrt(p.x*p.x + p.y*p.y);\n"
CODE &= !"}\n"

CODE &= !"float length6(vec2 p) {\n"
CODE &= !"  p = p*p*p; p = p*p;\n"
CODE &= !"  return pow( p.x + p.y, 1.0/6.0 );\n"
CODE &= !"}\n"

CODE &= !"float length8(vec2 p) {\n"
CODE &= !"  p = p*p; \n"
CODE &= !"  p = p*p; \n"
CODE &= !"  p = p*p;\n"
CODE &= !"  return pow( p.x + p.y, 1.0/8.0 );\n"
CODE &= !"}\n"

CODE &= !"float sdTorus82( vec3 p, vec2 t) {\n"
CODE &= !"  vec2 q = vec2(length2(p.xz)-t.x,p.y);\n"
CODE &= !"  return length8(q)-t.y;\n"
CODE &= !"}\n"

CODE &= !"float sdTorus88( vec3 p, vec2 t) {\n"
CODE &= !"  vec2 q = vec2(length8(p.xz)-t.x,p.y);\n"
CODE &= !"  return length8(q)-t.y;\n"
CODE &= !"}\n"

CODE &= !"float sdCylinder6( vec3 p, vec2 h) {\n"
CODE &= !"  return max( length6(p.xz)-h.x, abs(p.y)-h.y );\n"
CODE &= !"}\n"

CODE &= !"float opS( float d1, float d2 ) {\n"
CODE &= !"  return max(-d2,d1);\n"
CODE &= !"}\n"

CODE &= !"vec2 opU( vec2 d1, vec2 d2) {\n"
CODE &= !"  return (d1.x<d2.x) ? d1 : d2;\n"
CODE &= !"}\n"

CODE &= !"vec3 opRep( vec3 p, vec3 c) {\n"
CODE &= !"  return mod(p,c)-0.5*c;\n"
CODE &= !"}\n"

CODE &= !"vec3 opTwist(vec3 p) {\n"
CODE &= !"  float  c = cos(10.0*p.y+10.0);\n"
CODE &= !"  float  s = sin(10.0*p.y+10.0);\n"
CODE &= !"  mat2   m = mat2(c,-s,s,c);\n"
CODE &= !"  return vec3(m*p.xz,p.y);\n"
CODE &= !"}\n"

CODE &= !"vec2 map(in vec3 pos ) {\n"
CODE &= !"  vec2 res; \n"
CODE &= !"  res = opU(vec2( sdPlane(     pos), 1.0 ), vec2( sdSphere(    pos-vec3( 0.0,0.25, 0.0), 0.25 ), 46.9 ) );\n"
CODE &= !"  res = opU( res, vec2( sdBox(       pos-vec3( 1.0,0.25, 0.0), vec3(0.25) ), 3.0 ) );\n"
CODE &= !"  res = opU( res, vec2( udRoundBox(  pos-vec3( 1.0,0.25, 1.0), vec3(0.15), 0.1 ), 41.0 ) );\n"
CODE &= !"  res = opU( res, vec2( sdTorus(     pos-vec3( 0.0,0.25, 1.0), vec2(0.20,0.05) ), 25.0 ) );\n"
CODE &= !"  res = opU( res, vec2( sdCapsule(   pos,vec3(-1.3,0.10,-0.1), vec3(-0.8,0.50,0.2), 0.1  ), 31.9 ) );\n"
CODE &= !"  res = opU( res, vec2( sdTriPrism(  pos-vec3(-1.0,0.25,-1.0), vec2(0.25,0.05) ),43.5 ) );\n"
CODE &= !"  res = opU( res, vec2( sdCylinder(  pos-vec3( 1.0,0.30,-1.0), vec2(0.1,0.2) ), 8.0 ) );\n"
CODE &= !"  res = opU( res, vec2( sdCone(      pos-vec3( 0.0,0.50,-1.0), vec3(0.8,0.6,0.3) ), 55.0 ) );\n"
CODE &= !"  res = opU( res, vec2( sdTorus82(   pos-vec3( 0.0,0.25, 2.0), vec2(0.20,0.05) ),50.0 ) );\n"
CODE &= !"  res = opU( res, vec2( sdTorus88(   pos-vec3(-1.0,0.25, 2.0), vec2(0.20,0.05) ),43.0 ) );\n"
CODE &= !"  res = opU( res, vec2( sdCylinder6( pos-vec3( 1.0,0.30, 2.0), vec2(0.1,0.2) ), 12.0 ) );\n"
CODE &= !"  res = opU( res, vec2( sdHexPrism(  pos-vec3(-1.0,0.20, 1.0), vec2(0.25,0.05) ),17.0 ) );\n"
CODE &= !"  res = opU( res, vec2( opS(udRoundBox(pos-vec3(-2.0,0.2, 1.0), vec3(0.15),0.05), sdSphere(pos-vec3(-2.0,0.2, 1.0), 0.25)), 13.0 ) );\n"
CODE &= !"  res = opU( res, vec2( opS(sdTorus82(pos-vec3(-2.0,0.2, 0.0), vec2(0.20,0.1)), sdCylinder(opRep( vec3(atan(pos.x+2.0,pos.z)/6.2831, pos.y,0.02+0.5*length(pos-vec3(-2.0,0.2, 0.0))), vec3(0.05,1.0,0.05)), vec2(0.02,0.6))), 51.0 ) );\n"
CODE &= !"  res = opU( res, vec2( 0.7*sdSphere(    pos-vec3(-2.0,0.25,-1.0), 0.2 ) + 0.03*sin(50.0*pos.x)*sin(50.0*pos.y)*sin(50.0*pos.z), 65.0 ));\n"
CODE &= !"  res = opU( res, vec2( 0.5*sdTorus( opTwist(pos-vec3(-2.0,0.25, 2.0)),vec2(0.20,0.05)), 46.7 ) );\n"
CODE &= !"  res = opU( res, vec2(sdConeSection( pos-vec3( 0.0,0.35,-2.0), 0.15, 0.2, 0.1 ), 13.67 ) );\n"
CODE &= !"  res = opU( res, vec2(sdEllipsoid( pos-vec3( 1.0,0.35,-2.0), vec3(0.15, 0.2, 0.05) ), 43.17 ) );\n"
CODE &= !"  return res;\n"
CODE &= !"}\n"

CODE &= !"vec2 castRay( in vec3 ro, in vec3 rd) {\n"
CODE &= !"  float tmin = 1.0;\n"
CODE &= !"  float tmax = 20.0;\n"
CODE &= !"  float precis = 0.002;\n"
CODE &= !"  float t = tmin;\n"
CODE &= !"  float m = -1.0;\n"
CODE &= !"  for ( int i=0; i<50; i++ ) {\n"
CODE &= !"    vec2 res = map( ro+rd*t );\n"
CODE &= !"    if( res.x<precis || t>tmax ) break;\n"
CODE &= !"    t += res.x;\n"
CODE &= !"    m = res.y;\n"
CODE &= !"  }\n"
CODE &= !"  if( t>tmax ) m=-1.0;\n"
CODE &= !"  return vec2( t, m );\n"
CODE &= !"}\n"

CODE &= !"float softshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax) {\n"
CODE &= !"  float res = 1.0;\n"
CODE &= !"  float t = mint;\n"
CODE &= !"  for (int i=0; i<16; i++) {\n"
CODE &= !"    float h = map( ro + rd*t ).x;\n"
CODE &= !"    res = min( res, 8.0*h/t );\n"
CODE &= !"    t += clamp( h, 0.02, 0.10 );\n"
CODE &= !"    if( h<0.001 || t>tmax ) break;\n"
CODE &= !"  }\n"
CODE &= !"  return clamp( res, 0.0, 1.0 );\n"
CODE &= !"}\n"

CODE &= !"vec3 calcNormal( in vec3 pos ) {\n"
CODE &= !"  vec3 eps = vec3( 0.001, 0.0, 0.0 );\n"
CODE &= !"  vec3 nor = vec3(map(pos+eps.xyy).x - map(pos-eps.xyy).x,\n"
CODE &= !"                  map(pos+eps.yxy).x - map(pos-eps.yxy).x,\n"
CODE &= !"                  map(pos+eps.yyx).x - map(pos-eps.yyx).x );\n"
CODE &= !"  return normalize(nor);\n"
CODE &= !"}\n"

CODE &= !"float calcAO(in vec3 pos, in vec3 nor) {\n"
CODE &= !"  float occ = 0.0;\n"
CODE &= !"  float sca = 1.0;\n"
CODE &= !"  for( int i=0; i<5; i++) {\n"
CODE &= !"    float hr = 0.01 + 0.12*float(i)/4.0;\n"
CODE &= !"    vec3 aopos =  nor * hr + pos;\n"
CODE &= !"    float dd = map( aopos ).x;\n"
CODE &= !"    occ += -(dd-hr)*sca;\n"
CODE &= !"    sca *= 0.95;\n"
CODE &= !"  }\n"
CODE &= !"  return clamp( 1.0 - 3.0*occ, 0.0, 1.0 );    \n"
CODE &= !"}\n"

CODE &= !"vec3 render(in vec3 ro, in vec3 rd) {\n"
CODE &= !"  vec3 col;\n"
CODE &= !"  vec2 res = castRay(ro,rd);\n"
CODE &= !"  float t = res.x;\n"
CODE &= !"  float m = res.y;\n"
CODE &= !"  if ( m>-0.5 ) {\n"
CODE &= !"    vec3 pos = ro + t*rd;\n"
CODE &= !"    vec3 nor = calcNormal( pos );\n"
CODE &= !"    vec3 ref = reflect( rd, nor );\n"
CODE &= !"    // ground checker board\n"
CODE &= !"    if ( m<1.5 ) {\n"
CODE &= !"      float f = mod( floor(5.0*pos.z) + floor(5.0*pos.x), 2.0);\n"
CODE &= !"      col = 0.4 + 0.1*f*vec3(1.0);\n"
CODE &= !"    }\n"
CODE &= !"    else\n"
CODE &= !"    {\n"
CODE &= !"      // material        \n"
CODE &= !"      col = 0.45 + 0.3*sin( vec3(0.05,0.08,0.10)*(m-1.0) );\n"
CODE &= !"    }\n"
CODE &= !"    // lighitng\n"
CODE &= !"    float occ = calcAO( pos, nor );\n"
CODE &= !"    vec3  lig = normalize( vec3(-0.6, 0.7, -0.5) );\n"
CODE &= !"    float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 );\n"
CODE &= !"    float dif = clamp( dot( nor, lig ), 0.0, 1.0 );\n"
CODE &= !"    float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0);\n"
CODE &= !"    float dom = smoothstep( -0.1, 0.1, ref.y );\n"
CODE &= !"    float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 );\n"
CODE &= !"    float spe = pow(clamp( dot( ref, lig ), 0.0, 1.0 ),16.0);\n"
CODE &= !"    dif *= softshadow( pos, lig, 0.02, 2.5 );\n"
CODE &= !"    dom *= softshadow( pos, ref, 0.02, 2.5 );\n"
CODE &= !"    vec3 lin = vec3(0.0);\n"
CODE &= !"    lin += 1.20*dif*vec3(1.00,0.85,0.55);\n"
CODE &= !"    lin += 1.20*spe*vec3(1.00,0.85,0.55)*dif;\n"
CODE &= !"    lin += 0.20*amb*vec3(0.50,0.70,1.00)*occ;\n"
CODE &= !"    lin += 0.30*dom*vec3(0.50,0.70,1.00)*occ;\n"
CODE &= !"    lin += 0.30*bac*vec3(0.25,0.25,0.25)*occ;\n"
CODE &= !"    lin += 0.40*fre*vec3(1.00,1.00,1.00)*occ;\n"
CODE &= !"    col = col*lin;\n"
CODE &= !"    col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.002*t*t ) );\n"
CODE &= !"  }\n"
CODE &= !"  else\n"
CODE &= !"  { // sky\n"
CODE &= !"    col = vec3(0.7, 0.9, 1.0) +rd.y*0.8;\n"
CODE &= !"  }\n"
CODE &= !"  return vec3( clamp(col,0.0,1.0) );\n"
CODE &= !"}\n"

CODE &= !"mat3 setCamera( in vec3 ro, in vec3 ta, float cr) {\n"
CODE &= !"  vec3 cw = normalize(ta-ro);\n"
CODE &= !"  vec3 cp = vec3(sin(cr), cos(cr),0.0);\n"
CODE &= !"  vec3 cu = normalize( cross(cw,cp) );\n"
CODE &= !"  vec3 cv = normalize( cross(cu,cw) );\n"
CODE &= !"  return mat3( cu, cv, cw );\n"
CODE &= !"}\n"

CODE &= !"void mainImage(out vec4 fragColor, in vec2 fragCoord) {\n"
CODE &= !"  vec2 q = fragCoord.xy/iResolution.xy;\n"
CODE &= !"  vec2 p = -1.0+2.0*q;\n"
CODE &= !"  p.x *= iResolution.x/iResolution.y;\n"
CODE &= !"  vec2 mo = iMouse.xy/iResolution.xy;\n"
CODE &= !"  float time = 15.0 + iGlobalTime;\n"

CODE &= !"  // camera  \n"
CODE &= !"  vec3 ro = vec3( -0.5+3.5*cos(0.1*time + 6.0*mo.x), 1.0 + 2.0*mo.y, 0.5 + 3.5*sin(0.1*time + 6.0*mo.x) );\n"
CODE &= !"  vec3 ta = vec3( -0.5, -0.4, 0.5 );\n"

CODE &= !"  // camera-to-world transformation\n"
CODE &= !"  mat3 ca = setCamera( ro, ta, 0.0 );\n"

CODE &= !"  // ray direction\n"
CODE &= !"  vec3 rd = ca * normalize( vec3(p.xy,2.0) );\n"

CODE &= !"  // render \n"  
CODE &= !"  vec3 col = render( ro, rd );\n"
CODE &= !"  col = pow( col, vec3(0.4545) );\n"
CODE &= !"  fragColor=vec4( col, 1.0 );\n"
CODE &= !"}\n"


#include once "fbgfx.bi"
#include once "GL/gl.bi"
#include once "GL/glext.bi"

#ifndef NULL
#define NULL 0
#endif


type vec3
  as GLfloat x,y,z
end type

sub ErrorExit(msg as string)
  if screenptr() then screen 0
  dim as integer w,h
  screeninfo w,h : w*=0.75:h*=0.75
  screenres w,h
  print msg
  print "press any key to quit ..."
  beep : sleep : end 1
end sub



' define OpenGL proc's
#define glDefine(n) dim shared as PFN##n##PROC n
' texture
'glDefine(glActiveTexture)

' shader
glDefine(glCreateShader)
glDefine(glDeleteShader)
glDefine(glShaderSource)
glDefine(glCompileShader)
glDefine(glGetShaderiv)
glDefine(glGetShaderInfoLog)

' program
glDefine(glCreateProgram)
glDefine(glDeleteProgram)
glDefine(glAttachShader)
glDefine(glDetachShader)
glDefine(glLinkProgram)
glDefine(glGetProgramiv)
glDefine(glGetProgramInfoLog)
glDefine(glUseProgram)

' uniform
glDefine(glGetUniformLocation)
glDefine(glUniform1f)
glDefine(glUniform2f)
glDefine(glUniform3f)
glDefine(glUniform4f)
glDefine(glUniform1i)

#undef glDefine

sub glScreen(w as integer=640, h as integer=360, b as integer=32, d as integer=24, s as integer=0, f as integer=0)
  if ScreenPtr() then screen 0
  ScreenControl FB.SET_GL_STENCIL_BITS,s
  ScreenControl FB.SET_GL_DEPTH_BITS  ,d
  if ScreenRes(w,h,b,,FB.GFX_OPENGL or iif(f<>0,FB.GFX_FULLSCREEN,0)) then
    ErrorExit("screenres(" & w & "," & h &") failed !")
  end if
  Windowtitle "offline shadertoy.com"

  flip

  ' get OpenGL proc's (abort if something goes wrong)
  #define glProc(n) n = ScreenGLProc(#n) : if n = 0 then ErrorExit(#n)
  ' texture
'  glProc(glActiveTexture)
  ' shader
  glProc(glCreateShader)
  glProc(glDeleteShader)
  glProc(glShaderSource)
  glProc(glCompileShader)
  glProc(glGetShaderiv)
  glProc(glGetShaderInfoLog)
  ' program
  glProc(glCreateProgram)
  glProc(glDeleteProgram)
  glProc(glAttachShader)
  glProc(glDetachShader)
  glProc(glLinkProgram)
  glProc(glGetProgramiv)
  glProc(glGetProgramInfoLog)
  glProc(glUseProgram)
  ' uniform
  glProc(glGetUniformLocation)
  glProc(glUniform1f)
  glProc(glUniform2f)
  glProc(glUniform3f)
  glProc(glUniform4f)
  glProc(glUniform1i)
  #undef glProc

end sub

type ShaderToy
  declare destructor
  declare function CompileFile(Filename as string) as boolean
  declare function CompileCode(Code as string) as boolean
  as GLuint FragmentShader
  as GLuint ProgramObject
  as string Shaderlog
end type

destructor ShaderToy
  if ProgramObject then 
   glUseprogram(0)
   if FragmentShader  then 
     glDetachShader(ProgramObject,FragmentShader)
     glDeleteShader(FragmentShader)
   end if
   glDeleteProgram(ProgramObject)
  end if
end destructor

function ShaderToy.CompileFile(filename as string) as boolean
  dim as string code
  var hFile = FreeFile()
  if open(filename,for input, as #hFile) then 
    ShaderLog = "can't read shader: " & chr(34) & filename  & chr(34) & " !"
    return false
  end if
  while not eof(hFile)
    dim as string aLine
    line input #hFile,aLine
    code &= aLine & !"\n"
  wend
  close #hFile
  return CompileCode(code)
end function

function ShaderToy.CompileCode(UserCode as string) as boolean
  dim as GLint logSize
  dim as GLint status
  
  dim as string FragmentProlog
  FragmentProlog   =!"uniform float     iGlobalTime;  // shader playback time (in seconds)\n"
  FragmentProlog & =!"uniform vec3      iResolution;  // viewport resolution (in pixels)\n"
  FragmentProlog & =!"uniform vec4      iMouse;       // mouse pixel coords. xy: current (if MLB down), zw: click\n"
  FragmentProlog & =!"uniform vec4      iDate;        // (year, month, day, time in seconds)\n"
  FragmentProlog & =!"uniform sampler2D iChannel0;\n"
  FragmentProlog & =!"uniform sampler2D iChannel1;\n"
  FragmentProlog & =!"uniform sampler2D iChannel2;\n"
  FragmentProlog & =!"uniform sampler2D iChannel3;\n"
  
  dim as string FragmentEpilog
  FragmentEpilog  = !"void main() {\n"
  FragmentEpilog &= !"  vec4 color;\n"
  FragmentEpilog &= !"  // call user shader\n"
  FragmentEpilog &= !"  mainImage(color, gl_FragCoord.xy);\n"
  FragmentEpilog &= !"  color.w = 1.0;\n"
  FragmentEpilog &= !"  gl_FragColor = color;\n"
  FragmentEpilog &= !"}\n"

  dim as string FragmentCode = FragmentProlog & UserCode & FragmentEpilog

  FragmentShader = glCreateShader(GL_FRAGMENT_SHADER)
  if FragmentShader=0 then 
    ShaderLog = "glCreateShader(GL_FRAGMENT_SHADER) failed !"
    return false
  end if
  dim as GLchar ptr pCode=strptr(FragmentCode)
  glShaderSource (FragmentShader, 1, @pCode, NULL)
  glCompileShader(FragmentShader)
  glGetShaderiv  (FragmentShader, GL_COMPILE_STATUS, @status)
  if status = GL_FALSE then 
    glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH, @logSize)
    ShaderLog = space(logSize)
    pCode=strptr(ShaderLog)
    glGetShaderInfoLog(FragmentShader, logSize, NULL, pCode)
    ShaderLog = !"glCompileShader(FragmentShader) failed !\n" & Shaderlog
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if

  ProgramObject = glCreateProgram()
  if ProgramObject=0 then 
    ShaderLog = "glCreateProgram() failed !"
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if
  glAttachShader(ProgramObject,FragmentShader)
  glLinkProgram (ProgramObject)
  glGetProgramiv(ProgramObject, GL_LINK_STATUS, @status)
  if (status = GL_FALSE) then
    glGetProgramiv(ProgramObject, GL_INFO_LOG_LENGTH, @logSize)
    ShaderLog = space(logSize) : pCode = strptr(ShaderLog)
    glGetProgramInfoLog (ProgramObject, logSize, NULL, pCode)
    ShaderLog = !"glLinkProgram() failed !\n" & Shaderlog
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if
  return true
end function

'
' main
'


' init Screenres, create the OpenGL context and load some OpenGL procs.
dim as boolean fullscreen=false
dim as integer scr_w=640,scr_h=480
glScreen scr_w,scr_h,,,,fullscreen


' get curent resolution

screeninfo scr_w,scr_h

dim as vec3 v3
v3.x=scr_w     ' width in pixle
v3.y=scr_h     '`height in pixle
v3.z=v3.x/v3.y ' pixel ratio

dim as ShaderToy Shader

if Shader.CompileCode(CODE)=false then
  ErrorExit Shader.ShaderLog
end if  

' enable shader
glUseProgram(Shader.ProgramObject)

' get uniforms locations in shader program
var iGlobalTime = glGetUniformLocation(Shader.ProgramObject,"iGlobalTime")
var iResolution = glGetUniformLocation(Shader.ProgramObject,"iResolution")
var iMouse      = glGetUniformLocation(Shader.ProgramObject,"iMouse")

' set vec3 iResolution
glUniform3f(iResolution,v3.x,v3.y,v3.z)

dim as integer mx,my,mb,frames,fps
dim as double tStart = Timer()
dim as double tLast=tStart
while inkey=""
  dim as double tNow=Timer()
  ' set uniform float iGlobalTime
  glUniform1f(iGlobalTime,tNow-tStart)


  if frames mod 3=0 then
    ' set vec4 iMouse
    if getMouse(mx,my,,mb)=0 then
      if mb then
        glUniform4f(iMouse,mx,my,1,1)
      else
        glUniform4f(iMouse,0,0,0,0)
      end if
    end if
  end if
  'glClear(GL_COLOR_BUFFER_BIT)
  ' draw a rectangle (2 triangles over the whole screen)
  glRectf(-1,-1,1,1)
  flip ' swap the buffers

  frames+=1
  ' update fps
  if frames mod 24=0 then
    fps=24/(tNow-tLast)
    windowtitle "fps: " & fps
    tLast=tNow
  end if

wend

' disable shader
glUseProgram(0)
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: OpenGL shader language math in FreeBASIC.

Post by Tourist Trap »

D.J.Peters wrote:@Tourist Trap if you never saw it on GPU before here is it.
It's stuck in CreateGlShader... How much time should it take in general to render here??
dafhi
Posts: 1641
Joined: Jun 04, 2005 9:51

Re: OpenGL shader language math in FreeBASIC.

Post by dafhi »

5 seconds to initialize, and 10 fps
fatman2021
Posts: 215
Joined: Dec 14, 2013 0:43

Re: OpenGL shader language math in FreeBASIC.

Post by fatman2021 »

D.J.Peters wrote: Feb 21, 2016 13:11 OpenGL shader language math.

It's fresh not all tested ATM. :-)

Based on this reference: http://www.shaderific.com/glsl-functions/

Forum limit 60,000 I can't post it here right klick save as: glslstyle.bi

Joshy

data types: scalar, vec2, vec3, vec4, mat2, mat3, mat4

vector union:
vec2: x,y : s,t
vec3: x,y,z : r.g.b,
vec4: x,y,z,w : r.g.b,a

Swizzling: v2.yx, v2.xx, v3.xyx, v3.xxx, v3.rgb v4.zyx, v4,rgba ...

All math operators are overloaded for scalar, vec2, vec3 and vec4.
+=,-=,*=,/=,+,-,*,/

All math function are overloaded for scalar, vec2, vec3 and vec4.
radians, degrees, sin, cos, tan, asin, acos, atan, pow, exp, log, log2, sqrt
abs, floor, ceil, min, max, clamp, mix, step, smoothstep
length, distance, dot, cross, normalize, faceforward, reflect, refract

added:
boolean: bvec2, bvec3, bvec4
long: ivec2, ivec3, ivec4
matrixCompMult
lessThan, lessThanEqua, greaterThan, greaterThan, greaterThanEqual, equal, notEqual
any, all, not.

NOTE: the step function is renamed in step_ and any in any_
Image
Luxan
Posts: 222
Joined: Feb 18, 2009 12:47
Location: New Zealand

Re: OpenGL shader language math in FreeBASIC.

Post by Luxan »

I'm using Ubuntu 20.04, with a NVIDIA GTX1030 GPU, your code runs very smoothly at 800 x 600 and 40 fps.

I haven't extensively scrutinized your code, I see where you might be constructing
objects from vectors.
A general piece of code for defining these 3d objects, as a function, is suggested.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: OpenGL shader language math in FreeBASIC.

Post by D.J.Peters »

Luxan wrote: Aug 27, 2022 21:43A general piece of code for defining these 3d objects, as a function, is suggested.
Here are the best overview of distance functions: https://iquilezles.org/articles/distfunctions/
(needs some seconds to load the whole page so you can scroll it down)

Joshy
Luxan
Posts: 222
Joined: Feb 18, 2009 12:47
Location: New Zealand

Re: OpenGL shader language math in FreeBASIC.

Post by Luxan »

Fascinating.

Now does the OpenGL language have transpose of a matrix available ?
Post Reply