SleakEngine 1.0.0
C++23 multi-backend game engine
Loading...
Searching...
No Matches
Material.cpp
Go to the documentation of this file.
5
6namespace Sleak {
7
8 Material::Material() : Object("Material") {}
9
10 Material::~Material() = default;
11
12 /// Lazily allocates the material's constant buffer on first use.
14 if (!m_materialBuffer) {
15 m_materialBuffer = ObjectPtr<RenderEngine::BufferBase>(
19 nullptr));
20 m_materialBuffer->SetSlot(1);
21 }
22 }
23
24 /// Binds shader, all set textures, and uploads the packed material CB for a forward draw.
26 if (m_shader) {
27 m_shader->bind();
28 }
29
30 if (m_diffuseTexture)
31 m_diffuseTexture->Bind(TEXTURE_SLOT_DIFFUSE);
32 if (m_normalTexture)
33 m_normalTexture->Bind(TEXTURE_SLOT_NORMAL);
34 if (m_specularTexture)
35 m_specularTexture->Bind(TEXTURE_SLOT_SPECULAR);
36 if (m_roughnessTexture)
37 m_roughnessTexture->Bind(TEXTURE_SLOT_ROUGHNESS);
38 if (m_metallicTexture)
39 m_metallicTexture->Bind(TEXTURE_SLOT_METALLIC);
40 if (m_aoTexture)
41 m_aoTexture->Bind(TEXTURE_SLOT_AO);
42 if (m_emissiveTexture)
43 m_emissiveTexture->Bind(TEXTURE_SLOT_EMISSIVE);
44
45 if (m_materialBuffer) {
46 RenderEngine::MaterialGPUData data = BuildGPUData();
47 m_materialBuffer->Update(&data, sizeof(data));
48 m_materialBuffer->Update();
49 }
50 }
51
52 /// Packs texture-presence flags and material scalars into the GPU constant buffer layout.
53 RenderEngine::MaterialGPUData Material::BuildGPUData() const {
55
56 data.HasDiffuseMap = m_diffuseTexture.IsValid() ? 1u : 0u;
57 data.HasNormalMap = m_normalTexture.IsValid() ? 1u : 0u;
58 data.HasSpecularMap = m_specularTexture.IsValid() ? 1u : 0u;
59 data.HasRoughnessMap = m_roughnessTexture.IsValid() ? 1u : 0u;
60 data.HasMetallicMap = m_metallicTexture.IsValid() ? 1u : 0u;
61 data.HasAOMap = m_aoTexture.IsValid() ? 1u : 0u;
62 data.HasEmissiveMap = m_emissiveTexture.IsValid() ? 1u : 0u;
63 data._pad0 = 0;
64
65 Math::Vector4D diffNorm = m_diffuseColor.normalize();
66 data.DiffuseR = diffNorm.GetX();
67 data.DiffuseG = diffNorm.GetY();
68 data.DiffuseB = diffNorm.GetZ();
69 data.DiffuseA = diffNorm.GetW();
70
71 Math::Vector4D specNorm = m_specularColor.normalize();
72 data.SpecularR = specNorm.GetX();
73 data.SpecularG = specNorm.GetY();
74 data.SpecularB = specNorm.GetZ();
75 data.Shininess = m_shininess;
76
77 Math::Vector4D emitNorm = m_emissiveColor.normalize();
78 data.EmissiveR = emitNorm.GetX();
79 data.EmissiveG = emitNorm.GetY();
80 data.EmissiveB = emitNorm.GetZ();
81 data.EmissiveIntensity = m_emissiveIntensity;
82
83 data.Metallic = m_metallic;
84 data.Roughness = m_roughness;
85 data.AO = m_ao;
86 data.NormalIntensity = m_normalIntensity;
87
88 data.TilingX = m_tilingX;
89 data.TilingY = m_tilingY;
90 data.OffsetX = m_offsetX;
91 data.OffsetY = m_offsetY;
92
93 data.Opacity = m_opacity;
94 data.AlphaCutoff = m_alphaCutoff;
95 data._pad1 = 0.0f;
96 data._pad2 = 0.0f;
97
98 return data;
99 }
100
101 /// True when this material must skip the GBuffer and render in the forward transparent pass.
103 return m_renderMode == MaterialRenderMode::Transparent
104 || m_opacity < 1.0f;
105 }
106
107 /// Binds textures and uploads the material CB for the deferred geometry pass, skipping the shader bind.
109 // Same as Bind() but without shader->bind() — geometry pass overrides the shader.
110 if (m_diffuseTexture) m_diffuseTexture->Bind(TEXTURE_SLOT_DIFFUSE);
111 if (m_normalTexture) m_normalTexture->Bind(TEXTURE_SLOT_NORMAL);
112 if (m_specularTexture) m_specularTexture->Bind(TEXTURE_SLOT_SPECULAR);
113 if (m_roughnessTexture) m_roughnessTexture->Bind(TEXTURE_SLOT_ROUGHNESS);
114 if (m_metallicTexture) m_metallicTexture->Bind(TEXTURE_SLOT_METALLIC);
115 if (m_aoTexture) m_aoTexture->Bind(TEXTURE_SLOT_AO);
116 if (m_emissiveTexture) m_emissiveTexture->Bind(TEXTURE_SLOT_EMISSIVE);
117
118 if (m_materialBuffer) {
119 RenderEngine::MaterialGPUData data = BuildGPUData();
120 m_materialBuffer->Update(&data, sizeof(data));
121 m_materialBuffer->Update();
122 }
123 }
124
126 m_shader = ObjectPtr<RenderEngine::Shader>(shader);
127 }
128
129 void Material::SetShader(const std::string& shaderPath) {
130 auto* shader =
132 if (shader)
133 m_shader = ObjectPtr<RenderEngine::Shader>(shader);
134 }
135
137 return m_shader.IsValid() ? m_shader.operator->() : nullptr;
138 }
139
141 m_diffuseTexture = ObjectPtr<Texture>(texture);
142 }
143
144 void Material::SetDiffuseTexture(const std::string& path) {
145 m_diffuseTexture = ObjectPtr<Texture>(
147 }
148
150 return m_diffuseTexture.IsValid() ? m_diffuseTexture.operator->()
151 : nullptr;
152 }
153
155 return m_diffuseTexture.IsValid();
156 }
157
159 m_normalTexture = ObjectPtr<Texture>(texture);
160 }
161
162 void Material::SetNormalTexture(const std::string& path) {
163 m_normalTexture = ObjectPtr<Texture>(
165 }
166
168 return m_normalTexture.IsValid() ? m_normalTexture.operator->()
169 : nullptr;
170 }
171
173 return m_normalTexture.IsValid();
174 }
175
177 m_specularTexture = ObjectPtr<Texture>(texture);
178 }
179
180 void Material::SetSpecularTexture(const std::string& path) {
181 m_specularTexture = ObjectPtr<Texture>(
183 }
184
186 return m_specularTexture.IsValid() ? m_specularTexture.operator->()
187 : nullptr;
188 }
189
191 return m_specularTexture.IsValid();
192 }
193
195 m_roughnessTexture = ObjectPtr<Texture>(texture);
196 }
197
198 void Material::SetRoughnessTexture(const std::string& path) {
199 m_roughnessTexture = ObjectPtr<Texture>(
201 }
202
204 return m_roughnessTexture.IsValid()
205 ? m_roughnessTexture.operator->()
206 : nullptr;
207 }
208
210 return m_roughnessTexture.IsValid();
211 }
212
214 m_metallicTexture = ObjectPtr<Texture>(texture);
215 }
216
217 void Material::SetMetallicTexture(const std::string& path) {
218 m_metallicTexture = ObjectPtr<Texture>(
220 }
221
223 return m_metallicTexture.IsValid()
224 ? m_metallicTexture.operator->()
225 : nullptr;
226 }
227
229 return m_metallicTexture.IsValid();
230 }
231
233 m_aoTexture = ObjectPtr<Texture>(texture);
234 }
235
236 void Material::SetAOTexture(const std::string& path) {
237 m_aoTexture = ObjectPtr<Texture>(
239 }
240
242 return m_aoTexture.IsValid() ? m_aoTexture.operator->() : nullptr;
243 }
244
246 return m_aoTexture.IsValid();
247 }
248
250 m_emissiveTexture = ObjectPtr<Texture>(texture);
251 }
252
253 void Material::SetEmissiveTexture(const std::string& path) {
254 m_emissiveTexture = ObjectPtr<Texture>(
256 }
257
259 return m_emissiveTexture.IsValid()
260 ? m_emissiveTexture.operator->()
261 : nullptr;
262 }
263
265 return m_emissiveTexture.IsValid();
266 }
267
269 m_diffuseColor = color;
270 }
271
272 void Material::SetDiffuseColor(uint8_t r, uint8_t g, uint8_t b,
273 uint8_t a) {
274 m_diffuseColor = Math::Color(r, g, b, a);
275 }
276
277 void Material::SetDiffuseColor(float r, float g, float b, float a) {
278 m_diffuseColor = Math::Color(
279 static_cast<uint8_t>(r * 255.0f),
280 static_cast<uint8_t>(g * 255.0f),
281 static_cast<uint8_t>(b * 255.0f),
282 static_cast<uint8_t>(a * 255.0f));
283 }
284
285 Math::Color Material::GetDiffuseColor() const { return m_diffuseColor; }
286
288 m_specularColor = color;
289 }
290
291 void Material::SetSpecularColor(uint8_t r, uint8_t g, uint8_t b,
292 uint8_t a) {
293 m_specularColor = Math::Color(r, g, b, a);
294 }
295
297 return m_specularColor;
298 }
299
301 m_emissiveColor = color;
302 }
303
304 void Material::SetEmissiveColor(uint8_t r, uint8_t g, uint8_t b) {
305 m_emissiveColor = Math::Color(r, g, b, 255);
306 }
307
308 void Material::SetEmissiveColor(float r, float g, float b) {
309 m_emissiveColor = Math::Color(
310 static_cast<uint8_t>(r * 255.0f),
311 static_cast<uint8_t>(g * 255.0f),
312 static_cast<uint8_t>(b * 255.0f), 255);
313 }
314
316 return m_emissiveColor;
317 }
318
319 void Material::SetShininess(float shininess) {
320 m_shininess = shininess;
321 }
322
323 float Material::GetShininess() const { return m_shininess; }
324
325 void Material::SetMetallic(float metallic) {
326 m_metallic = metallic;
327 }
328
329 float Material::GetMetallic() const { return m_metallic; }
330
331 void Material::SetRoughness(float roughness) {
332 m_roughness = roughness;
333 }
334
335 float Material::GetRoughness() const { return m_roughness; }
336
337 void Material::SetAO(float ao) { m_ao = ao; }
338
339 float Material::GetAO() const { return m_ao; }
340
341 void Material::SetNormalIntensity(float intensity) {
342 m_normalIntensity = intensity;
343 }
344
345 float Material::GetNormalIntensity() const { return m_normalIntensity; }
346
347 void Material::SetEmissiveIntensity(float intensity) {
348 m_emissiveIntensity = intensity;
349 }
350
352 return m_emissiveIntensity;
353 }
354
355 void Material::SetOpacity(float opacity) { m_opacity = opacity; }
356
357 float Material::GetOpacity() const { return m_opacity; }
358
359 void Material::SetAlphaCutoff(float cutoff) {
360 m_alphaCutoff = cutoff;
361 }
362
363 float Material::GetAlphaCutoff() const { return m_alphaCutoff; }
364
365 void Material::SetTiling(float x, float y) {
366 m_tilingX = x;
367 m_tilingY = y;
368 }
369
371 m_tilingX = tiling.GetX();
372 m_tilingY = tiling.GetY();
373 }
374
376 return Math::Vector2D(m_tilingX, m_tilingY);
377 }
378
379 void Material::SetOffset(float x, float y) {
380 m_offsetX = x;
381 m_offsetY = y;
382 }
383
385 m_offsetX = offset.GetX();
386 m_offsetY = offset.GetY();
387 }
388
390 return Math::Vector2D(m_offsetX, m_offsetY);
391 }
392
394 m_renderMode = mode;
395 }
396
398 return m_renderMode;
399 }
400
401 void Material::SetTwoSided(bool twoSided) {
402 m_twoSided = twoSided;
403 }
404
405 bool Material::IsTwoSided() const { return m_twoSided; }
406
407}
#define TEXTURE_SLOT_DIFFUSE
Definition Material.hpp:15
#define TEXTURE_SLOT_METALLIC
Definition Material.hpp:19
#define TEXTURE_SLOT_NORMAL
Definition Material.hpp:16
#define TEXTURE_SLOT_SPECULAR
Definition Material.hpp:17
#define TEXTURE_SLOT_EMISSIVE
Definition Material.hpp:21
#define TEXTURE_SLOT_AO
Definition Material.hpp:20
#define TEXTURE_SLOT_ROUGHNESS
Definition Material.hpp:18
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
Vector4D normalize() const noexcept
Converts to a Vector4D with each channel in [0,1].
Definition Color.hpp:93
float GetX() const
Definition Vector.hpp:216
float GetY() const
Definition Vector.hpp:217
Object(const std::string &name="Object")
Definition Object.hpp:14
static Shader * CreateShader(const std::string &ShaderPath)
Compiles a shader via the currently registered backend factory.
static Sleak::Texture * CreateTexture(const std::string &TexturePath)
Loads a texture via the currently registered backend factory.
static BufferBase * CreateBuffer(BufferType Type, uint32_t Size, void *Data)
Creates a buffer via the currently registered backend factory.
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.