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
19#include <libsbx/models/vertex_stream.hpp>
20
21namespace sbx::models {
22
23enum class alpha_mode : std::uint8_t {
24 opaque,
25 mask,
26 blend
27}; // enum class alpha_mode
28
29enum class material_feature : std::uint8_t {
30 none = 0,
31 cast_shadow = utility::bit_v<0>,
32 receive_shadow = utility::bit_v<1>,
33 invert_backface_normals = utility::bit_v<2>
34}; // enum class material_feature
35
36inline constexpr auto operator|(const material_feature lhs, const material_feature rhs) -> material_feature {
37 return static_cast<material_feature>(static_cast<std::uint8_t>(lhs) | static_cast<std::uint8_t>(rhs));
38}
39
40struct alignas(16) material_data {
41 std::uint32_t albedo_image_index;
42 std::uint32_t albedo_sampler_index;
43 std::uint32_t normal_image_index;
44 std::uint32_t normal_sampler_index;
45
46 std::uint32_t metallic_roughness_image_index;
47 std::uint32_t metallic_roughness_sampler_index;
48 std::uint32_t occlusion_image_index;
49 std::uint32_t occlusion_sampler_index;
50
51 std::uint32_t emissive_image_index;
52 std::uint32_t emissive_sampler_index;
53 std::uint32_t height_image_index;
54 std::uint32_t height_sampler_index;
55
56 std::float_t height_scale;
57 std::float_t height_offset;
58 std::float_t parallax_min_layers;
59 std::float_t parallax_max_layers;
60
61 std::float_t emissive_strength;
62 std::float_t normal_scale;
63 std::float_t metallic_factor;
64 std::float_t roughness_factor;
65
66 std::float_t occlusion_strength;
67 std::float_t specular_factor;
68 std::float_t alpha_cutoff;
69 std::uint32_t flags;
70
71 math::vector2 uv_offset;
72 math::vector2 uv_scale;
73
74 math::color base_color;
75
76 math::vector4 emissive_factor;
77
78 std::float_t sway_speed_strength;
79 std::float_t scrumble_speed_strength;
80 std::float_t falloff_exponents;
81 std::uint32_t _pad0;
82}; // struct material_data
83
84static_assert(sizeof(material_data) <= 256u);
85static_assert(alignof(material_data) == 16u);
86
87struct alignas(std::uint32_t) material_key {
88 std::uint32_t surface_shader_hash;
89 std::uint16_t alpha : 2;
90 std::uint16_t is_double_sided : 1;
91 std::uint16_t stream_mask : 5;
92 std::uint16_t feature_mask : 8;
93
94 material_key() {
95 std::memset(this, 0, sizeof(material_key));
96 }
97
98}; // struct material_key
99
100static_assert(sizeof(material_key) == 8u);
101static_assert(alignof(material_key) == alignof(std::uint32_t));
102
103inline auto operator==(const material_key& lhs, const material_key& rhs) -> bool {
104 return std::memcmp(&lhs, &rhs, sizeof(material_key)) == 0;
105}
106
108 auto operator()(const material_key& key) const noexcept -> std::size_t {
109 return utility::djb2_hash{}({reinterpret_cast<const std::uint8_t*>(&key), sizeof(material_key)});
110 }
111}; // struct material_key_hash
112
115
116 graphics::address_mode address_mode_u{graphics::address_mode::repeat};
117 graphics::address_mode address_mode_v{graphics::address_mode::repeat};
118
119 graphics::filter mag_filter{graphics::filter::linear};
120 graphics::filter min_filter{graphics::filter::linear};
121 std::float_t anisotropy{1.0f};
122}; // struct texture_slot
123
125 auto operator()(const texture_slot& texture_slot) const noexcept -> std::size_t;
126}; // struct texture_slot_hash
127
128struct material {
129
130 math::color base_color{math::color::white()};
131
132 std::float_t metallic_factor{1.0f};
133 std::float_t roughness_factor{1.0f};
134 std::float_t occlusion_strength{1.0f};
135 std::float_t specular_factor{1.0f};
136
137 math::vector4 emissive_factor{0, 0, 0, 1};
138 std::float_t emissive_strength{1.0f};
139
140 alpha_mode alpha{alpha_mode::opaque};
141 std::float_t alpha_cutoff{0.9f};
142 bool is_double_sided{false};
143
144 texture_slot albedo{};
145 texture_slot normal{};
146 texture_slot metallic_roughness{};
147 texture_slot occlusion{};
148 texture_slot emissive{};
149 texture_slot height{};
150
151 std::float_t normal_scale{1.0f};
152
153 std::float_t height_offset{0.0f};
154 std::float_t height_scale{0.05f};
155
156 std::float_t parallax_min_layers{8.0f};
157 std::float_t parallax_max_layers{32.0f};
158
159 std::float_t sway_speed{0.0f};
160 std::float_t sway_strength{0.0f};
161 std::float_t sway_falloff_exponent{3.0f};
162
163 std::float_t scrumble_speed{0.0f};
164 std::float_t scrumble_strength{0.0f};
165 std::float_t scrumble_falloff_exponent{2.0f};
166
167 math::vector2 uv_scale{1.0f, 1.0f};
168 math::vector2 uv_offset{0.0f, 0.0f};
169
170 utility::bit_field<material_feature> features{material_feature::cast_shadow | material_feature::receive_shadow | material_feature::invert_backface_normals};
171
172 std::filesystem::path surface_shader{};
173 utility::bit_field<vertex_stream> required_streams{};
174
175 operator material_key() const {
176 auto key = material_key{};
177
178 key.alpha = static_cast<std::uint64_t>(alpha);
179 key.is_double_sided = is_double_sided;
180 key.stream_mask = required_streams.underlying();
181
182 auto shader_path = surface_shader.generic_string();
183 key.surface_shader_hash = utility::crc32(std::span{reinterpret_cast<const std::uint8_t*>(shader_path.data()), shader_path.size()});
184
185 return key;
186 }
187
188}; // struct material
189
190} // namespace sbx::models
191
192template<>
193struct std::hash<sbx::models::material_key> {
194 auto operator()(const sbx::models::material_key& key) const noexcept -> std::size_t {
195 return sbx::models::material_key_hash{}(key);
196 }
197}; // struct std::hash
198
199#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:43
RGBA color representation and utilities.
Definition: material.hpp:40
Definition: material.hpp:107
Definition: material.hpp:87
Definition: material.hpp:128
Definition: material.hpp:124
Definition: material.hpp:113
Definition: hash.hpp:155