OpenGL shader language math in FreeBASIC.
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
OpenGL shader language math in FreeBASIC.
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_" !
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.
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: OpenGL shader language math in FreeBASIC.
Premiere first fragment shader runing in FreeBASIC.
Does it makes any sense I don't know but it was fun.
Joshy
FreeBASIC with "glslstyle.bi"
original fragment shader:
Does it makes any sense I don't know but it was fun.
Joshy
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
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.
Re: OpenGL shader language math in FreeBASIC.
too awesome. I saw this at shadertoy also. When I get the inspiration I will continue my work on path tracer :D
Re: OpenGL shader language math in FreeBASIC.
It could be used with OpenB3D, to build callback function for FluidFunction.
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: OpenGL shader language math in FreeBASIC.
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.
-
- Posts: 2958
- Joined: Jun 02, 2015 16:24
Re: OpenGL shader language math in FreeBASIC.
For me it renders quite slowly... But anyway thanks it's great to have a home 3D renderer.
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: OpenGL shader language math in FreeBASIC.
That's normal the "shader" runs on the CPU in FreeBASIC :-)Tourist Trap wrote:For me it renders quite slowly...
You know what GLSL is ?
Joshy
-
- Posts: 2958
- Joined: Jun 02, 2015 16:24
Re: OpenGL shader language math in FreeBASIC.
Not really. But it's absolutey ok, rendering a single scene is already very great.D.J.Peters wrote:You know what GLSL is ?
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: OpenGL shader language math in FreeBASIC.
@Tourist Trap if you never saw it on GPU before here is it.
Joshy
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)
-
- Posts: 2958
- Joined: Jun 02, 2015 16:24
Re: OpenGL shader language math in FreeBASIC.
It's stuck in CreateGlShader... How much time should it take in general to render here??D.J.Peters wrote:@Tourist Trap if you never saw it on GPU before here is it.
Re: OpenGL shader language math in FreeBASIC.
5 seconds to initialize, and 10 fps
-
- Posts: 215
- Joined: Dec 14, 2013 0:43
Re: OpenGL shader language math in FreeBASIC.
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_
Re: OpenGL shader language math in FreeBASIC.
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.
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.
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: OpenGL shader language math in FreeBASIC.
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
Re: OpenGL shader language math in FreeBASIC.
Fascinating.
Now does the OpenGL language have transpose of a matrix available ?
Now does the OpenGL language have transpose of a matrix available ?