Skip to content

Commit 334c03d

Browse files
committed
fix camera, break examples, add TraceMakie prototype, add light types
1 parent 8f7032c commit 334c03d

File tree

16 files changed

+532
-169
lines changed

16 files changed

+532
-169
lines changed

docs/code/TraceMakie.jl

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
using Makie, Trace, ImageShow, Colors, FileIO, LinearAlgebra, GeometryBasics
2+
3+
function to_spectrum(data::Colorant)
4+
rgb = RGBf(data)
5+
return Trace.RGBSpectrum(rgb.r, rgb.g, rgb.b)
6+
end
7+
8+
function to_spectrum(data::AbstractMatrix{<:Colorant})
9+
colors = convert(AbstractMatrix{RGBf}, data)
10+
return collect(reinterpret(Trace.RGBSpectrum, colors))
11+
end
12+
13+
function extract_material(plot::Plot, tex::Union{Trace.Texture, Nothing})
14+
if haskey(plot, :material) && !isnothing(to_value(plot.material))
15+
if to_value(plot.material) isa Trace.Material
16+
return to_value(plot.material)
17+
end
18+
elseif tex isa Nothing
19+
error("Neither color nor material are defined for plot: $plot")
20+
else
21+
return Trace.MatteMaterial(tex, Trace.ConstantTexture(0.0f0))
22+
end
23+
end
24+
25+
function extract_material(plot::Plot, color_obs::Observable)
26+
color = to_value(color_obs)
27+
tex = nothing
28+
if color isa AbstractMatrix{<:Number}
29+
calc_color = to_value(plot.calculated_colors)
30+
tex = Trace.Texture(to_spectrum(to_color(calc_color)))
31+
onany(plot, color_obs, plot.colormap, plot.colorrange) do color, cmap, crange
32+
tex.data = to_spectrum(to_color(calc_color))
33+
return
34+
end
35+
elseif color isa AbstractMatrix{<:Colorant}
36+
tex = Trace.Texture(to_spectrum(color))
37+
onany(plot, color_obs) do color
38+
tex.data = to_spectrum(color)
39+
return
40+
end
41+
elseif color isa Colorant || color isa Union{String,Symbol}
42+
tex = Trace.ConstantTexture(to_spectrum(color))
43+
elseif color isa Nothing
44+
# ignore!
45+
nothing
46+
else
47+
error("Unsupported color type for RadeonProRender backend: $(typeof(color))")
48+
end
49+
50+
return extract_material(plot, tex)
51+
end
52+
53+
function to_trace_primitive(plot::Makie.Mesh)
54+
# Potentially per instance attributes
55+
triangles = Trace.create_triangle_mesh(
56+
plot.mesh[], Trace.ShapeCore(Trace.translate(Vec3f(0)), false),
57+
)
58+
material = extract_material(plot, plot.color)
59+
return [Trace.GeometricPrimitive(t, material) for t in triangles]
60+
end
61+
62+
function to_trace_primitive(plot::Makie.Surface)
63+
!plot.visible[] && return nothing
64+
x = plot[1]
65+
y = plot[2]
66+
z = plot[3]
67+
68+
function grid(x, y, z, trans)
69+
space = to_value(get(plot, :space, :data))
70+
g = map(CartesianIndices(z)) do i
71+
p = Point3f(Makie.get_dim(x, i, 1, size(z)), Makie.get_dim(y, i, 2, size(z)), z[i])
72+
return Makie.apply_transform(trans, p, space)
73+
end
74+
return vec(g)
75+
end
76+
77+
positions = lift(grid, x, y, z, Makie.transform_func_obs(plot))
78+
normals = Makie.surface_normals(x[], y[], z[])
79+
r = Tesselation(Rect2f((0, 0), (1, 1)), size(z[]))
80+
# decomposing a rectangle into uv and triangles is what we need to map the z coordinates on
81+
# since the xyz data assumes the coordinates to have the same neighouring relations
82+
# like a grid
83+
faces = decompose(GLTriangleFace, r)
84+
uv = decompose_uv(r)
85+
# with this we can beuild a mesh
86+
mesh = normal_mesh(GeometryBasics.Mesh(meta(vec(positions[]), uv=uv), faces))
87+
88+
triangles = Trace.create_triangle_mesh(
89+
mesh, Trace.ShapeCore(Trace.translate(Vec3f(0)), false),
90+
)
91+
material = extract_material(plot, plot.z)
92+
return [Trace.GeometricPrimitive(t, material) for t in triangles]
93+
end
94+
function to_trace_primitive(plot::Makie.Plot)
95+
return []
96+
end
97+
98+
function to_trace_light(light::Makie.AmbientLight)
99+
return Trace.AmbientLight(
100+
to_spectrum(light.color[]),
101+
)
102+
end
103+
function to_trace_light(light::Makie.PointLight)
104+
return Trace.PointLight(
105+
Trace.translate(light.position[]), to_spectrum(light.color[]),
106+
)
107+
end
108+
109+
function to_trace_light(light::Makie.PointLight)
110+
return Trace.PointLight(
111+
Trace.translate(light.position[]), to_spectrum(light.color[]),
112+
)
113+
end
114+
115+
function to_trace_light(light::Makie.PointLight)
116+
return Trace.PointLight(
117+
Trace.translate(light.position[]), to_spectrum(light.color[]),
118+
)
119+
end
120+
121+
122+
123+
function to_trace_light(light)
124+
return nothing
125+
end
126+
127+
128+
function to_trace_camera(scene::Makie.Scene, film)
129+
cc = scene.camera_controls
130+
fov = cc.fov[]
131+
view = Trace.look_at(
132+
Point3f(cc.eyeposition[]), Point3f(cc.lookat[]), Vec3f(cc.upvector[]),
133+
)
134+
return Trace.PerspectiveCamera(
135+
view, Trace.Bounds2(Point2f(-1.0f0), Point2f(1.0f0)),
136+
0.0f0, 1.0f0, 0.0f0, 1.0f6, Float32(fov),
137+
film
138+
)
139+
end
140+
141+
function render_scene(mscene::Makie.Scene)
142+
# Only set background image if it isn't set by env light, since
143+
# background image takes precedence
144+
resolution = Point2f(size(mscene))
145+
f = Trace.LanczosSincFilter(Point2f(1.0f0), 3.0f0)
146+
film = Trace.Film(
147+
resolution,
148+
Trace.Bounds2(Point2f(0.0f0), Point2f(1.0f0)),
149+
f, 1.0f0, 1.0f0,
150+
"trace-test.png",
151+
)
152+
primitives = []
153+
for plot in mscene.plots
154+
prim = to_trace_primitive(plot)
155+
append!(primitives, prim)
156+
end
157+
camera = to_trace_camera(mscene, film)
158+
lights = []
159+
for light in mscene.lights
160+
l = to_trace_light(light)
161+
isnothing(l) || push!(lights, l)
162+
end
163+
if isempty(lights)
164+
error("Must have at least one light")
165+
end
166+
bvh = Trace.BVHAccel(map(identity, primitives), 1)
167+
integrator = Trace.WhittedIntegrator(camera, Trace.UniformSampler(8), 5)
168+
scene = Trace.Scene([lights...], bvh)
169+
integrator(scene)
170+
return reverse(film.framebuffer, dims=1)
171+
end
172+
173+
catmesh = load(Makie.assetpath("cat.obj"))
174+
begin
175+
glass = Trace.GlassMaterial(
176+
Trace.ConstantTexture(Trace.RGBSpectrum(1.0f0)),
177+
Trace.ConstantTexture(Trace.RGBSpectrum(1.0f0)),
178+
Trace.ConstantTexture(0.0f0),
179+
Trace.ConstantTexture(0.0f0),
180+
Trace.ConstantTexture(1.25f0),
181+
true,
182+
)
183+
mirror = Trace.MirrorMaterial(Trace.ConstantTexture(Trace.RGBSpectrum(1.0f0)))
184+
plastic = Trace.PlasticMaterial(
185+
Trace.ConstantTexture(Trace.RGBSpectrum(0.6399999857f0, 0.6399999857f0, 0.6399999857f0)),
186+
Trace.ConstantTexture(Trace.RGBSpectrum(0.1000000015f0, 0.1000000015f0, 0.1000000015f0)),
187+
Trace.ConstantTexture(0.010408001f0),
188+
true,
189+
)
190+
scene = Scene(size=(1024, 1024); lights=[AmbientLight(RGBf(0.5, 0.5, 0.5)), PointLight(Vec3f(0, 1, 0.5), RGBf(1, 1, 1))])
191+
cam3d!(scene)
192+
mesh!(scene, catmesh, color=load(Makie.assetpath("diffusemap.png")), material=plastic)
193+
mesh!(scene, Sphere(Point3f(0, 0, 2), 1f0), material=glass)
194+
center!(scene)
195+
render_scene(scene)
196+
end
197+
198+
199+
begin
200+
scene = Scene(size=(1024, 1024); lights=[
201+
AmbientLight(RGBf(0.4, 0.4, 0.4)), PointLight(Vec3f(4, 4, 10), RGBf(500, 500, 500))])
202+
cam3d!(scene)
203+
xs = LinRange(0, 10, 100)
204+
ys = LinRange(0, 15, 100)
205+
zs = [cos(x) * sin(y) for x in xs, y in ys]
206+
surface!(scene, xs, ys, zs)
207+
center!(scene)
208+
render_scene(scene)
209+
end

docs/code/caustic_glass.jl

Lines changed: 84 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,99 @@
11
using GeometryBasics
22
using LinearAlgebra
33
using Trace, FileIO, MeshIO
4+
begin
5+
glass = Trace.GlassMaterial(
6+
Trace.ConstantTexture(Trace.RGBSpectrum(1f0)),
7+
Trace.ConstantTexture(Trace.RGBSpectrum(1f0)),
8+
Trace.ConstantTexture(0f0),
9+
Trace.ConstantTexture(0f0),
10+
Trace.ConstantTexture(1.25f0),
11+
true,
12+
)
13+
plastic = Trace.PlasticMaterial(
14+
Trace.ConstantTexture(Trace.RGBSpectrum(0.6399999857f0, 0.6399999857f0, 0.6399999857f0)),
15+
Trace.ConstantTexture(Trace.RGBSpectrum(0.1000000015f0, 0.1000000015f0, 0.1000000015f0)),
16+
Trace.ConstantTexture(0.010408001f0),
17+
true,
18+
)
419

5-
glass = Trace.GlassMaterial(
6-
Trace.ConstantTexture(Trace.RGBSpectrum(1f0)),
7-
Trace.ConstantTexture(Trace.RGBSpectrum(1f0)),
8-
Trace.ConstantTexture(0f0),
9-
Trace.ConstantTexture(0f0),
10-
Trace.ConstantTexture(1.25f0),
11-
true,
12-
)
13-
plastic = Trace.PlasticMaterial(
14-
Trace.ConstantTexture(Trace.RGBSpectrum(0.6399999857f0, 0.6399999857f0, 0.6399999857f0)),
15-
Trace.ConstantTexture(Trace.RGBSpectrum(0.1000000015f0, 0.1000000015f0, 0.1000000015f0)),
16-
Trace.ConstantTexture(0.010408001f0),
17-
true,
18-
)
20+
model = load(joinpath(@__DIR__, "..", "src", "assets", "models", "caustic-glass.ply"))
1921

20-
model = load(joinpath(@__DIR__, "..", "src", "assets", "models", "caustic-glass.ply"))
2122

23+
triangles = Trace.create_triangle_mesh(
24+
model, Trace.ShapeCore(Trace.translate(Vec3f(5, -1.49, -100)), false),
25+
)
2226

23-
triangles = Trace.create_triangle_mesh(
24-
model, Trace.ShapeCore(Trace.translate(Vec3f(5, -1.49, -100)), false),
25-
)
27+
floor_triangles = Trace.create_triangle_mesh(
28+
Trace.ShapeCore(Trace.translate(Vec3f(-10, 0, -87)), false),
29+
UInt32[1, 2, 3, 1, 4, 3],
30+
[
31+
Point3f(0, 0, 0), Point3f(0, 0, -30),
32+
Point3f(30, 0, -30), Point3f(30, 0, 0),
33+
],
34+
[
35+
Trace.Normal3f(0, 1, 0), Trace.Normal3f(0, 1, 0),
36+
Trace.Normal3f(0, 1, 0), Trace.Normal3f(0, 1, 0),
37+
],
38+
)
2639

27-
floor_triangles = Trace.create_triangle_mesh(
28-
Trace.ShapeCore(Trace.translate(Vec3f(-10, 0, -87)), false),
29-
UInt32[1, 2, 3, 1, 4, 3],
30-
[
31-
Point3f(0, 0, 0), Point3f(0, 0, -30),
32-
Point3f(30, 0, -30), Point3f(30, 0, 0),
33-
],
34-
[
35-
Trace.Normal3f(0, 1, 0), Trace.Normal3f(0, 1, 0),
36-
Trace.Normal3f(0, 1, 0), Trace.Normal3f(0, 1, 0),
37-
],
38-
)
40+
primitives = Trace.GeometricPrimitive[]
41+
for t in triangles
42+
push!(primitives, Trace.GeometricPrimitive(t, glass))
43+
end
44+
for t in floor_triangles
45+
push!(primitives, Trace.GeometricPrimitive(t, plastic))
46+
end
3947

40-
primitives = Trace.GeometricPrimitive[]
41-
for t in triangles
42-
push!(primitives, Trace.GeometricPrimitive(t, glass))
43-
end
44-
for t in floor_triangles
45-
push!(primitives, Trace.GeometricPrimitive(t, plastic))
46-
end
47-
48-
bvh = Trace.BVHAccel(map(identity, primitives), 1);
48+
bvh = Trace.BVHAccel(map(identity, primitives), 1);
4949

50-
from, to = Point3f(0, 2, 0), Point3f(-5, 0, 5)
51-
cone_angle, cone_δ_angle = 30f0, 10f0
52-
dir = normalize(Vec3f(to - from))
53-
dir, du, dv = Trace.coordinate_system(dir)
50+
from, to = Point3f(0, 2, 0), Point3f(-5, 0, 5)
51+
cone_angle, cone_δ_angle = 30f0, 10f0
52+
dir = normalize(Vec3f(to - from))
53+
dir, du, dv = Trace.coordinate_system(dir)
5454

55-
dir_to_z = Trace.Transformation(transpose(Mat4f(
56-
du[1], du[2], du[3], 0f0,
57-
dv[1], dv[2], dv[3], 0f0,
58-
dir[1], dir[2], dir[3], 0f0,
59-
0f0, 0f0, 0f0, 1f0,
60-
)))
61-
light_to_world = (
62-
Trace.translate(Vec3f(4.5, 0, -101))
63-
* Trace.translate(Vec3f(from))
64-
* inv(dir_to_z)
65-
)
55+
dir_to_z = Trace.Transformation(transpose(Mat4f(
56+
du[1], du[2], du[3], 0f0,
57+
dv[1], dv[2], dv[3], 0f0,
58+
dir[1], dir[2], dir[3], 0f0,
59+
0f0, 0f0, 0f0, 1f0,
60+
)))
61+
light_to_world = (
62+
Trace.translate(Vec3f(4.5, 0, -101))
63+
* Trace.translate(Vec3f(from))
64+
* inv(dir_to_z)
65+
)
6666

67-
lights = [
68-
Trace.SpotLight(
69-
light_to_world, Trace.RGBSpectrum(60f0),
70-
cone_angle, cone_angle - cone_δ_angle,
71-
),
72-
]
67+
lights = [
68+
Trace.SpotLight(
69+
light_to_world, Trace.RGBSpectrum(100f0),
70+
cone_angle, cone_angle - cone_δ_angle,
71+
),
72+
Trace.AmbientLight(Trace.RGBSpectrum(0.5f0)),
73+
]
7374

74-
scene = Trace.Scene(lights, bvh)
75+
scene = Trace.Scene(lights, bvh)
7576

76-
n_samples = 8
77-
ray_depth = 5
77+
n_samples = 8
78+
ray_depth = 5
7879

79-
look_point = Point3f(-3, 0, -91)
80-
screen = Trace.Bounds2(Point2f(-1f0), Point2f(1f0))
81-
filter = Trace.LanczosSincFilter(Point2f(1f0), 3f0)
82-
83-
resolution = Point2f(1024)
84-
ir = Int64.(resolution)
85-
film = Trace.Film(
86-
resolution, Trace.Bounds2(Point2f(0), Point2f(1)),
87-
filter, 1f0, 1f0,
88-
"./scenes/caustics-sppm-$(ir[1])x$(ir[2]).png",
89-
)
90-
camera = Trace.PerspectiveCamera(
91-
Trace.look_at(Point3f(0, 150, 150), look_point, Vec3f(0, 1, 0)),
92-
screen, 0f0, 1f0, 0f0, 1f6, 90f0, film,
93-
)
94-
95-
integrator = Trace.SPPMIntegrator(camera, 0.075f0, ray_depth, 1)
96-
@profview_allocs integrator(scene)
97-
@time integrator(scene)
80+
look_point = Point3f(-3, 0, 0)
81+
screen = Trace.Bounds2(Point2f(-1f0), Point2f(1f0))
82+
filter = Trace.LanczosSincFilter(Point2f(1f0), 3f0)
83+
resolution = Point2f(1024)
84+
ir = Int64.(resolution)
85+
film = Trace.Film(
86+
resolution, Trace.Bounds2(Point2f(0), Point2f(1)),
87+
filter, 1f0, 1f0,
88+
"./scenes/caustics-sppm-$(ir[1])x$(ir[2]).png",
89+
)
90+
camera = Trace.PerspectiveCamera(
91+
Trace.look_at(Point3f(0, 4, 4), look_point, Vec3f(0, 1, 0)),
92+
screen, 0f0, 1f0, 0f0, 1f6, 90f0, film,
93+
)
94+
integrator = Trace.SPPMIntegrator(camera, 0.075f0, ray_depth, 1)
95+
@time integrator(scene)
96+
reverse(film.framebuffer, dims=1)
97+
end
98+
mean(decompose(Point, Rect3f(model)))
99+
Rect3f(model)

0 commit comments

Comments
 (0)