Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ##rewrite of Tree of Objects approach
- using Images, ImageView, Gtk.ShortNames, Colors, FixedPointNumbers, StaticArrays, LinearAlgebra, ColorVectorSpace, BenchmarkTools, Profile, StatProfilerHTML
- N = 0
- Nm = Float64
- Nic = Normed{UInt8,8}
- Ct = RGB{Nic}
- abstract type Shader end
- abstract type Sdf end
- #=
- struct RayInfo ## making RayInfo parametric ends up with worse performance
- pos::SVector{3,Nm}
- dir::SVector{3,Nm}
- t_Sdf::Sdf
- step::Nm
- initial::SVector{3,Nm}
- length::Nm
- render_lim::Nm
- end
- =#
- struct RayInfo{G} ## making RayInfo parametric ends up with worse performance
- pos::SVector{3,Nm}
- dir::SVector{3,Nm}
- t_Sdf::G
- step::Nm
- initial::SVector{3,Nm}
- length::Nm
- render_lim::Nm
- end
- function gradient(Sdf::Sdf, Ri::RayInfo)
- local Step = Ri.step
- normalize([(dist(Sdf,Ri.pos+SVector{3,Nm}(Step,0.0,0.0)) - dist(Sdf,Ri.pos))/Step,
- (dist(Sdf,Ri.pos+SVector{3,Nm}(0.0,Step,0.0)) - dist(Sdf,Ri.pos))/Step,
- (dist(Sdf,Ri.pos+SVector{3,Nm}(0.0,0.0,Step)) - dist(Sdf,Ri.pos))/Step])
- end
- struct ConstantShader <: Shader
- color::Ct
- end
- function shade(Shadr::ConstantShader,Ri::RayInfo)
- Shadr.color
- end
- struct Checkbox{S1,S2} <: Shader
- box_size::Nm
- shd1::S1
- shd2::S2
- end
- function shade(Shadr::Checkbox,Ri::RayInfo)
- x,y,z = Ri.pos
- Bs = Shadr.box_size
- if xor(mod(x,2*Bs)>Bs,mod(y,2*Bs)>Bs,mod(z,2*Bs)>Bs)
- shade(Shadr.shd1,Ri)
- else
- shade(Shadr.shd2,Ri)
- end
- end
- struct Spot{S1} <: Shader
- light_pos::SVector{3,Nm}
- brightness::Nm
- shd1::S1
- end
- function shade(Shadr::Spot,Ri::RayInfo)
- shade(Shadr.shd1,Ri)*Nic(min(Nm(1.0),max(Nm(0.1),Shadr.brightness*dot(gradient(Ri.t_Sdf,Ri),normalize(Shadr.light_pos-Ri.pos)))))
- end
- struct Conjun <: Sdf
- coll::Tuple
- end
- function dist(Sdf::Conjun, Position::SVector{3,Nm})
- min(map(x->dist(x,Position),Sdf.coll)...)
- end
- function color(Sdf::Conjun, Ri::RayInfo)
- color(Sdf.coll[argmin(map(x->dist(x,Ri.pos),Sdf.coll))],Ri)
- end
- struct Transl{S1} <: Sdf
- off::SVector{3,Nm}
- vict::S1
- end
- function dist(Sdf::Transl, Position::SVector{3,Nm})
- dist(Sdf.vict,Position-Sdf.off)
- end
- function color(Sdf::Transl, Ri::RayInfo)
- color(Sdf.vict,RayInfo(Ri.pos-Sdf.off,Ri.dir,Ri.t_Sdf,Ri.step,Ri.initial-Sdf.off,Ri.length,Ri.render_lim))
- end
- abstract type SSdf <: Sdf end
- struct Sphere{S1} <: SSdf
- Radius::Nm
- shadr::S1
- end
- function dist(Sph::Sphere, Position::SVector{3,Nm})
- norm(Position)-Sph.Radius
- end
- function color(Sph::Sphere, Ri::RayInfo)
- shade(Sph.shadr,Ri)
- end
- struct Plane{S1} <: SSdf
- normal::SVector{3,Nm} ##Check for normality
- shadr::S1
- end
- function dist(Pln::Plane, Position::SVector{3,Nm})
- norm(dot(Position,Pln.normal))
- end
- function color(Pln::Plane, Ri::RayInfo)
- shade(Pln.shadr,Ri)
- end
- const Red = ConstantShader(Ct(1,0,0))
- const Green = ConstantShader(Ct(0,1,0))
- const Blue = ConstantShader(Ct(0,0,1))
- const Gelb = ConstantShader(Ct(1,1,0))
- const Black = ConstantShader(Ct(0,0,0))
- const White = ConstantShader(Ct(1,1,1))
- const Grey = ConstantShader(Ct(0.5,0.5,0.5))
- const scene = Conjun((
- Transl(SVector{3,Nm}(0,20,0),Sphere(Nm(3.0),Spot(SVector{3,Nm}(0,0,0),Nm(1.5),Red))),
- Transl(SVector{3,Nm}(12,9,-4),Sphere(Nm(12.0),Spot(SVector{3,Nm}(0,0,0),Nm(1.8),Blue))),
- Transl(SVector{3,Nm}(3,-13,0),Sphere(Nm(9.0),Spot(SVector{3,Nm}(0,0,0),Nm(1.0),Green))),
- Sphere(Nm(1.0),White),
- Transl(SVector{3,Nm}(-20,0,0),Sphere(Nm(0.5),White)),
- Transl(SVector{3,Nm}(-18,0,0),Sphere(Nm(1.0),Red)),
- Plane(SVector{3,Nm}(0.0,0.0,1.0),Checkbox(Nm(10),Grey,Black))
- ))
- function raymarch(Pos::SVector{3,Nm},Normal::SVector{3,Nm},Gf::Sdf,Fb::Shader,renderlim::Nm)
- stepsize=Nm(1.0);
- Start=Pos;
- Strecke=Nm(0.0);
- while (stepsize > Nm(0.001))
- global N += 1
- stepsize=dist(Gf,Pos);
- Pos+=Normal*stepsize;
- Strecke+=stepsize
- if Strecke > renderlim
- return shade(Fb,RayInfo(Pos,Normal,Gf,stepsize,Start,Strecke,renderlim-Strecke))
- end
- end
- color(Gf,RayInfo(Pos,Normal,Gf,stepsize,Start,Strecke,renderlim-Strecke))
- end
- function ray_source(x::Real,y::Real,Pos::SVector{3,Nm},Direction::SVector{3,Nm},
- maxx::Int64,maxy::Int64,Sensorxv::SVector{3,Nm},Sensoryv::SVector{3,Nm})
- (SVector{3,Nm}(Pos+(maxx/2-x)/maxx*Sensorxv+(maxy/2-y)/maxy*Sensoryv),SVector{3,Nm}(normalize(Direction)))
- end
- const x = 800
- const y = 800
- Pic = Array{Ct}(undef,x,y)
- const CamPosition = SVector{3,Nm}(-10.0,10.0,20.0)
- const Normal = SVector{3,Nm}(10.0,-10.0,-20.0)
- const SclX = Nm(60.0)
- const SclY = Nm(60.0)
- const Ortho1 = SVector{3,Nm}( 0.0, -0.8944271909999159, 0.4472135954999579)
- const Ortho2 = SVector{3,Nm}( 0.9128709291752769, 0.18257418583505536, 0.3651483716701107 )
- #=
- @profile for i=1:x
- for j=1:y
- lpos, lnormal = ray_source(Nm(i),Nm(j),CamPosition,Normal,x,y,SclX * Ortho1,SclY * Ortho2)
- Pic[i,j]=raymarch(lpos,lnormal,scene,Black,Nm(500.0))
- end
- end
- statprofilehtml()
- =#
- #=
- @btime for i=1:x
- for j=1:y
- lpos, lnormal = ray_source(Nm(i),Nm(j),CamPosition,Normal,x,y,SclX * Ortho1,SclY * Ortho2)
- Pic[i,j]=raymarch(lpos,lnormal,scene,Black,Nm(500.0))
- end
- end
- =#
- ## 12.352 s (173535725 allocations: 4.96 GiB) with RayInfo not parametric
- ## 14.537 s (213811941 allocations: 7.19 GiB) with Sdf parametric in RayInfo
- for i=1:x
- for j=1:y
- lpos, lnormal = ray_source(Nm(i),Nm(j),CamPosition,Normal,x,y,SclX * Ortho1,SclY * Ortho2)
- Pic[i,j]=raymarch(lpos,lnormal,scene,Black,Nm(500.0))
- end
- end
- println(N)
- #=
- guidict = imshow(Pic);
- if (!isinteractive())
- # Create a condition object
- c = Condition()
- # Get the window
- win = guidict["gui"]["window"]
- # Notify the condition object when the window closes
- signal_connect(win, :destroy) do widget
- notify(c)
- end
- # Wait for the notification before proceeding ...
- wait(c)
- end
- =#
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement