Skip to content

Materials

A material bundles the surface parameters passed to a shader - colors, texture references, and PBR scalars. In the ECS, materials live on the MaterialComponent attached to an entity.

MaterialComponent

cpp
auto* obj = add_entity<Object>("Cube", glm::vec3(0, 0, -5));
obj->add_component<MaterialComponent>();

By default, MaterialComponent initializes with a plain white albedo and fully non-metallic, rough surface.

PBR Properties

PropertyTypeDefaultDescription
albedoglm::vec4{1, 1, 1, 1}Base color (RGBA)
metallicfloat0.0Metallic factor [0, 1]
roughnessfloat1.0Roughness factor [0, 1]
aofloat1.0Ambient occlusion scalar
emissiveglm::vec3{0, 0, 0}Emissive color
emissive_strengthfloat0.0Emissive intensity multiplier

Texture Maps

Texture maps are set by referencing a registered Texture2D id:

cpp
auto* mat = obj->add_component<MaterialComponent>();
mat->set_albedo_map("albedo");
mat->set_normal_map("normal");
mat->set_metallic_roughness_map("metallic_roughness");
mat->set_ao_map("ao");
mat->set_emissive_map("emissive");

When a map is set, it takes precedence over the corresponding scalar property in the shader.

MaterialDescriptor

For batch registration, use MaterialDescriptor:

cpp
auto desc = MaterialDescriptor::create("rock");
desc->albedo       = glm::vec4(0.6f, 0.5f, 0.4f, 1.0f);
desc->roughness    = 0.9f;
desc->metallic     = 0.0f;
desc->albedo_map   = "rock_albedo";
desc->normal_map   = "rock_normal";

ResourceManager::get()->register_material(std::move(desc));

Then upload:

cpp
res->load_from_descriptors<MaterialDescriptor>(RendererBackend::OpenGL);

Attaching a Registered Material

cpp
obj->get_component<MaterialComponent>()->attach_material("rock");

This copies the descriptor's property values into the component and resolves the texture handles.

Rendering

GeometryPass iterates entities with MeshComponent, ResourceComponent, and MaterialComponent. It binds the resolved shader and uploads material properties as uniforms before issuing the draw call: