sandbox
Loading...
Searching...
No Matches
material.hpp
1// SPDX-License-Identifier: MIT
2#ifndef LIBSBX_MODELS_MATERIAL_HPP_
3#define LIBSBX_MODELS_MATERIAL_HPP_
4
5#include <cinttypes>
6#include <cmath>
7
9
10#include <libsbx/math/uuid.hpp>
11#include <libsbx/math/vector3.hpp>
12#include <libsbx/math/matrix4x4.hpp>
13#include <libsbx/math/color.hpp>
14
15#include <libsbx/graphics/images/image2d.hpp>
16
17#include <libsbx/scenes/components/static_mesh.hpp>
18
19namespace sbx::models {
20
21enum class alpha_mode : std::uint8_t {
22 opaque,
23 mask,
24 blend
25}; // enum class alpha_mode
26
27enum class material_feature : std::uint8_t {
28 none = 0,
29 emission = utility::bit_v<0>,
30 normal_map = utility::bit_v<1>,
31 occlusion = utility::bit_v<2>,
32 height = utility::bit_v<3>,
33 clearcoat = utility::bit_v<4>,
34 anisotropy = utility::bit_v<5>,
35 cast_shadow = utility::bit_v<6>,
36 receive_shadow = utility::bit_v<7>
37}; // struct material_feature
38
39inline constexpr auto operator|(const material_feature lhs, const material_feature rhs) -> material_feature {
40 return static_cast<material_feature>(static_cast<std::uint8_t>(lhs) | static_cast<std::uint8_t>(rhs));
41}
42
43struct alignas(16) material_data {
44 std::uint32_t albedo_image_index;
45 std::uint32_t albedo_sampler_index;
46 std::uint32_t normal_image_index;
47 std::uint32_t normal_sampler_index;
48
49 std::uint32_t metallic_roughness_image_index;
50 std::uint32_t metallic_roughness_sampler_index;
51 std::uint32_t occlusion_image_index;
52 std::uint32_t occlusion_sampler_index;
53
54 std::uint32_t emissive_image_index;
55 std::uint32_t emissive_sampler_index;
56 std::uint32_t height_image_index;
57 std::uint32_t height_sampler_index;
58
59 std::float_t height_scale;
60 std::float_t height_offset;
61 std::float_t parallax_min_layers;
62 std::float_t parallax_max_layers;
63
64 std::float_t emissive_strength;
65 std::float_t normal_scale;
66 std::float_t metallic_factor;
67 std::float_t roughness_factor;
68
69 std::float_t occlusion_strength;
70 std::float_t alpha_cutoff;
71 std::uint32_t flags;
72 std::uint32_t _pad0;
73
74 math::vector2 uv_offset;
75 math::vector2 uv_scale;
76
77 math::color base_color;
78
79 math::vector4 emissive_factor;
80}; // struct material_data
81
82static_assert(sizeof(material_data) <= 256u);
83static_assert(alignof(material_data) == 16u);
84
86 std::uint16_t alpha : 2;
87 std::uint16_t is_double_sided : 1;
88 std::uint16_t _pad0 : 5;
89 std::uint16_t feature_mask : 8;
90
91 material_key() {
92 std::memset(this, 0, sizeof(material_key));
93 }
94
95}; // struct material_key
96
97static_assert(sizeof(material_key) == sizeof(std::uint16_t));
98static_assert(alignof(material_key) == alignof(std::uint16_t));
99
100inline auto operator==(const material_key& lhs, const material_key& rhs) -> bool {
101 return std::memcmp(&lhs, &rhs, sizeof(material_key)) == 0;
102}
103
105 auto operator()(const material_key& key) const noexcept -> std::size_t {
106 return utility::djb2_hash{}({reinterpret_cast<const std::uint8_t*>(&key), sizeof(material_key)});
107 }
108}; // struct material_key_hash
109
112
113 graphics::address_mode address_mode_u{graphics::address_mode::repeat};
114 graphics::address_mode address_mode_v{graphics::address_mode::repeat};
115
116 graphics::filter mag_filter{graphics::filter::linear};
117 graphics::filter min_filter{graphics::filter::linear};
118 std::float_t anisotropy{1.0f};
119}; // struct texture_slot
120
122 auto operator()(const texture_slot& texture_slot) const noexcept -> std::size_t;
123}; // struct texture_slot_hash
124
125struct material {
126
127 math::color base_color{math::color::white()};
128
129 std::float_t metallic_factor{1.0f};
130 std::float_t roughness_factor{1.0f};
131 std::float_t occlusion_strength{1.0f};
132
133 math::vector4 emissive_factor{0, 0, 0, 1};
134 std::float_t emissive_strength{1.0f};
135
136 std::float_t alpha_cutoff{0.9f};
137
138 texture_slot albedo{};
139 texture_slot normal{};
140 texture_slot metallic_roughness{};
141 texture_slot occlusion{};
142 texture_slot emissive{};
143 texture_slot height{};
144
145 std::float_t normal_scale{1.0f};
146
147 std::float_t height_offset{0.0f};
148 std::float_t height_scale{0.05f};
149
150 std::float_t parallax_min_layers{8.0f};
151 std::float_t parallax_max_layers{32.0f};
152
153 math::vector2 uv_scale{1.0f, 1.0f};
154 math::vector2 uv_offset{0.0f, 0.0f};
155
156 alpha_mode alpha{alpha_mode::opaque};
157 bool is_double_sided{false};
158
159 utility::bit_field<material_feature> features{material_feature::cast_shadow | material_feature::receive_shadow};
160
161 operator material_key() const {
162 auto key = material_key{};
163
164 key.alpha = static_cast<std::uint64_t>(alpha);
165 key.is_double_sided = is_double_sided;
166 // key.feature_mask = features.underlying();
167
168 return key;
169 }
170
171}; // struct material
172
173auto load_materials(const std::filesystem::path& path) -> std::vector<scenes::static_mesh::submesh>;
174
175} // namespace sbx::models
176
177#endif // LIBSBX_MODELS_MATERIAL_HPP_
Definition: resource_storage.hpp:18
A vector in two-dimensional space.
Definition: vector2.hpp:28
Definition: vector4.hpp:24
RGBA color value type.
Definition: color.hpp:48
static auto white() noexcept -> color
Returns a white color.
Definition: color.cpp:49
Definition: enum.hpp:88
RGBA color representation and utilities.
Definition: material.hpp:43
Definition: material.hpp:104
Definition: material.hpp:85
Definition: material.hpp:125
Definition: material.hpp:121
Definition: material.hpp:110
Definition: hash.hpp:155