Skip to content

Commit 71764e6

Browse files
authored
Incorporate emissive material parameters (#64)
- Material: emissive texture, emissive factor. - Camera: exposure. - editor: inspect new params; WIP: drag-and-drop.
1 parent 154c00f commit 71764e6

File tree

16 files changed

+616
-531
lines changed

16 files changed

+616
-531
lines changed

.clang-format

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ IncludeCategories:
2828
- Regex: '<([A-Za-z0-9\/-_])+>'
2929
Priority: 30
3030
PointerAlignment: Left
31+
QualifierAlignment: Right

lib/engine/include/facade/engine/editor/inspector.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ class SceneInspector : public Inspector {
5454
bool inspect(NotClosed<TreeNode>, UnlitMaterial& out_material) const;
5555
bool inspect(NotClosed<TreeNode> node, LitMaterial& out_material) const;
5656
bool inspect(Id<Material> material_id) const;
57-
bool inspect(Id<Mesh> mesh) const;
57+
bool inspect(Id<Mesh> mesh_id) const;
58+
bool inspect(Id<Camera> camera_id) const;
5859

5960
bool inspect(Id<Node> node_id, Bool& out_unified_scaling) const;
6061

lib/engine/include/facade/engine/scene_renderer.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class SceneRenderer {
2222
Buffer m_view_proj;
2323
Buffer m_dir_lights;
2424
Texture m_white;
25+
Texture m_black;
2526

2627
std::vector<glm::mat4x4> m_instance_mats{};
2728
Scene const* m_scene{};

lib/engine/src/editor/inspector.cpp

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ struct Modified {
1818
}
1919
};
2020

21-
using DragFloatFunc = bool (*)(const char*, float* v, float, float, float, const char*, ImGuiSliderFlags);
21+
using DragFloatFunc = bool (*)(char const*, float* v, float, float, float, char const*, ImGuiSliderFlags);
2222

2323
constexpr DragFloatFunc drag_float_vtable[] = {
2424
nullptr, &ImGui::DragFloat, &ImGui::DragFloat2, &ImGui::DragFloat3, &ImGui::DragFloat4,
@@ -153,14 +153,14 @@ bool Inspector::inspect(Lights& out_lights) const {
153153
bool Inspector::do_inspect(Transform& out_transform, Bool& out_unified_scaling, Bool scaling_toggle) const {
154154
auto ret = Modified{};
155155
auto vec3 = out_transform.position();
156-
if (ret(inspect("Position", vec3))) { out_transform.set_position(vec3); }
156+
if (ret(inspect("Position", vec3, 0.1f))) { out_transform.set_position(vec3); }
157157
auto quat = out_transform.orientation();
158158
if (ret(inspect("Orientation", quat))) { out_transform.set_orientation(quat); }
159159
vec3 = out_transform.scale();
160160
if (out_unified_scaling) {
161-
if (ret(ImGui::DragFloat("Scale", &vec3.x, 0.1f))) { out_transform.set_scale({vec3.x, vec3.x, vec3.x}); }
161+
if (ret(ImGui::DragFloat("Scale", &vec3.x, 0.05f))) { out_transform.set_scale({vec3.x, vec3.x, vec3.x}); }
162162
} else {
163-
if (ret(inspect("Scale", vec3, 0.1f))) { out_transform.set_scale(vec3); }
163+
if (ret(inspect("Scale", vec3, 0.05f))) { out_transform.set_scale(vec3); }
164164
}
165165
if (scaling_toggle) {
166166
ImGui::SameLine();
@@ -182,16 +182,28 @@ bool SceneInspector::inspect(NotClosed<TreeNode>, LitMaterial& out_material) con
182182
ret(ImGui::SliderFloat("Metallic", &out_material.metallic, 0.0f, 1.0f));
183183
ret(ImGui::SliderFloat("Roughness", &out_material.roughness, 0.0f, 1.0f));
184184
ret(inspect_rgb("Albedo", out_material.albedo));
185+
if (out_material.emissive) { ret(inspect_rgb("Emission", out_material.emissive_factor)); }
185186
if (out_material.base_colour || out_material.roughness_metallic) {
186187
auto const ri = ResourceInspector{m_target, m_scene.resources()};
187188
if (out_material.base_colour) {
188189
auto const* tex = m_scene.find(*out_material.base_colour);
189190
ri.display(*tex, *out_material.base_colour, "Base Colour: ");
191+
if (ImGui::BeginDragDropTarget()) {
192+
if (ImGuiPayload const* payload = ImGui::AcceptDragDropPayload("ID_TEXTURE")) {
193+
assert(payload->DataSize == sizeof(std::size_t));
194+
out_material.base_colour = *reinterpret_cast<std::size_t*>(payload->Data);
195+
}
196+
ImGui::EndDragDropTarget();
197+
}
190198
}
191199
if (out_material.roughness_metallic) {
192200
auto const* tex = m_scene.find(*out_material.roughness_metallic);
193201
ri.display(*tex, *out_material.roughness_metallic, "Roughness Metallic: ");
194202
}
203+
if (out_material.emissive) {
204+
auto const* tex = m_scene.find(*out_material.emissive);
205+
ri.display(*tex, *out_material.emissive, "Emissive: ");
206+
}
195207
}
196208
return ret.value;
197209
}
@@ -224,13 +236,24 @@ bool SceneInspector::inspect(Id<Mesh> mesh_id) const {
224236
return ret.value;
225237
}
226238

239+
bool SceneInspector::inspect(Id<Camera> camera_id) const {
240+
auto ret = Modified{};
241+
auto* camera = m_scene.find(camera_id);
242+
if (!camera) { return ret.value; }
243+
if (ImGui::CollapsingHeader(FixedString{"Camera ({})###Camera", camera_id}.c_str())) {
244+
ret(ImGui::DragFloat("Exposure", &camera->exposure, 0.1f, 0.0f, 10.0f));
245+
}
246+
return ret.value;
247+
}
248+
227249
bool SceneInspector::inspect(Id<Node> node_id, Bool& out_unified_scaling) const {
228250
auto ret = Modified{};
229251
auto* node = m_scene.find(node_id);
230252
if (!node) { return false; }
231253
ret(inspect(node->transform, out_unified_scaling));
232254
ret(inspect(node->instances, out_unified_scaling));
233255
if (auto const* mesh_id = node->find<Id<Mesh>>()) { ret(inspect(*mesh_id)); }
256+
if (auto const* camera_id = node->find<Id<Camera>>()) { ret(inspect(*camera_id)); }
234257
return ret.value;
235258
}
236259

@@ -283,13 +306,20 @@ void ResourceInspector::display(Camera const& camera, std::size_t index, std::st
283306
}
284307

285308
void ResourceInspector::display(Texture const& texture, std::size_t index, std::string_view prefix) const {
286-
if (auto tn = editor::TreeNode{FixedString<128>{"{}{} ({})", prefix, texture.name(), index}.c_str()}) {
309+
auto const name = FixedString<128>{"{}{} ({})", prefix, texture.name(), index};
310+
if (auto tn = editor::TreeNode{name.c_str()}) {
287311
auto const view = texture.view();
288312
editor::TreeNode::leaf(FixedString{"Extent: {}x{}", view.extent.width, view.extent.height}.c_str());
289313
editor::TreeNode::leaf(FixedString{"Mip levels: {}", texture.mip_levels()}.c_str());
290314
auto const cs = texture.colour_space() == ColourSpace::eLinear ? "linear" : "sRGB";
291315
editor::TreeNode::leaf(FixedString{"Colour Space: {}", cs}.c_str());
292316
}
317+
318+
if (ImGui::BeginDragDropSource()) {
319+
ImGui::SetDragDropPayload("ID_TEXTURE", &index, sizeof(index));
320+
ImGui::Text("%s", name.c_str());
321+
ImGui::EndDragDropSource();
322+
}
293323
}
294324

295325
void ResourceInspector::display(Material const& material, std::size_t const index, std::string_view prefix) const {

lib/engine/src/scene_renderer.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ struct DirLightSSBO {
4141

4242
SceneRenderer::SceneRenderer(Gfx const& gfx)
4343
: m_gfx(gfx), m_sampler(gfx), m_view_proj(gfx, Buffer::Type::eUniform), m_dir_lights(gfx, Buffer::Type::eStorage),
44-
m_white(gfx, m_sampler.sampler(), Img1x1::make({0xff, 0xff, 0xff, 0xff}).view(), Texture::CreateInfo{.mip_mapped = false}) {}
44+
m_white(gfx, m_sampler.sampler(), Img1x1::make({0xff, 0xff, 0xff, 0xff}).view(), Texture::CreateInfo{.mip_mapped = false}),
45+
m_black(gfx, m_sampler.sampler(), Img1x1::make({0x0, 0x0, 0x0, 0xff}).view(), Texture::CreateInfo{.mip_mapped = false}) {}
4546

4647
void SceneRenderer::render(Scene const& scene, Renderer& renderer, vk::CommandBuffer cb) {
4748
m_scene = &scene;
@@ -57,11 +58,11 @@ void SceneRenderer::write_view(glm::vec2 const extent) {
5758
struct {
5859
glm::mat4x4 mat_v;
5960
glm::mat4x4 mat_p;
60-
glm::vec4 pos_v;
61+
glm::vec4 vpos_exposure;
6162
} vp{
6263
.mat_v = cam.view(cam_node.transform),
6364
.mat_p = cam.projection(extent),
64-
.pos_v = {cam_node.transform.position(), 1.0f},
65+
.vpos_exposure = {cam_node.transform.position(), cam.exposure},
6566
};
6667
m_view_proj.write(&vp, sizeof(vp));
6768
auto dir_lights = FlexArray<DirLightSSBO, 4>{};
@@ -99,7 +100,7 @@ void SceneRenderer::render(Renderer& renderer, vk::CommandBuffer cb, Node const&
99100
pipeline.set_line_width(m_scene->pipeline_state.line_width);
100101

101102
update_view(pipeline);
102-
auto const store = TextureStore{resources.textures, m_white};
103+
auto const store = TextureStore{resources.textures, m_white, m_black};
103104
material.write_sets(pipeline, store);
104105

105106
auto const& static_mesh = resources.static_meshes[primitive.static_mesh];

lib/scene/include/facade/scene/camera.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@ struct Camera {
3535

3636
std::string name{};
3737
std::variant<Perspective, Orthographic> type{Perspective{}};
38+
float exposure{2.0f};
3839
};
3940
} // namespace facade

lib/scene/include/facade/scene/material.hpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,19 @@ struct TextureStore {
2323
/// \brief White texture.
2424
///
2525
Texture const& white;
26+
///
27+
/// \brief Black texture;
28+
///
29+
Texture const& black;
2630

31+
///
32+
/// \brief Obtain a texture corresponding to index if present, else fallback.
33+
///
34+
Texture const& get(std::optional<std::size_t> index, Texture const& fallback) const;
2735
///
2836
/// \brief Obtain a texture corresponding to index if present, else white.
2937
///
30-
Texture const& get(std::optional<std::size_t> index) const;
38+
Texture const& get(std::optional<std::size_t> index) const { return get(index, white); }
3139
};
3240

3341
///
@@ -98,6 +106,10 @@ class LitMaterial : public Material {
98106
///
99107
glm::vec3 albedo{1.0f};
100108
///
109+
/// \brief Emissive factor.
110+
///
111+
glm::vec3 emissive_factor{0.0f};
112+
///
101113
/// \brief Metallic factor.
102114
///
103115
float metallic{0.5f};
@@ -113,6 +125,11 @@ class LitMaterial : public Material {
113125
/// \brief Roughness-metallic texture.
114126
///
115127
std::optional<Id<Texture>> roughness_metallic{};
128+
///
129+
/// \brief Emissive texture.
130+
///
131+
std::optional<Id<Texture>> emissive{};
132+
116133
float alpha_cutoff{};
117134
AlphaMode alpha_mode{AlphaMode::eOpaque};
118135

lib/scene/include/facade/scene/scene.hpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,17 @@ class Scene {
156156
///
157157
Ptr<Texture const> find(Id<Texture> id) const;
158158
///
159-
/// \brief Obtain an immutable pointer to the Mesh corresponding to its Id.
159+
/// \brief Obtain a mutable pointer to the Mesh corresponding to its Id.
160160
/// \param id Id of the Mesh
161161
/// \returns nullptr if id is invalid (out of bounds)
162162
///
163-
Ptr<Mesh const> find(Id<Mesh> id) const;
163+
Ptr<Mesh> find(Id<Mesh> id);
164+
///
165+
/// \brief Obtain a mutable pointer to the Camera corresponding to its Id.
166+
/// \param id Id of the Camera
167+
/// \returns nullptr if id is invalid (out of bounds)
168+
///
169+
Ptr<Camera> find(Id<Camera> id);
164170

165171
///
166172
/// \brief Obtain a mutable view into all the root nodes attached to the active Tree.

lib/scene/src/detail/gltf.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,12 +483,11 @@ struct Data {
483483
auto set_linear = [this](std::size_t index) { storage.textures.at(index).colour_space = ColourSpace::eLinear; };
484484

485485
// Determine whether a texture points to colour data by referring to the material(s) it is used in
486-
// In our case all material textures except pbr.base_colour_texture are linear
486+
// In our case all material textures except pbr.base_colour_texture and emissive_texture are linear
487487
// The GLTF spec mandates image formats for corresponding material textures:
488488
// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#reference-material
489489
for (auto const& m : storage.materials) {
490490
if (m.pbr.metallic_roughness_texture) { set_linear(m.pbr.metallic_roughness_texture->texture); }
491-
if (m.emissive_texture) { set_linear(m.emissive_texture->texture); }
492491
if (m.occlusion_texture) { set_linear(m.occlusion_texture->info.texture); }
493492
if (m.normal_texture) { set_linear(m.normal_texture->info.texture); }
494493
}

lib/scene/src/gltf_loader.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,10 @@ std::unique_ptr<Material> to_material(gltf::Material const& material) {
5858
ret->roughness = material.pbr.roughness_factor;
5959
ret->alpha_mode = material.alpha_mode;
6060
ret->alpha_cutoff = material.alpha_cutoff;
61-
if (material.pbr.base_colour_texture) { ret->base_colour = material.pbr.base_colour_texture->texture; }
62-
if (material.pbr.metallic_roughness_texture) { ret->roughness_metallic = material.pbr.metallic_roughness_texture->texture; }
61+
ret->base_colour = material.pbr.base_colour_texture->texture;
62+
ret->roughness_metallic = material.pbr.metallic_roughness_texture->texture;
63+
ret->emissive = material.emissive_texture->texture;
64+
ret->emissive_factor = material.emissive_factor;
6365
return ret;
6466
}
6567

lib/scene/src/material.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace {
77
struct Mat {
88
glm::vec4 albedo;
99
glm::vec4 m_r_aco_am;
10+
glm::vec4 emissive;
1011
};
1112

1213
// std::bit_cast not available on GCC 10.x
@@ -17,8 +18,8 @@ float bit_cast_f(Material::AlphaMode const mode) {
1718
}
1819
} // namespace
1920

20-
Texture const& TextureStore::get(std::optional<std::size_t> const index) const {
21-
if (!index || *index >= textures.size()) { return white; }
21+
Texture const& TextureStore::get(std::optional<std::size_t> const index, Texture const& fallback) const {
22+
if (!index || *index >= textures.size()) { return fallback; }
2223
return textures[*index];
2324
}
2425

@@ -32,6 +33,7 @@ void UnlitMaterial::write_sets(Pipeline& pipeline, TextureStore const& store) co
3233
auto const mat = Mat{
3334
.albedo = to_linear(tint),
3435
.m_r_aco_am = {},
36+
.emissive = {},
3537
};
3638
set2.write(0, mat);
3739
pipeline.bind(set1);
@@ -42,10 +44,12 @@ void LitMaterial::write_sets(Pipeline& pipeline, TextureStore const& store) cons
4244
auto& set1 = pipeline.next_set(1);
4345
set1.update(0, store.get(base_colour).descriptor_image());
4446
set1.update(1, store.get(roughness_metallic).descriptor_image());
47+
set1.update(2, store.get(emissive, store.black).descriptor_image());
4548
auto& set2 = pipeline.next_set(2);
4649
auto const mat = Mat{
4750
.albedo = to_linear({albedo, 1.0f}),
4851
.m_r_aco_am = {metallic, roughness, alpha_cutoff, bit_cast_f(alpha_mode)},
52+
.emissive = to_linear({emissive_factor, 1.0f}),
4953
};
5054
set2.write(0, mat);
5155
pipeline.bind(set1);

lib/scene/src/scene.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ Ptr<Node const> Scene::find(Id<Node> id) const { return find_node(m_tree.roots,
143143
Ptr<Material> Scene::find(Id<Material> id) const { return id >= m_storage.materials.size() ? nullptr : m_storage.materials[id].get(); }
144144
Ptr<StaticMesh const> Scene::find(Id<StaticMesh> id) const { return id >= m_storage.static_meshes.size() ? nullptr : &m_storage.static_meshes[id]; }
145145
Ptr<Texture const> Scene::find(Id<Texture> id) const { return id >= m_storage.textures.size() ? nullptr : &m_storage.textures[id]; }
146-
Ptr<Mesh const> Scene::find(Id<Mesh> id) const { return id >= m_storage.meshes.size() ? nullptr : &m_storage.meshes[id]; }
146+
Ptr<Mesh> Scene::find(Id<Mesh> id) { return id >= m_storage.meshes.size() ? nullptr : &m_storage.meshes[id]; }
147+
Ptr<Camera> Scene::find(Id<Camera> id) { return id >= m_storage.cameras.size() ? nullptr : &m_storage.cameras[id]; }
147148

148149
bool Scene::select(Id<Camera> id) {
149150
if (id >= camera_count()) { return false; }

0 commit comments

Comments
 (0)