Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using Images, Colors, ImageView, LinearAlgebra, Gtk.ShortNames, StaticArrays, BenchmarkTools, ForwardDiff, FixedPointNumbers, Profile, StatProfilerHTML
- function ray_source(x::Real,y::Real,Pos::SVector{3},Direction::SVector{3},
- maxx::Int64,maxy::Int64,Sensorxv::SVector{3},Sensoryv::SVector{3})
- (SVector{3}(Pos+(maxx/2-x)/maxx*Sensorxv+(maxy/2-y)/maxy*Sensoryv),SVector{3}(normalize(Direction)))
- end
- const x = 800
- const y = 800
- Picff = Array{RGB{Normed{UInt8,8}}}(undef,x,y)
- PicTos = Array{RGB{Normed{UInt8,8}}}(undef,x,y)
- PicExp = Array{RGB{Normed{UInt8,8}}}(undef,x,y)
- CamPosition = SVector{3}(-10.0,10.0,20.0)
- Normal = SVector{3}(10.0,-10.0,-20.0)
- SclX = 60.0
- SclY = 60.0
- Ortho1 = SVector{3}( 0.0, -0.8944271909999159, 0.4472135954999579)
- Ortho2 = SVector{3}( 0.9128709291752769, 0.18257418583505536, 0.3651483716701107 )
- abstract type Shader end
- abstract type Sdf end
- mutable struct RayInfo
- Position::SVector{3,Float64}
- Direction::SVector{3,Float64}
- lSdf::Sdf
- tSdf::Sdf
- Step::Float64
- Initial::SVector{3,Float64}
- length::Float64
- renderlim::Float64
- end
- function gradient(Sdf::Sdf, Ri::RayInfo)
- local Step = Ri.Step
- normalize([(dist(Sdf,Ri.Position+SVector{3}(Step,0.0,0.0)) - dist(Sdf,Ri.Position))/Step,
- (dist(Sdf,Ri.Position+SVector{3}(0.0,Step,0.0)) - dist(Sdf,Ri.Position))/Step,
- (dist(Sdf,Ri.Position+SVector{3}(0.0,0.0,Step)) - dist(Sdf,Ri.Position))/Step])
- end
- struct ConstantShader <: Shader
- Color::RGB
- end
- function shade(Shadr::ConstantShader,Ri::RayInfo)
- Shadr.Color
- end
- struct Checkbox <: Shader
- BoxSize::Float64
- Shd1::Shader
- Shd2::Shader
- end
- function shade(Shadr::Checkbox,Ri::RayInfo)
- x,y,z = Ri.Position
- Bs = Shadr.BoxSize
- 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 <: Shader
- lightPos::SVector{3,Float64}
- brightness::Float64
- Shd1::Shader
- end
- function shade(Shadr::Spot,Ri::RayInfo)
- shade(Shadr.Shd1,Ri)*min(1,max(0.1,Shadr.brightness*dot(gradient(Ri.tSdf,Ri),normalize(Shadr.lightPos-Ri.Position))))
- end
- struct Conjun <: Sdf
- Coll::Array{Sdf, 1}
- end
- function dist(Sdf::Conjun, Position::SVector{3,Float64})
- min(map(x->dist(x,Position),Sdf.Coll)...)
- end
- function closest(Sdf::Conjun, Position::SVector{3,Float64})
- closest(Sdf.Coll[argmin(map(x->dist(x,Position),Sdf.Coll))],Position)
- end
- struct Transl <: Sdf
- Off::SVector{3,Float64}
- Vict::Sdf
- end
- function dist(Sdf::Transl, Position::SVector{3,Float64})
- dist(Sdf.Vict,Position-Sdf.Off)
- end
- function closest(Sdf::Transl, Position::SVector{3,Float64})
- closest(Sdf.Vict,Position-Sdf.Off)
- end
- abstract type SSdf <: Sdf end
- ## Everything that is Subtype of SSdf must provide color
- function closest(Sdf::SSdf,Position::SVector{3,Float64})
- Sdf
- end
- struct Sphere <: SSdf
- Radius::Float64
- Shadr::Shader
- end
- function dist(Sph::Sphere, Position::SVector{3,Float64})
- norm(Position)-Sph.Radius
- end
- function color(Sph::Sphere, Ri::RayInfo)
- shade(Sph.Shadr,Ri)
- end
- struct Plane <: SSdf
- Normal::SVector{3,Float64} ##Check for normality
- Shadr::Shader
- end
- function dist(Pln::Plane, Position::SVector{3,Float64})
- norm(dot(Position,Pln.Normal))
- end
- function color(Pln::Plane, Ri::RayInfo)
- shade(Pln.Shadr,Ri)
- end
- struct IsometricCamera
- Position::SVector{3,Float64}
- Direction::SVector{3,Float64}
- Sensorx::SVector{3,Float64}
- Sensory::SVector{3,Float64}
- Maxx::Float64
- Maxy::Float64
- function IsometricCamera(Position::SVector{3,Float64}, Direction::SVector{3,Float64}, Sensorx::SVector{3,Float64}, Sensory::SVector{3,Float64}, Maxx::Int64, Maxy::Int64)
- new(Position, normalize(Direction), Sensorx/Maxx, Sensory/Maxy, Maxx/2.0, Maxy/2.0)
- end
- end
- function los(Cam::IsometricCamera,X::Int64,Y::Int64)::Tuple{SVector{3,Float64},SVector{3,Float64}}
- ((X-Cam.Maxx)*Cam.Sensorx+(Y-Cam.Maxy)*Cam.Sensory+Cam.Position,Cam.Direction)
- end
- isocam = IsometricCamera(SVector{3,Float64}(45.0,45.0,45.0),SVector{3,Float64}(-1.0,-1.0,-1.0),45*normalize(SVector{3,Float64}(0.0,1.0,-1.0)),45*normalize(SVector{3,Float64}(1.0,-1.0,-1.0)),x,y)
- const Red = ConstantShader(RGB{Normed{UInt8,8}}(1,0,0))
- const Green = ConstantShader(RGB{Normed{UInt8,8}}(0,1,0))
- const Blue = ConstantShader(RGB{Normed{UInt8,8}}(0,0,1))
- const Gelb = ConstantShader(RGB{Normed{UInt8,8}}(1,1,0))
- const Black = ConstantShader(RGB{Normed{UInt8,8}}(0,0,0))
- const White = ConstantShader(RGB{Normed{UInt8,8}}(1,1,1))
- const Grey = ConstantShader(RGB{Normed{UInt8,8}}(0.5,0.5,0.5))
- function scene_ff(Pos)
- union(trans(sphere(3.0,spot(SVector{3,Float64}(0,0,0),1.5,Red)),SVector{3,Float64}(0,20,0)),
- trans(sphere(12.0,spot(SVector{3,Float64}(0,0,0),1.8,Blue)),SVector{3,Float64}(12,9,-4)),
- trans(sphere(9.0,spot(SVector{3,Float64}(0,0,0),1.0,Green)),SVector{3,Float64}(3,-13,0)),
- sphere(1.0,White),
- trans(sphere(0.5,White),SVector{3,Float64}(-20,0,0)),
- trans(sphere(1.0,Red),SVector{3,Float64}(-18,0,0)),
- plane(SVector{3,Float64}(0.0,0.0,1.0),checkerbox(10,Grey,Black)))(Pos)
- end
- const scene = Conjun([
- Transl(SVector{3,Float64}(0,20,0),Sphere(3.0,Spot(SVector{3,Float64}(0,0,0),1.5,Red))),
- Transl(SVector{3,Float64}(12,9,-4),Sphere(12.0,Spot(SVector{3,Float64}(0,0,0),1.8,Blue))),
- Transl(SVector{3,Float64}(3,-13,0),Sphere(9.0,Spot(SVector{3,Float64}(0,0,0),1.0,Green))),
- Sphere(1.0,White),
- Transl(SVector{3,Float64}(-20,0,0),Sphere(0.5,White)),
- Transl(SVector{3,Float64}(-18,0,0),Sphere(1.0,Red)),
- Plane(SVector(0.0,0.0,1.0),Checkbox(10,Grey,Black))
- ])
- function raymarch(Pos::SVector{3,Float64},Normal::SVector{3,Float64},Sdf::Sdf,Fb::Shader,renderlim::Float64)
- stepsize=1.0;
- Start=Pos;
- Strecke=0.0;
- while (stepsize > 0.001)
- stepsize=dist(scene,Pos);
- Pos+=Normal*stepsize;
- Strecke+=stepsize
- if Strecke > renderlim
- c = closest(Sdf,Pos)
- return shade(Fb,RayInfo(Pos,Normal,c,Sdf,stepsize,Start,Strecke,renderlim-Strecke))
- end
- end
- c = closest(Sdf,Pos)
- color(c,RayInfo(Pos,Normal,c,Sdf,stepsize,Start,Strecke,renderlim-Strecke))
- end
- @btime for h=-10.0:0.5:10.0
- for i=-10.0:0.5:10.0
- for j=-10.0:0.5:10.0
- dist(scene,SVector{3,Float64}(h,i,j))
- end
- end
- end
- ## 65.579 ms (2136551 allocations: 52.58 MiB)
- for i=1:x
- for j=1:y
- lpos, lnormal = ray_source(Float64(i),Float64(j),CamPosition,Normal,x,y,SclX * Ortho1,SclY * Ortho2)
- @profile PicTos[i,j]=raymarch(lpos,lnormal,scene,Black,500.0)
- end
- end
- ## 6.605 s (195129663 allocations: 4.84 GiB)
- statprofilehtml()
- guidict = imshow(PicTos);
- 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