SleakEngine 1.0.0
C++23 multi-backend game engine
Loading...
Searching...
No Matches
Material.hpp
Go to the documentation of this file.
1#ifndef _MATERIAL_HPP_
2#define _MATERIAL_HPP_
3
4#include <Core/Object.hpp>
5#include <Core/OSDef.hpp>
7#include <Memory/RefPtr.hpp>
8#include <Runtime/Texture.hpp>
9#include <Math/Vector.hpp>
10#include <Math/Color.hpp>
11#include <string>
12#include <cstdint>
13
14// Texture binding slots (must match shader register/binding layout)
15#define TEXTURE_SLOT_DIFFUSE 0
16#define TEXTURE_SLOT_NORMAL 1
17#define TEXTURE_SLOT_SPECULAR 2
18#define TEXTURE_SLOT_ROUGHNESS 3
19#define TEXTURE_SLOT_METALLIC 4
20#define TEXTURE_SLOT_AO 5
21#define TEXTURE_SLOT_EMISSIVE 6
22
23namespace Sleak {
24
25 namespace RenderEngine {
26 class Shader;
27 class BufferBase;
28 struct MaterialGPUData;
29 }
30
31 /// Controls how a material handles transparency.
32 /// @ingroup rendering
33 enum class MaterialRenderMode : uint8_t {
34 Opaque = 0, // Fully opaque, no alpha blending
35 Cutout = 1, // Binary alpha test (clip below AlphaCutoff)
36 Transparent = 2 // Alpha blending
37 };
38
39 /// PBR-ish surface properties, textures, and GPU buffer for a drawable; shared across any mesh that references it.
40 ///
41 /// A Material describes how a surface responds to light: a base color,
42 /// metallic, roughness, ambient occlusion, emissive, and opacity, plus
43 /// up to seven texture maps that override those scalars per texel. It
44 /// owns its own GPU constant buffer and rebuilds it when properties
45 /// change.
46 ///
47 /// Materials are meant to be shared. Wrap one in a RefPtr and hand the
48 /// same RefPtr to every MaterialComponent that should use it; changing
49 /// a property updates every object drawn with it. Each texture setter
50 /// comes in two forms, one taking an owned `Texture*` and one taking a
51 /// file path the material loads for you.
52 ///
53 /// SetRenderMode() decides how transparency is handled:
54 /// MaterialRenderMode::Opaque and ::Cutout render in the normal
55 /// (deferred, where the backend supports it) path, while ::Transparent
56 /// forces the material into a forward pass. IsForwardRendered()
57 /// reports which side a material falls on.
58 ///
59 /// @code{.cpp}
60 /// auto* mat = new Sleak::Material();
61 /// mat->SetShader("assets/shaders/default_shader.hlsl");
62 /// mat->SetDiffuseColor((uint8_t)230, (uint8_t)230, (uint8_t)230);
63 /// mat->SetMetallic(0.0f);
64 /// mat->SetRoughness(0.35f);
65 /// mat->SetAO(1.0f);
66 ///
67 /// // Texture maps, loaded by path
68 /// mat->SetDiffuseTexture("assets/textures/crate_albedo.png");
69 /// mat->SetNormalTexture("assets/textures/crate_normal.png");
70 /// mat->SetTiling(2.0f, 2.0f);
71 ///
72 /// // Share one material across many objects
73 /// Sleak::RefPtr<Sleak::Material> shared(mat);
74 /// crate->AddComponent<Sleak::MaterialComponent>(shared);
75 /// barrel->AddComponent<Sleak::MaterialComponent>(shared);
76 ///
77 /// // Alpha-blended glass
78 /// auto* glass = new Sleak::Material();
79 /// glass->SetRenderMode(Sleak::MaterialRenderMode::Transparent);
80 /// glass->SetOpacity(0.35f);
81 /// glass->SetTwoSided(true);
82 /// @endcode
83 ///
84 /// @see MaterialComponent, Texture, MaterialRenderMode, MeshBatch,
85 /// RefPtr
86 /// @ingroup rendering
87 class ENGINE_API Material : public Object {
88 public:
89 Material();
90 ~Material() override;
91
92 void Initialize();
93 void Bind();
94
95 // Shader
96 void SetShader(RenderEngine::Shader* shader);
97 void SetShader(const std::string& shaderPath);
99
100 // Texture slots: each pair of Set overloads takes either an owned Texture* or loads by path
101 void SetDiffuseTexture(Texture* texture);
102 void SetDiffuseTexture(const std::string& path);
103 Texture* GetDiffuseTexture() const;
104 bool HasDiffuseTexture() const;
105
106 void SetNormalTexture(Texture* texture);
107 void SetNormalTexture(const std::string& path);
108 Texture* GetNormalTexture() const;
109 bool HasNormalTexture() const;
110
111 void SetSpecularTexture(Texture* texture);
112 void SetSpecularTexture(const std::string& path);
114 bool HasSpecularTexture() const;
115
116 void SetRoughnessTexture(Texture* texture);
117 void SetRoughnessTexture(const std::string& path);
119 bool HasRoughnessTexture() const;
120
121 void SetMetallicTexture(Texture* texture);
122 void SetMetallicTexture(const std::string& path);
124 bool HasMetallicTexture() const;
125
126 void SetAOTexture(Texture* texture);
127 void SetAOTexture(const std::string& path);
128 Texture* GetAOTexture() const;
129 bool HasAOTexture() const;
130
131 void SetEmissiveTexture(Texture* texture);
132 void SetEmissiveTexture(const std::string& path);
134 bool HasEmissiveTexture() const;
135
136 // Color properties
137 void SetDiffuseColor(Math::Color color);
138 void SetDiffuseColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255);
139 void SetDiffuseColor(float r, float g, float b, float a = 1.0f);
141
142 void SetSpecularColor(Math::Color color);
143 void SetSpecularColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255);
145
146 void SetEmissiveColor(Math::Color color);
147 void SetEmissiveColor(uint8_t r, uint8_t g, uint8_t b);
148 void SetEmissiveColor(float r, float g, float b);
150
151 // Scalar PBR/shading properties
152 void SetShininess(float shininess);
153 float GetShininess() const;
154
155 void SetMetallic(float metallic);
156 float GetMetallic() const;
157
158 void SetRoughness(float roughness);
159 float GetRoughness() const;
160
161 void SetAO(float ao);
162 float GetAO() const;
163
164 void SetNormalIntensity(float intensity);
165 float GetNormalIntensity() const;
166
167 void SetEmissiveIntensity(float intensity);
168 float GetEmissiveIntensity() const;
169
170 void SetOpacity(float opacity);
171 float GetOpacity() const;
172
173 void SetAlphaCutoff(float cutoff);
174 float GetAlphaCutoff() const;
175
176 // UV transform
177 void SetTiling(float x, float y);
178 void SetTiling(Math::Vector2D tiling);
180
181 void SetOffset(float x, float y);
182 void SetOffset(Math::Vector2D offset);
184
185 // Rendering state
188
189 void SetTwoSided(bool twoSided);
190 bool IsTwoSided() const;
191
192 /// True if this material must be rendered in a forward pass
193 /// (transparent, alpha-blended). Opaque and cutout materials return false.
194 bool IsForwardRendered() const;
195
196 /// Bind only textures and material CB (skips shader bind).
197 /// Used by the deferred geometry pass which overrides the shader.
198 void BindTexturesAndCB();
199
200 private:
201 /// Build GPU-aligned data struct from current properties.
202 RenderEngine::MaterialGPUData BuildGPUData() const;
203
204 // Shader
206
207 // GPU constant buffer (slot 1)
209
210 // Texture maps
211 ObjectPtr<Texture> m_diffuseTexture;
212 ObjectPtr<Texture> m_normalTexture;
213 ObjectPtr<Texture> m_specularTexture;
214 ObjectPtr<Texture> m_roughnessTexture;
215 ObjectPtr<Texture> m_metallicTexture;
216 ObjectPtr<Texture> m_aoTexture;
217 ObjectPtr<Texture> m_emissiveTexture;
218
219 // Color properties (stored as 0-255 Color, converted to float for GPU)
220 Math::Color m_diffuseColor {255, 255, 255, 255};
221 Math::Color m_specularColor {255, 255, 255, 255};
222 Math::Color m_emissiveColor {0, 0, 0, 255};
223
224 // Scalar properties
225 float m_shininess = 32.0f;
226 float m_metallic = 0.0f;
227 float m_roughness = 0.5f;
228 float m_ao = 1.0f;
229 float m_normalIntensity = 1.0f;
230 float m_emissiveIntensity = 1.0f;
231 float m_opacity = 1.0f;
232 float m_alphaCutoff = 0.5f;
233
234 // UV transform
235 float m_tilingX = 1.0f;
236 float m_tilingY = 1.0f;
237 float m_offsetX = 0.0f;
238 float m_offsetY = 0.0f;
239
240 // Rendering state
241 MaterialRenderMode m_renderMode = MaterialRenderMode::Opaque;
242 bool m_twoSided = false;
243 };
244};
245
246#endif
float GetAlphaCutoff() const
Definition Material.cpp:363
Math::Color GetEmissiveColor() const
Definition Material.cpp:315
Texture * GetRoughnessTexture() const
Definition Material.cpp:203
void SetShader(RenderEngine::Shader *shader)
Definition Material.cpp:125
Texture * GetMetallicTexture() const
Definition Material.cpp:222
bool HasNormalTexture() const
Definition Material.cpp:172
Math::Color GetSpecularColor() const
Definition Material.cpp:296
RenderEngine::Shader * GetShader() const
Definition Material.cpp:136
void SetMetallicTexture(Texture *texture)
Definition Material.cpp:213
Texture * GetNormalTexture() const
Definition Material.cpp:167
void SetNormalTexture(Texture *texture)
Definition Material.cpp:158
void SetAO(float ao)
Definition Material.cpp:337
void SetOpacity(float opacity)
Definition Material.cpp:355
Texture * GetDiffuseTexture() const
Definition Material.cpp:149
void SetMetallic(float metallic)
Definition Material.cpp:325
void SetShininess(float shininess)
Definition Material.cpp:319
bool HasEmissiveTexture() const
Definition Material.cpp:264
void SetOffset(float x, float y)
Definition Material.cpp:379
bool IsTwoSided() const
Definition Material.cpp:405
bool HasAOTexture() const
Definition Material.cpp:245
~Material() override
float GetOpacity() const
Definition Material.cpp:357
void SetAOTexture(Texture *texture)
Definition Material.cpp:232
void SetDiffuseTexture(Texture *texture)
Definition Material.cpp:140
void SetSpecularColor(Math::Color color)
Definition Material.cpp:287
float GetShininess() const
Definition Material.cpp:323
Texture * GetEmissiveTexture() const
Definition Material.cpp:258
void SetRenderMode(MaterialRenderMode mode)
Definition Material.cpp:393
float GetAO() const
Definition Material.cpp:339
void SetAlphaCutoff(float cutoff)
Definition Material.cpp:359
void Initialize()
Lazily allocates the material's constant buffer on first use.
Definition Material.cpp:13
void SetSpecularTexture(Texture *texture)
Definition Material.cpp:176
bool HasRoughnessTexture() const
Definition Material.cpp:209
void BindTexturesAndCB()
Binds textures and uploads the material CB for the deferred geometry pass, skipping the shader bind.
Definition Material.cpp:108
bool HasSpecularTexture() const
Definition Material.cpp:190
Texture * GetSpecularTexture() const
Definition Material.cpp:185
void SetRoughnessTexture(Texture *texture)
Definition Material.cpp:194
Math::Vector2D GetTiling() const
Definition Material.cpp:375
Math::Color GetDiffuseColor() const
Definition Material.cpp:285
void SetTwoSided(bool twoSided)
Definition Material.cpp:401
MaterialRenderMode GetRenderMode() const
Definition Material.cpp:397
bool HasDiffuseTexture() const
Definition Material.cpp:154
void SetNormalIntensity(float intensity)
Definition Material.cpp:341
void SetEmissiveTexture(Texture *texture)
Definition Material.cpp:249
Math::Vector2D GetOffset() const
Definition Material.cpp:389
void SetEmissiveColor(Math::Color color)
Definition Material.cpp:300
void SetDiffuseColor(Math::Color color)
Definition Material.cpp:268
void SetRoughness(float roughness)
Definition Material.cpp:331
bool IsForwardRendered() const
True when this material must skip the GBuffer and render in the forward transparent pass.
Definition Material.cpp:102
Texture * GetAOTexture() const
Definition Material.cpp:241
float GetNormalIntensity() const
Definition Material.cpp:345
float GetRoughness() const
Definition Material.cpp:335
void SetTiling(float x, float y)
Definition Material.cpp:365
float GetMetallic() const
Definition Material.cpp:329
void SetEmissiveIntensity(float intensity)
Definition Material.cpp:347
void Bind()
Binds shader, all set textures, and uploads the packed material CB for a forward draw.
Definition Material.cpp:25
float GetEmissiveIntensity() const
Definition Material.cpp:351
bool HasMetallicTexture() const
Definition Material.cpp:228
Object(const std::string &name="Object")
Definition Object.hpp:14
Backend-agnostic compiled shader program.
Definition Shader.hpp:11
MaterialRenderMode
Definition Material.hpp:33
Root namespace for everything the engine exposes.
Definition Camera.hpp:10
Packed PBR material parameters uploaded to the material constant buffer.