Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

materials: seperate storage / allow overrides #31

Merged
merged 9 commits into from
Jan 24, 2024
173 changes: 112 additions & 61 deletions include/vierkant/Material.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,81 +4,78 @@

#pragma once

#include <crocore/NamedUUID.hpp>

#include "vierkant/Geometry.hpp"
#include "vierkant/Image.hpp"
#include "vierkant/Pipeline.hpp"

namespace vierkant
{

DEFINE_CLASS_PTR(Material)
//! define resource-identifiers
DEFINE_NAMED_UUID(MaterialId)
DEFINE_NAMED_UUID(TextureSourceId)
DEFINE_NAMED_UUID(SamplerId)

class Material
enum class BlendMode : uint8_t
{
public:
enum class BlendMode : uint8_t
{
Opaque = 0,
Blend = 1,
Mask = 2
};

enum class CullMode : uint8_t
{
None = 0,
Front,
Back,
FrontAndBack
};

enum TextureType : uint32_t
{
Color = 0x001,
Normal = 0x002,
Ao_rough_metal = 0x004,
Emission = 0x008,
Displacement = 0x010,
VolumeThickness = 0x020,
Transmission = 0x040,
Clearcoat = 0x080,
SheenColor = 0x100,
SheenRoughness = 0x200,
Iridescence = 0x400,
IridescenceThickness = 0x800,
Specular = 0x1000,
SpecularColor = 0x2000,
Environment = 0x4000
};
Opaque = 0,
Blend = 1,
Mask = 2
};

static MaterialPtr create() { return MaterialPtr(new Material()); };
enum class CullMode : uint8_t
{
None = 0,
Front,
Back,
FrontAndBack
};

[[nodiscard]] std::size_t hash() const;
enum class TextureType : uint32_t
{
Color = 0x001,
Normal = 0x002,
Ao_rough_metal = 0x004,
Emission = 0x008,
Displacement = 0x010,
VolumeThickness = 0x020,
Transmission = 0x040,
Clearcoat = 0x080,
SheenColor = 0x100,
SheenRoughness = 0x200,
Iridescence = 0x400,
IridescenceThickness = 0x800,
Specular = 0x1000,
SpecularColor = 0x2000,
Environment = 0x4000
};

struct material_t
{
vierkant::MaterialId id;
std::string name;

glm::vec4 color = glm::vec4(1);

glm::vec4 emission = glm::vec4(0, 0, 0, 1);

float metalness = 0.f;
glm::vec4 base_color = glm::vec4(1.f);
glm::vec3 emission = glm::vec3(0.f);
float emissive_strength = 1.f;

float roughness = 1.f;

float metalness = 0.f;
float occlusion = 1.f;

bool two_sided = false;

//! null-surface (skip surface interaction)
bool null_surface = false;

BlendMode blend_mode = BlendMode::Opaque;

float alpha_cutoff = 0.5f;

float transmission = 0.f;
bool twosided = false;

// transmission
float ior = 1.5f;
glm::vec3 attenuation_color = glm::vec3(1.f);

// volumes
float transmission = 0.f;
float attenuation_distance = std::numeric_limits<float>::infinity();

// phase-function asymmetry parameter (forward- vs. back-scattering) [-1, 1]
Expand All @@ -87,14 +84,22 @@ class Material
// ratio of scattering vs. absorption (sigma_s / sigma_t)
float scattering_ratio = 0.f;

float ior = 1.5f;
// idk rasterizer only thingy
float thickness = 1.f;

float clearcoat_factor = 0.f;
vierkant::BlendMode blend_mode = vierkant::BlendMode::Opaque;
float alpha_cutoff = 0.5f;

// specular
float specular_factor = 1.f;
glm::vec3 specular_color = glm::vec3(1.f);

// clearcoat
float clearcoat_factor = 0.f;
float clearcoat_roughness_factor = 0.f;

// sheen
glm::vec3 sheen_color = glm::vec3(0.f);

float sheen_roughness = 0.f;

// iridescence
Expand All @@ -104,19 +109,65 @@ class Material
// iridescence thin-film layer given in nanometers (nm)
glm::vec2 iridescence_thickness_range = {100.f, 400.f};

bool depth_test = true;
// optional texture-transform (todo: per image)
glm::mat4 texture_transform = glm::mat4(1);

bool depth_write = true;
// maps TextureType to a TextureId/SamplerId. sorted in enum order, which is important in other places.
std::map<vierkant::TextureType, vierkant::TextureSourceId> textures;
std::map<vierkant::TextureType, vierkant::SamplerId> samplers;
};

VkCullModeFlagBits cull_mode = VK_CULL_MODE_BACK_BIT;
bool operator==(const vierkant::material_t &lhs, const vierkant::material_t &rhs);
inline bool operator!=(const vierkant::material_t &lhs, const vierkant::material_t &rhs) { return !(lhs == rhs); }

std::map<TextureType, vierkant::ImagePtr> textures;
struct texture_sampler_t
{
enum class Filter
{
NEAREST = 0,
LINEAR,
CUBIC
};

// optional texture-transform (todo: per image)
glm::mat4 texture_transform = glm::mat4(1);
enum class AddressMode
{
REPEAT = 0,
MIRRORED_REPEAT,
CLAMP_TO_EDGE,
CLAMP_TO_BORDER,
MIRROR_CLAMP_TO_EDGE,
};

AddressMode address_mode_u = AddressMode::REPEAT;
AddressMode address_mode_v = AddressMode::REPEAT;

Filter min_filter = Filter::LINEAR;
Filter mag_filter = Filter::LINEAR;
glm::mat4 transform = glm::mat4(1);
};

DEFINE_CLASS_PTR(Material)

class Material
{
public:
static MaterialPtr create() { return MaterialPtr(new Material()); };

material_t m;
std::map<TextureType, vierkant::ImagePtr> textures;

private:
Material() = default;
};

}// namespace vierkant
}// namespace vierkant

// template specializations for hashing
namespace std
{
template<>
struct hash<vierkant::material_t>
{
size_t operator()(vierkant::material_t const &m) const;
};
}// namespace std
2 changes: 1 addition & 1 deletion include/vierkant/Object3D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class Object3D : public std::enable_shared_from_this<Object3D>
template<object_component T>
inline T &add_component(const T &component = {})
{
if(auto reg = m_registry.lock()) { return reg->template emplace<T>(m_entity, component); }
if(auto reg = m_registry.lock()) { return reg->template emplace_or_replace<T>(m_entity, component); }
throw std::runtime_error("error adding component: no registry defined");
}

Expand Down
2 changes: 1 addition & 1 deletion include/vierkant/RayBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class RayBuilder

uint32_t texture_type_flags = 0;

uint32_t blend_mode = static_cast<uint32_t>(Material::BlendMode::Opaque);
uint32_t blend_mode = static_cast<uint32_t>(vierkant::BlendMode::Opaque);

float alpha_cutoff = 0.5f;

Expand Down
2 changes: 1 addition & 1 deletion include/vierkant/drawable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct alignas(16) material_struct_t

float ambient = 1.f;

uint32_t blend_mode = static_cast<uint32_t>(Material::BlendMode::Opaque);
uint32_t blend_mode = static_cast<uint32_t>(vierkant::BlendMode::Opaque);

float alpha_cutoff = 0.5f;

Expand Down
88 changes: 4 additions & 84 deletions include/vierkant/model/model_loading.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <variant>

#include <crocore/Image.hpp>
#include <crocore/NamedUUID.hpp>
#include <crocore/ThreadPool.hpp>

#include <vierkant/Geometry.hpp>
Expand All @@ -19,8 +18,9 @@

namespace vierkant
{
DEFINE_NAMED_UUID(TextureSourceId)
DEFINE_NAMED_UUID(SamplerId)

//! define resource-identifiers
DEFINE_NAMED_UUID(MeshId)

//! contains uncompressed or BC7-compressed images
using texture_variant_t = std::variant<crocore::ImagePtr, vierkant::bc7::compress_result_t>;
Expand All @@ -35,86 +35,6 @@ using geometry_variant_t = std::variant<std::vector<vierkant::Mesh::entry_create
namespace vierkant::model
{

struct material_t
{
std::string name;

glm::vec4 base_color = glm::vec4(1.f);
glm::vec3 emission;
float emissive_strength = 1.f;

float roughness = 1.f;
float metalness = 0.f;

// transmission
float ior = 1.5f;
glm::vec3 attenuation_color = glm::vec3(1.f);

// volumes
float transmission = 0.f;
float attenuation_distance = std::numeric_limits<float>::infinity();

// idk rasterizer only thingy
float thickness = 1.f;

vierkant::Material::BlendMode blend_mode = vierkant::Material::BlendMode::Opaque;
float alpha_cutoff = 0.5f;

bool twosided = false;

// specular
float specular_factor = 1.f;
glm::vec3 specular_color = glm::vec3(1.f);

// clearcoat
float clearcoat_factor = 0.f;
float clearcoat_roughness_factor = 0.f;

// sheen
glm::vec3 sheen_color = glm::vec3(0.f);
float sheen_roughness = 0.f;

// iridescence
float iridescence_factor = 0.f;
float iridescence_ior = 1.3f;

// iridescence thin-film layer given in nanometers (nm)
glm::vec2 iridescence_thickness_range = {100.f, 400.f};

// optional texture-transform (todo: per image)
glm::mat4 texture_transform = glm::mat4(1);

// maps TextureType to a TextureId/SamplerId. sorted in enum order, which is important in other places.
std::map<Material::TextureType, vierkant::TextureSourceId> textures;
std::map<Material::TextureType, vierkant::SamplerId> samplers;
};

struct texture_sampler_t
{
enum class Filter
{
NEAREST = 0,
LINEAR,
CUBIC
};

enum class AddressMode
{
REPEAT = 0,
MIRRORED_REPEAT,
CLAMP_TO_EDGE,
CLAMP_TO_BORDER,
MIRROR_CLAMP_TO_EDGE,
};

AddressMode address_mode_u = AddressMode::REPEAT;
AddressMode address_mode_v = AddressMode::REPEAT;

Filter min_filter = Filter::LINEAR;
Filter mag_filter = Filter::LINEAR;
glm::mat4 transform = glm::mat4(1);
};

enum class LightType : uint32_t
{
Omni = 0,
Expand Down Expand Up @@ -151,7 +71,7 @@ struct mesh_assets_t
geometry_variant_t geometry_data;

//! common materials for all submeshes
std::vector<material_t> materials;
std::vector<vierkant::material_t> materials;

//! common textures for all materials
std::unordered_map<vierkant::TextureSourceId, texture_variant_t> textures;
Expand Down
8 changes: 3 additions & 5 deletions src/DrawContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,10 @@ DrawContext::DrawContext(vierkant::DevicePtr device) : m_device(std::move(device
box->tangents.clear();
box->normals.clear();
vierkant::mesh_component_t mesh_component = {vierkant::Mesh::create_from_geometry(m_device, box, {})};
auto &mat = mesh_component.mesh->materials.front();
mat->depth_write = false;
mat->depth_test = true;
mat->cull_mode = VK_CULL_MODE_FRONT_BIT;
mat->textures[vierkant::Material::TextureType::Environment] = {};
m_drawable_skybox = vierkant::create_drawables(mesh_component, drawable_params).front();
m_drawable_skybox.pipeline_format.depth_write = false;
m_drawable_skybox.pipeline_format.depth_test = true;
m_drawable_skybox.pipeline_format.cull_mode = VK_CULL_MODE_FRONT_BIT;
}
}

Expand Down
Loading
Loading