Poprawki do renderowania + nowy model kamery
This commit is contained in:
parent
952b90e79e
commit
a42a7ac1a7
4 changed files with 64 additions and 13 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
|
.CondaPkg
|
||||||
Manifest.toml
|
Manifest.toml
|
||||||
|
|
4
CondaPkg.toml
Normal file
4
CondaPkg.toml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
channels = ["conda-forge"]
|
||||||
|
|
||||||
|
[pip.deps]
|
||||||
|
opencv-python = ""
|
|
@ -1,6 +1,8 @@
|
||||||
module SimpleRayTracer
|
module SimpleRayTracer
|
||||||
|
|
||||||
using LinearAlgebra
|
using LinearAlgebra
|
||||||
|
using StaticArrays
|
||||||
|
|
||||||
using Images
|
using Images
|
||||||
using GeometryBasics
|
using GeometryBasics
|
||||||
using Rotations
|
using Rotations
|
||||||
|
@ -14,20 +16,47 @@ abstract type AbstractObject end
|
||||||
|
|
||||||
struct OrthogonalCamera{T<:AbstractFloat} <: AbstractCamera
|
struct OrthogonalCamera{T<:AbstractFloat} <: AbstractCamera
|
||||||
origin::Vec3{T}
|
origin::Vec3{T}
|
||||||
rotation::RotXYZ{T}
|
|
||||||
size::Tuple{T, T}
|
size::Tuple{T, T}
|
||||||
|
rotation::RotXYZ{T}
|
||||||
# function OrthogonalCamera(o, θ, s)
|
# function OrthogonalCamera(o, θ, s)
|
||||||
# new(o, RotXYZ(0.0, 0.0, 0.0), s)
|
# new(o, RotXYZ(0.0, 0.0, 0.0), s)
|
||||||
# end
|
# end
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_rays(camera::OrthogonalCamera, resolution::Tuple{I, I}) where {I<:Integer}
|
function get_rays(camera::OrthogonalCamera, resolution::Tuple{I, I}) where {I<:Integer}
|
||||||
|
R = camera.rotation
|
||||||
X, Y = camera.size
|
X, Y = camera.size
|
||||||
rx, ry = resolution
|
Nx, Ny = resolution
|
||||||
origins = [Vec3(x, y, 0.0) + camera.origin for x = LinRange(-X, X, rx), y = LinRange(-Y, Y, ry)]
|
screen_pixel_position = [Vec3(x, y, 0.0) + camera.origin for y = LinRange(Y/2, -Y/2, Ny), x = LinRange(-X/2, X/2, Nx)]
|
||||||
[Ray(o, Vec3(0.0, 0.0, 1.0)) for o in origins]
|
[Ray(p, Vec3(0.0, 0.0, 1.0)) for p in screen_pixel_position]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
struct PinHoleCamera{T<:AbstractFloat} <: AbstractCamera
|
||||||
|
origin::Vec3{T}
|
||||||
|
distance::T
|
||||||
|
base::SMatrix{3, 3, T}
|
||||||
|
size::Tuple{T, T}
|
||||||
|
end
|
||||||
|
|
||||||
|
function PinHoleCamera(origin, lookAt, up, distance, size)
|
||||||
|
w = origin - lookAt |> normalize
|
||||||
|
u = cross(up, w) |> normalize
|
||||||
|
v = cross(w, u)
|
||||||
|
B = [u v w]
|
||||||
|
PinHoleCamera(origin, distance, B, size)
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_rays(camera::PinHoleCamera, resolution::Tuple{I, I}) where {I<:Integer}
|
||||||
|
origin = camera.origin
|
||||||
|
d = camera.distance
|
||||||
|
X, Y = camera.size
|
||||||
|
B = camera.base
|
||||||
|
Nx, Ny = resolution
|
||||||
|
[Ray(origin, normalize(B*Vec3(x, y, -d))) for y = LinRange(Y/2, -Y/2, Ny), x = LinRange(-X/2, X/2, Nx)]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct Ray{T<:AbstractFloat}
|
struct Ray{T<:AbstractFloat}
|
||||||
origin::Vec3{T}
|
origin::Vec3{T}
|
||||||
direction::Vec3{T}
|
direction::Vec3{T}
|
||||||
|
@ -85,4 +114,9 @@ function trace_ray(world::World, ray::Ray)::HitInfo
|
||||||
return HitInfo(hit, color)
|
return HitInfo(hit, color)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function render(world, camera, resolution)
|
||||||
|
rays = get_rays(camera, resolution)
|
||||||
|
[trace_ray(world, ray).color for ray in rays];
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
30
rt.jl
30
rt.jl
|
@ -2,7 +2,8 @@ using BenchmarkTools
|
||||||
using LinearAlgebra
|
using LinearAlgebra
|
||||||
using Rotations
|
using Rotations
|
||||||
|
|
||||||
# using Images
|
using Images
|
||||||
|
using GeometryBasics
|
||||||
using Colors
|
using Colors
|
||||||
using GLMakie
|
using GLMakie
|
||||||
|
|
||||||
|
@ -10,19 +11,30 @@ using GLMakie
|
||||||
include("SimpleRayTracer.jl")
|
include("SimpleRayTracer.jl")
|
||||||
|
|
||||||
world = SimpleRayTracer.World(RGB(.1,.5,.5))
|
world = SimpleRayTracer.World(RGB(.1,.5,.5))
|
||||||
push!(world, SimpleRayTracer.Sphere(Vec3(-2.5, 0.0, 0.0), 2.0, RGB(1, 0, 0)))
|
push!(world, SimpleRayTracer.Sphere(Vec3(-4.0, 0.0, 0.0), 2.0, RGB(1, 0, 0)))
|
||||||
push!(world, SimpleRayTracer.Sphere(Vec3( 2.5, 0.0, 0.0), 2.0, RGB(0, 1, 0)))
|
push!(world, SimpleRayTracer.Sphere(Vec3( 4.0, 0.0, 0.0), 2.0, RGB(0, 1, 0)))
|
||||||
push!(world, SimpleRayTracer.Sphere(Vec3( 0.0, 0.0, 2.5), 2.0, RGB(0, 0, 1)))
|
push!(world, SimpleRayTracer.Sphere(Vec3( 0.0, 0.0, 3.0), 2.0, RGB(0, 0, 1)))
|
||||||
|
|
||||||
camera = SimpleRayTracer.OrthogonalCamera(
|
camera = SimpleRayTracer.OrthogonalCamera(
|
||||||
Vec3(0.0, 0.0, -5.0),
|
Vec3(0.0, 0.0, -5.0),
|
||||||
|
(20.0, 10.0),
|
||||||
RotXYZ(0.0, 0.0, 0.0),
|
RotXYZ(0.0, 0.0, 0.0),
|
||||||
(5.0, 5.0)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
resolution = (256, 256)
|
camera = SimpleRayTracer.PinHoleCamera(
|
||||||
img = [SimpleRayTracer.trace_ray(world, ray).color for ray in SimpleRayTracer.get_rays(camera, resolution)];
|
Vec3(0.0, 1.0, -8.0),
|
||||||
|
Vec3(0.0, 0.0, 0.0),
|
||||||
|
Vec3(0.0, 1.0, 0.0),
|
||||||
|
1.0,
|
||||||
|
(4.0, 2.0),
|
||||||
|
)
|
||||||
|
|
||||||
|
resolution = (512, 256);
|
||||||
|
img = SimpleRayTracer.render(world, camera, resolution);
|
||||||
|
# img |> size
|
||||||
fig = Figure(size=resolution)
|
fig = Figure(size=resolution)
|
||||||
ax = Axis(fig[1,1], aspect=1)
|
ax = GLMakie.Axis(fig[1,1], aspect=2)
|
||||||
image!(ax, img)
|
image!(ax, img |> rotr90)
|
||||||
|
|
||||||
|
|
||||||
|
Images.save("test.png", img)
|
||||||
|
|
Loading…
Reference in a new issue