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
|
||||
|
|
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
|
||||
|
||||
using LinearAlgebra
|
||||
using StaticArrays
|
||||
|
||||
using Images
|
||||
using GeometryBasics
|
||||
using Rotations
|
||||
|
@ -14,20 +16,47 @@ abstract type AbstractObject end
|
|||
|
||||
struct OrthogonalCamera{T<:AbstractFloat} <: AbstractCamera
|
||||
origin::Vec3{T}
|
||||
rotation::RotXYZ{T}
|
||||
size::Tuple{T, T}
|
||||
rotation::RotXYZ{T}
|
||||
# function OrthogonalCamera(o, θ, s)
|
||||
# new(o, RotXYZ(0.0, 0.0, 0.0), s)
|
||||
# end
|
||||
end
|
||||
|
||||
function get_rays(camera::OrthogonalCamera, resolution::Tuple{I, I}) where {I<:Integer}
|
||||
R = camera.rotation
|
||||
X, Y = camera.size
|
||||
rx, ry = resolution
|
||||
origins = [Vec3(x, y, 0.0) + camera.origin for x = LinRange(-X, X, rx), y = LinRange(-Y, Y, ry)]
|
||||
[Ray(o, Vec3(0.0, 0.0, 1.0)) for o in origins]
|
||||
Nx, Ny = resolution
|
||||
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(p, Vec3(0.0, 0.0, 1.0)) for p in screen_pixel_position]
|
||||
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}
|
||||
origin::Vec3{T}
|
||||
direction::Vec3{T}
|
||||
|
@ -85,4 +114,9 @@ function trace_ray(world::World, ray::Ray)::HitInfo
|
|||
return HitInfo(hit, color)
|
||||
end
|
||||
|
||||
function render(world, camera, resolution)
|
||||
rays = get_rays(camera, resolution)
|
||||
[trace_ray(world, ray).color for ray in rays];
|
||||
end
|
||||
|
||||
end
|
||||
|
|
30
rt.jl
30
rt.jl
|
@ -2,7 +2,8 @@ using BenchmarkTools
|
|||
using LinearAlgebra
|
||||
using Rotations
|
||||
|
||||
# using Images
|
||||
using Images
|
||||
using GeometryBasics
|
||||
using Colors
|
||||
using GLMakie
|
||||
|
||||
|
@ -10,19 +11,30 @@ using GLMakie
|
|||
include("SimpleRayTracer.jl")
|
||||
|
||||
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( 2.5, 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(-4.0, 0.0, 0.0), 2.0, RGB(1, 0, 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, 3.0), 2.0, RGB(0, 0, 1)))
|
||||
|
||||
camera = SimpleRayTracer.OrthogonalCamera(
|
||||
Vec3(0.0, 0.0, -5.0),
|
||||
(20.0, 10.0),
|
||||
RotXYZ(0.0, 0.0, 0.0),
|
||||
(5.0, 5.0)
|
||||
)
|
||||
|
||||
resolution = (256, 256)
|
||||
img = [SimpleRayTracer.trace_ray(world, ray).color for ray in SimpleRayTracer.get_rays(camera, resolution)];
|
||||
camera = SimpleRayTracer.PinHoleCamera(
|
||||
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)
|
||||
ax = Axis(fig[1,1], aspect=1)
|
||||
image!(ax, img)
|
||||
ax = GLMakie.Axis(fig[1,1], aspect=2)
|
||||
image!(ax, img |> rotr90)
|
||||
|
||||
|
||||
Images.save("test.png", img)
|
||||
|
|
Loading…
Reference in a new issue