WIP material modernization - Added new material attributes
Some checks failed
CMake on multiple platforms / build (Release, cl, cl, windows-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, clang, clang++, macos-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, clang, clang++, ubuntu-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, gcc, g++, ubuntu-latest) (push) Has been cancelled

This commit is contained in:
2026-04-14 00:53:34 -07:00
parent c28e088118
commit 16de2d66f2
10 changed files with 250 additions and 176 deletions

View File

@@ -340,7 +340,9 @@ KRResource* KRContext::loadResource(const std::string& file_name, Block* data)
// shader pre-processor options definition file
resource = m_pSourceManager->load(name, extension, data);
} else if (extension.compare("mtl") == 0) {
resource = m_pMaterialManager->load(name.c_str(), data);
resource = m_pMaterialManager->loadResource(name.c_str(), extension, data);
} else if (extension.compare("krmaterial") == 0) {
resource = m_pMaterialManager->loadResource(name.c_str(), extension, data);
} else if (extension.compare("mp3") == 0) {
resource = m_pSoundManager->load(name.c_str(), extension, data);
} else if (extension.compare("wav") == 0) {

View File

@@ -722,7 +722,7 @@ void KRPipeline::updatePushConstants(KRNode::RenderInfo& ri, const Matrix4& matM
setPushConstant(ShaderValue::lightmaptexture, 5);
setPushConstant(ShaderValue::gbuffer_frame, 6);
setPushConstant(ShaderValue::gbuffer_depth, 7); // Texture unit 7 is used for reading the depth buffer in gBuffer pass #2 and in post-processing pass
setPushConstant(ShaderValue::reflectiontexture, 7); // Texture unit 7 is used for the reflection map textures in gBuffer pass #3 and when using forward rendering
// setPushConstant(ShaderValue::reflectiontexture, 7); // Texture unit 7 is used for the reflection map textures in gBuffer pass #3 and when using forward rendering
setPushConstant(ShaderValue::depth_frame, 0);
setPushConstant(ShaderValue::render_frame, 1);
setPushConstant(ShaderValue::volumetric_environment_frame, 2);

View File

@@ -53,10 +53,8 @@ enum class ShaderValueType : uint8_t
enum class ShaderValue : uint8_t
{
material_ambient = 0,
material_diffuse,
material_diffuse = 0,
material_specular,
material_reflection,
material_alpha,
material_shininess,
light_position,
@@ -84,16 +82,13 @@ enum class ShaderValue : uint8_t
diffusetexture,
speculartexture,
reflectioncubetexture,
reflectiontexture,
normaltexture,
diffusetexture_scale,
speculartexture_scale,
reflectiontexture_scale,
normaltexture_scale,
ambienttexture_scale,
diffusetexture_offset,
speculartexture_offset,
reflectiontexture_offset,
normaltexture_offset,
ambienttexture_offset,
shadow_mvp1,

View File

@@ -36,28 +36,28 @@
#include "KRRenderPass.h"
#include "KRContext.h"
#include "simdjson.h"
using namespace mimir;
using namespace hydra;
using namespace simdjson;
KRMaterial::KRMaterial(KRContext& context, const char* szName)
: KRResource(context, szName)
, m_ambient{ KRTexture::TEXTURE_USAGE_AMBIENT_MAP, 0, Vector2::Create(0.0f, 0.0f), Vector2::Create(1.0f, 1.0f) }
, m_diffuse{ KRTexture::TEXTURE_USAGE_DIFFUSE_MAP, 0, Vector2::Create(0.0f, 0.0f), Vector2::Create(1.0f, 1.0f) }
, m_specular{ KRTexture::TEXTURE_USAGE_NORMAL_MAP, 0, Vector2::Create(0.0f, 0.0f), Vector2::Create(1.0f, 1.0f) }
, m_reflection{ KRTexture::TEXTURE_USAGE_REFLECTION_MAP, 0, Vector2::Create(0.0f, 0.0f), Vector2::Create(1.0f, 1.0f) }
, m_reflectionCube(KRTexture::TEXTURE_USAGE_REFECTION_CUBE)
, m_normal{ KRTexture::TEXTURE_USAGE_NORMAL_MAP, 0, Vector2::Create(0.0f, 0.0f), Vector2::Create(1.0f, 1.0f) }
KRMaterial::KRMaterial(KRContext& context, const char* name)
: KRResource(context, name)
{
m_name = szName;
m_ambientColor = Vector3::Zero();
m_diffuseColor = Vector3::One();
m_specularColor = Vector3::One();
m_reflectionColor = Vector3::Zero();
m_tr = 1.0f;
m_ns = 0.0f;
m_alpha_mode = KRMATERIAL_ALPHA_MODE_OPAQUE;
}
KRMaterial::KRMaterial(KRContext& context, std::string name, mimir::Block* data)
: KRResource(context, name)
{
simdjson::dom::parser parser;
simdjson::dom::element jsonRoot;
data->lock();
auto error = parser.parse((const char*)data->getStart(), data->getSize()).get(jsonRoot);
data->unlock();
if (error) {
// TODO - Report and handle error
}
}
KRMaterial::~KRMaterial()
@@ -67,21 +67,35 @@ KRMaterial::~KRMaterial()
std::string KRMaterial::getExtension()
{
return "mtl";
return "krmaterial";
}
bool KRMaterial::needsVertexTangents()
{
return m_normal.texture.isSet();
return m_normalTexture.texture.isSet();
}
bool KRMaterial::save(Block& data)
{
simdjson::builder::string_builder sb;
sb.start_object();
sb.append_key_value<"name">(getName());
sb.end_object();
const char* str = nullptr;
auto error = sb.c_str().get(str);
if (error) {
return false;
// TODO - Report error
}
data.append(str);
return true;
/*
std::stringstream stream;
stream.precision(std::numeric_limits<long double>::digits10);
stream.setf(std::ios::fixed, std::ios::floatfield);
stream << "newmtl " << m_name;
stream << "newmtl " << getName();
stream << "\nka " << m_ambientColor.x << " " << m_ambientColor.y << " " << m_ambientColor.z;
stream << "\nkd " << m_diffuseColor.x << " " << m_diffuseColor.y << " " << m_diffuseColor.z;
stream << "\nks " << m_specularColor.x << " " << m_specularColor.y << " " << m_specularColor.z;
@@ -118,7 +132,7 @@ bool KRMaterial::save(Block& data)
} else {
stream << "\n# map_ReflectionCube cubemapname";
}
switch (m_alpha_mode) {
switch (m_alphaMode) {
case KRMATERIAL_ALPHA_MODE_OPAQUE:
stream << "\nalpha_mode opaque";
break;
@@ -136,10 +150,11 @@ bool KRMaterial::save(Block& data)
stream << "\n";
data.append(stream.str());
return true;
*/
}
/*
void KRMaterial::setAmbientMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset)
{
m_ambient.texture.set(texture_name);
@@ -179,17 +194,18 @@ void KRMaterial::setReflectionCube(std::string texture_name)
{
m_reflectionCube.set(texture_name);
}
*/
void KRMaterial::setAlphaMode(KRMaterial::alpha_mode_type alpha_mode)
{
m_alpha_mode = alpha_mode;
m_alphaMode = alpha_mode;
}
KRMaterial::alpha_mode_type KRMaterial::getAlphaMode()
{
return m_alpha_mode;
return m_alphaMode;
}
/*
void KRMaterial::setAmbient(const Vector3& c)
{
m_ambientColor = c;
@@ -209,63 +225,94 @@ void KRMaterial::setReflection(const Vector3& c)
{
m_reflectionColor = c;
}
*/
void KRMaterial::setTransparency(float a)
{
if (a < 1.0f && m_alpha_mode == KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE) {
setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE);
if (a < 1.0f && m_alphaMode == KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE) {
setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLEND);
}
m_tr = a;
m_baseColorFactor[3] = a;
}
void KRMaterial::setShininess(float s)
{
m_ns = s;
m_roughnessFactor = 1.0f - s;
}
bool KRMaterial::isTransparent()
{
return m_tr < 1.0 || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE;
return m_baseColorFactor[3] < 1.0 || m_alphaMode == KRMATERIAL_ALPHA_MODE_BLEND;
}
void KRMaterial::getResourceBindings(std::list<KRResourceBinding*>& bindings)
{
KRResource::getResourceBindings(bindings);
bindings.push_back(&m_ambient.texture);
bindings.push_back(&m_diffuse.texture);
bindings.push_back(&m_normal.texture);
bindings.push_back(&m_specular.texture);
bindings.push_back(&m_reflection.texture);
bindings.push_back(&m_reflectionCube);
bindings.push_back(&m_baseColorTexture.texture);
bindings.push_back(&m_normalTexture.texture);
bindings.push_back(&m_emissiveTexture.texture);
bindings.push_back(&m_occlusionTexture.texture);
bindings.push_back(&m_metalicRoughness.texture);
bindings.push_back(&m_anisotropyTexture.texture);
bindings.push_back(&m_clearcoatTexture.texture);
bindings.push_back(&m_clearcoatRoughnessTexture.texture);
bindings.push_back(&m_clearcoatNormalTexture.texture);
bindings.push_back(&m_specularTexture.texture);
bindings.push_back(&m_specularColorTexture.texture);
bindings.push_back(&m_thicknessTexture.texture);
}
kraken_stream_level KRMaterial::getStreamLevel()
{
kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ;
if (m_ambient.texture.isBound()) {
stream_level = KRMIN(stream_level, m_ambient.texture.get()->getStreamLevel());
if (m_baseColorTexture.texture.isBound()) {
stream_level = KRMIN(stream_level, m_baseColorTexture.texture.get()->getStreamLevel());
}
if (m_diffuse.texture.isBound()) {
stream_level = KRMIN(stream_level, m_diffuse.texture.get()->getStreamLevel());
if (m_normalTexture.texture.isBound()) {
stream_level = KRMIN(stream_level, m_normalTexture.texture.get()->getStreamLevel());
}
if (m_normal.texture.isBound()) {
stream_level = KRMIN(stream_level, m_normal.texture.get()->getStreamLevel());
if (m_occlusionTexture.texture.isBound()) {
stream_level = KRMIN(stream_level, m_occlusionTexture.texture.get()->getStreamLevel());
}
if (m_specular.texture.isBound()) {
stream_level = KRMIN(stream_level, m_specular.texture.get()->getStreamLevel());
if (m_metalicRoughness.texture.isBound()) {
stream_level = KRMIN(stream_level, m_metalicRoughness.texture.get()->getStreamLevel());
}
if (m_reflection.texture.isBound()) {
stream_level = KRMIN(stream_level, m_reflection.texture.get()->getStreamLevel());
if (m_anisotropyTexture.texture.isBound()) {
stream_level = KRMIN(stream_level, m_anisotropyTexture.texture.get()->getStreamLevel());
}
if (m_reflectionCube.isBound()) {
stream_level = KRMIN(stream_level, m_reflectionCube.get()->getStreamLevel());
if (m_clearcoatTexture.texture.isBound()) {
stream_level = KRMIN(stream_level, m_clearcoatTexture.texture.get()->getStreamLevel());
}
if (m_clearcoatTexture.texture.isBound()) {
stream_level = KRMIN(stream_level, m_clearcoatTexture.texture.get()->getStreamLevel());
}
if (m_clearcoatRoughnessTexture.texture.isBound()) {
stream_level = KRMIN(stream_level, m_clearcoatRoughnessTexture.texture.get()->getStreamLevel());
}
if (m_clearcoatNormalTexture.texture.isBound()) {
stream_level = KRMIN(stream_level, m_clearcoatNormalTexture.texture.get()->getStreamLevel());
}
if (m_specularTexture.texture.isBound()) {
stream_level = KRMIN(stream_level, m_specularTexture.texture.get()->getStreamLevel());
}
if (m_specularColorTexture.texture.isBound()) {
stream_level = KRMIN(stream_level, m_specularColorTexture.texture.get()->getStreamLevel());
}
if (m_thicknessTexture.texture.isBound()) {
stream_level = KRMIN(stream_level, m_thicknessTexture.texture.get()->getStreamLevel());
}
return stream_level;
@@ -278,14 +325,14 @@ void KRMaterial::bind(KRNode::RenderInfo& ri, ModelFormat modelFormat, __uint32_
Vector2 default_scale = Vector2::One();
Vector2 default_offset = Vector2::Zero();
bool bHasReflection = m_reflectionColor != Vector3::Zero();
bool bDiffuseMap = m_diffuse.texture.isBound() && ri.camera->settings.bEnableDiffuseMap;
bool bNormalMap = m_normal.texture.isBound() && ri.camera->settings.bEnableNormalMap;
bool bSpecMap = m_specular.texture.isBound() && ri.camera->settings.bEnableSpecMap;
bool bReflectionMap = m_reflection.texture.isBound() && ri.camera->settings.bEnableReflectionMap && ri.camera->settings.bEnableReflection && bHasReflection;
bool bReflectionCubeMap = m_reflectionCube.isBound() && ri.camera->settings.bEnableReflection && bHasReflection;
bool bAlphaTest = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_TEST) && bDiffuseMap;
bool bAlphaBlend = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE) || (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE);
bool bHasReflection = m_roughnessFactor > 0.f;
bool bDiffuseMap = m_baseColorTexture.texture.isBound() && ri.camera->settings.bEnableDiffuseMap;
bool bNormalMap = m_normalTexture.texture.isBound() && ri.camera->settings.bEnableNormalMap;
bool bSpecMap = false;
bool bReflectionMap = false;
bool bReflectionCubeMap = false;
bool bAlphaTest = m_alphaMode == KRMATERIAL_ALPHA_MODE_TEST;
bool bAlphaBlend = m_alphaMode == KRMATERIAL_ALPHA_MODE_BLEND;
PipelineInfo info{};
std::string shader_name("object");
@@ -302,14 +349,14 @@ void KRMaterial::bind(KRNode::RenderInfo& ri, ModelFormat modelFormat, __uint32_
info.bReflectionMap = bReflectionMap;
info.bReflectionCubeMap = bReflectionCubeMap;
info.bLightMap = bLightMap;
info.bDiffuseMapScale = m_diffuse.scale != default_scale && bDiffuseMap;
info.bSpecMapScale = m_specular.scale != default_scale && bSpecMap;
info.bNormalMapScale = m_normal.scale != default_scale && bNormalMap;
info.bReflectionMapScale = m_reflection.scale != default_scale && bReflectionMap;
info.bDiffuseMapOffset = m_diffuse.offset != default_offset && bDiffuseMap;
info.bSpecMapOffset = m_specular.offset != default_offset && bSpecMap;
info.bNormalMapOffset = m_normal.offset != default_offset && bNormalMap;
info.bReflectionMapOffset = m_reflection.offset != default_offset && bReflectionMap;
info.bDiffuseMapScale = m_baseColorTexture.scale != default_scale && bDiffuseMap;
info.bSpecMapScale = false;
info.bNormalMapScale = m_normalTexture.scale != default_scale && bNormalMap;
info.bReflectionMapScale = false;
info.bDiffuseMapOffset = false;
info.bSpecMapOffset = false;
info.bNormalMapOffset = m_normalTexture.offset != default_offset && bNormalMap;
info.bReflectionMapOffset = false;
info.bAlphaTest = bAlphaTest;
info.rasterMode = bAlphaBlend ? RasterMode::kAlphaBlend : RasterMode::kOpaque;
info.renderPass = ri.renderPass;
@@ -352,23 +399,25 @@ void KRMaterial::bind(KRNode::RenderInfo& ri, ModelFormat modelFormat, __uint32_
}
if (bDiffuseMap) {
pShader->setImageBinding("diffuseTexture", m_diffuse.texture.get(), getContext().getSamplerManager()->DEFAULT_WRAPPING_SAMPLER);
pShader->setImageBinding("diffuseTexture", m_baseColorTexture.texture.get(), getContext().getSamplerManager()->DEFAULT_WRAPPING_SAMPLER);
}
if (bSpecMap) {
pShader->setImageBinding("specularTexture", m_specular.texture.get(), getContext().getSamplerManager()->DEFAULT_WRAPPING_SAMPLER);
pShader->setImageBinding("specularTexture", m_specularColorTexture.texture.get(), getContext().getSamplerManager()->DEFAULT_WRAPPING_SAMPLER);
}
if (bNormalMap) {
pShader->setImageBinding("normalTexture", m_normal.texture.get(), getContext().getSamplerManager()->DEFAULT_WRAPPING_SAMPLER);
pShader->setImageBinding("normalTexture", m_normalTexture.texture.get(), getContext().getSamplerManager()->DEFAULT_WRAPPING_SAMPLER);
}
if (bReflectionCubeMap) {
pShader->setImageBinding("reflectionCubeTexture", m_reflectionCube.get(), getContext().getSamplerManager()->DEFAULT_CLAMPED_SAMPLER);
// Deprecated by reflection cubes..
// pShader->setImageBinding("reflectionCubeTexture", m_reflectionCube.get(), getContext().getSamplerManager()->DEFAULT_CLAMPED_SAMPLER);
}
if (bReflectionMap) {
pShader->setImageBinding("reflectionTexture", m_reflection.texture.get(), getContext().getSamplerManager()->DEFAULT_CLAMPED_SAMPLER);
// Deprecated by PBR model..
// pShader->setImageBinding("reflectionTexture", m_reflection.texture.get(), getContext().getSamplerManager()->DEFAULT_CLAMPED_SAMPLER);
}
ri.reflectedObjects.push_back(this);
@@ -376,20 +425,14 @@ void KRMaterial::bind(KRNode::RenderInfo& ri, ModelFormat modelFormat, __uint32_
ri.reflectedObjects.pop_back();
}
const std::string& KRMaterial::getName() const
{
return m_name;
}
bool KRMaterial::getShaderValue(ShaderValue value, float* output) const
{
switch (value) {
case ShaderValue::material_alpha:
*output = m_tr;
*output = m_baseColorFactor[3];
return true;
case ShaderValue::material_shininess:
*output = m_ns;
*output = 1.0f - m_roughnessFactor;
return true;
}
return false;
@@ -399,28 +442,22 @@ bool KRMaterial::getShaderValue(ShaderValue value, hydra::Vector2* output) const
{
switch (value) {
case ShaderValue::diffusetexture_scale:
*output = m_diffuse.scale;
*output = m_baseColorTexture.scale;
return true;
case ShaderValue::speculartexture_scale:
*output = m_specular.scale;
return true;
case ShaderValue::reflectiontexture_scale:
*output = m_reflection.scale;
*output = m_specularColorTexture.scale;
return true;
case ShaderValue::normaltexture_scale:
*output = m_normal.scale;
*output = m_normalTexture.scale;
return true;
case ShaderValue::diffusetexture_offset:
*output = m_diffuse.offset;
*output = m_baseColorTexture.offset;
return true;
case ShaderValue::speculartexture_offset:
*output = m_specular.offset;
return true;
case ShaderValue::reflectiontexture_offset:
*output = m_reflection.offset;
*output = m_specularColorTexture.offset;
return true;
case ShaderValue::normaltexture_offset:
*output = m_normal.offset;
*output = m_normalTexture.offset;
return true;
}
return false;
@@ -429,17 +466,11 @@ bool KRMaterial::getShaderValue(ShaderValue value, hydra::Vector2* output) const
bool KRMaterial::getShaderValue(ShaderValue value, hydra::Vector3* output) const
{
switch (value) {
case ShaderValue::material_reflection:
*output = m_reflectionColor;
return true;
case ShaderValue::material_ambient:
*output = m_ambientColor;
return true;
case ShaderValue::material_diffuse:
*output = m_diffuseColor;
*output = hydra::Vector3::Create(m_baseColorFactor);
return true;
case ShaderValue::material_specular:
*output = m_specularColor;
*output = m_specularColorFactor;
return true;
}
return false;

View File

@@ -61,26 +61,31 @@ public:
{
KRMATERIAL_ALPHA_MODE_OPAQUE, // Non-transparent materials
KRMATERIAL_ALPHA_MODE_TEST, // Alpha in diffuse texture is interpreted as punch-through when < 0.5
KRMATERIAL_ALPHA_MODE_BLENDONESIDE, // Blended alpha with backface culling
KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE // Blended alpha rendered in two passes. First pass renders backfaces; second pass renders frontfaces.
KRMATERIAL_ALPHA_MODE_BLEND // Blended alpha with backface culling
} alpha_mode_type;
struct TransformedTexture
{
KRTextureBinding texture;
int texCoord = 0; // uv texture index
hydra::Vector2 scale{};
hydra::Vector2 offset{};
float rotation = 0;
int texCoord{ 0 };
hydra::Vector2 scale{ 1.f, 1.f };
hydra::Vector2 offset{ 0.f, 0.f };
float rotation{ 0.f };
TransformedTexture(KRTexture::texture_usage_t usage)
: texture{ usage }
{
}
};
KRMaterial(KRContext& context, const char* szName);
KRMaterial(KRContext& context, std::string name, mimir::Block* data);
virtual ~KRMaterial();
virtual std::string getExtension();
virtual bool save(mimir::Block& data);
/*
void setAmbientMap(std::string texture_name, hydra::Vector2 texture_scale, hydra::Vector2 texture_offset);
void setDiffuseMap(std::string texture_name, hydra::Vector2 texture_scale, hydra::Vector2 texture_offset);
void setSpecularMap(std::string texture_name, hydra::Vector2 texture_scale, hydra::Vector2 texture_offset);
@@ -91,15 +96,16 @@ public:
void setDiffuse(const hydra::Vector3& c);
void setSpecular(const hydra::Vector3& c);
void setReflection(const hydra::Vector3& c);
*/
void setTransparency(float a);
void setShininess(float s);
void setAlphaMode(alpha_mode_type blend_mode);
alpha_mode_type getAlphaMode();
bool isTransparent();
const std::string& getName() const;
bool isTransparent();
void bind(KRNode::RenderInfo& ri, ModelFormat modelFormat, __uint32_t vertexAttributes, CullMode cullMode, const std::vector<KRBone*>& bones, const std::vector<hydra::Matrix4>& bind_poses, const hydra::Matrix4& matModel, KRTexture* pLightMap, float lod_coverage = 0.0f);
bool needsVertexTangents();
@@ -108,29 +114,45 @@ public:
virtual void getResourceBindings(std::list<KRResourceBinding*>& bindings) override;
private:
std::string m_name;
TransformedTexture m_ambient;// mtl map_Ka value
TransformedTexture m_diffuse; // mtl map_Kd value
TransformedTexture m_specular; // mtl map_Ks value
TransformedTexture m_reflection; // mtl refl value
KRTextureBinding m_reflectionCube;
TransformedTexture m_normal; // mtl map_Normal value
// --- Serialized Material Attributes ---
TransformedTexture m_baseColorTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_BASE_COLOR };
hydra::Vector4 m_baseColorFactor{ 1.f, 1.f, 1.f, 1.f };
TransformedTexture m_normalTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_NORMAL };
float m_normalScale{ 1.f };
TransformedTexture m_emissiveTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_EMISSIVE };
hydra::Vector3 m_emissiveFactor{ 0.f, 0.f, 0.f };
TransformedTexture m_occlusionTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_OCCLUSION };
float m_occlusionStrength{ 1.f };
TransformedTexture m_metalicRoughness{ KRTexture::TEXTURE_USAGE_MATERIAL_METALIC_ROUGHNESS };
float m_metalicFactor{ 1.f };
float m_roughnessFactor{ 1.f };
alpha_mode_type m_alphaMode{ KRMATERIAL_ALPHA_MODE_OPAQUE };
float m_alphaCutoff{ 0.5f };
bool m_doubleSided{ false };
float m_ior{ 1.5f };
bool m_isUnlit{ false };
hydra::Vector3 m_ambientColor; // Ambient rgb
hydra::Vector3 m_diffuseColor; // Diffuse rgb
hydra::Vector3 m_specularColor; // Specular rgb
hydra::Vector3 m_reflectionColor; // Reflection rgb
TransformedTexture m_anisotropyTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_ANISOTROPY };
float m_anisotropyStrength{ 0.f };
float m_anisotropyRotation{ 0.f };
//float m_ka_r, m_ka_g, m_ka_b; // Ambient rgb
//float m_kd_r, m_kd_g, m_kd_b; // Diffuse rgb
//float m_ks_r, m_ks_g, m_ks_b; // Specular rgb
//float m_kr_r, m_kr_g, m_kr_b; // Reflection rgb
TransformedTexture m_clearcoatTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_CLEARCOAT };
float m_clearcoatFactor{ 0.f };
TransformedTexture m_clearcoatRoughnessTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_CLEARCOAT_ROUGHNESS };
float m_clearcoatRoughnessFactor{ 0.f };
TransformedTexture m_clearcoatNormalTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_CLEARCOAT_NORMAL };
float m_tr; // Transparency
float m_ns; // Shininess
float m_dispersion{ 0.f };
alpha_mode_type m_alpha_mode;
TransformedTexture m_specularTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_SPECULAR };
float m_specularFactor{ 1.f };
TransformedTexture m_specularColorTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_SPECULAR_COLOR };
hydra::Vector3 m_specularColorFactor{ 1.f, 1.f, 1.f };
TransformedTexture m_thicknessTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_THICKNESS };
float m_thicknessFactor{ 0.f };
float m_attenuationDistance{ std::numeric_limits<float>::max() };
hydra::Vector3 m_attenuationColor{ 1.f, 1.f, 1.f };
private:
bool getShaderValue(ShaderValue value, float* output) const final;

View File

@@ -49,17 +49,19 @@ KRMaterialManager::~KRMaterialManager()
KRResource* KRMaterialManager::loadResource(const std::string& name, const std::string& extension, Block* data)
{
if (extension.compare("mtl") == 0) {
return load(name.c_str(), data);
return loadMtl(data);
} else if (extension.compare("krmaterial") == 0) {
KRMaterial* material = new KRMaterial(*m_pContext, name, data);
add(material);
return material;
}
return nullptr;
}
KRResource* KRMaterialManager::getResource(const std::string& name, const std::string& extension)
{
if (extension.compare("mtl") == 0) {
// TODO - This is not correct -- there are multiple materials emitted in a single mtl file.
// We should treat "mtl" files as source files, managed by KRSource, which output
// material resources when compiled.
if (extension.compare("krmaterial") == 0) {
return m_materials[name];
}
return nullptr;
@@ -97,7 +99,7 @@ void KRMaterialManager::add(KRMaterial* new_material)
m_materials[lowerName] = new_material;
}
KRMaterial* KRMaterialManager::load(const char* szName, Block* data)
KRMaterial* KRMaterialManager::loadMtl(Block* data)
{
KRMaterial* pMaterial = NULL;
char szSymbol[16][256];
@@ -151,61 +153,65 @@ KRMaterial* KRMaterialManager::load(const char* szName, Block* data)
if (cSymbols == 2) {
if (strcmp(szSymbol[1], "test") == 0) {
pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_TEST);
pMaterial->m_doubleSided = false;
} else if (strcmp(szSymbol[1], "blendoneside") == 0) {
pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE);
pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLEND);
pMaterial->m_doubleSided = false;
} else if (strcmp(szSymbol[1], "blendtwoside") == 0) {
pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE);
pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLEND);
pMaterial->m_doubleSided = true;
} else {
pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE);
pMaterial->m_doubleSided = false;
}
}
} else if (strcmp(szSymbol[0], "ka") == 0) {
char* pScan2 = szSymbol[1];
float r = strtof(pScan2, &pScan2);
if (cSymbols == 2) {
pMaterial->setAmbient(Vector3::Create(r, r, r));
// pMaterial->setAmbient(Vector3::Create(r, r, r)); // TODO - Map to modern material attributes. (Eg, detect unlit?)
} else if (cSymbols == 4) {
pScan2 = szSymbol[2];
float g = strtof(pScan2, &pScan2);
pScan2 = szSymbol[3];
float b = strtof(pScan2, &pScan2);
pMaterial->setAmbient(Vector3::Create(r, g, b));
// pMaterial->setAmbient(Vector3::Create(r, g, b)); // TODO - Map to modern material attributes. (Eg, detect unlit?)
}
} else if (strcmp(szSymbol[0], "kd") == 0) {
char* pScan2 = szSymbol[1];
float r = strtof(pScan2, &pScan2);
if (cSymbols == 2) {
pMaterial->setDiffuse(Vector3::Create(r, r, r));
pMaterial->m_baseColorFactor = Vector4::Create(r, r, r, 1.f);
} else if (cSymbols == 4) {
pScan2 = szSymbol[2];
float g = strtof(pScan2, &pScan2);
pScan2 = szSymbol[3];
float b = strtof(pScan2, &pScan2);
pMaterial->setDiffuse(Vector3::Create(r, g, b));
pMaterial->m_baseColorFactor = Vector4::Create(r, g, b, 1.f);
}
} else if (strcmp(szSymbol[0], "ks") == 0) {
char* pScan2 = szSymbol[1];
float r = strtof(pScan2, &pScan2);
if (cSymbols == 2) {
pMaterial->setSpecular(Vector3::Create(r, r, r));
pMaterial->m_specularColorFactor = Vector3::Create(r, r, r);
} else if (cSymbols == 4) {
pScan2 = szSymbol[2];
float g = strtof(pScan2, &pScan2);
pScan2 = szSymbol[3];
float b = strtof(pScan2, &pScan2);
pMaterial->setSpecular(Vector3::Create(r, g, b));
pMaterial->m_specularColorFactor = Vector3::Create(r, g, b);
}
} else if (strcmp(szSymbol[0], "kr") == 0) {
char* pScan2 = szSymbol[1];
float r = strtof(pScan2, &pScan2);
if (cSymbols == 2) {
pMaterial->setReflection(Vector3::Create(r, r, r));
pMaterial->m_roughnessFactor = 1.f - r;
} else if (cSymbols == 4) {
pScan2 = szSymbol[2];
float g = strtof(pScan2, &pScan2);
pScan2 = szSymbol[3];
float b = strtof(pScan2, &pScan2);
pMaterial->setReflection(Vector3::Create(r, g, b));
// pMaterial->setReflection(Vector3::Create(r, g, b)); // TODO - Map to modern material attributes
}
} else if (strcmp(szSymbol[0], "tr") == 0) {
char* pScan2 = szSymbol[1];
@@ -265,17 +271,23 @@ KRMaterial* KRMaterialManager::load(const char* szName, Block* data)
}
if (strcmp(szSymbol[0], "map_ka") == 0) {
pMaterial->setAmbientMap(szSymbol[1], texture_scale, texture_offset);
// pMaterial->setAmbientMap(szSymbol[1], texture_scale, texture_offset); // TODO - Map to modern material attributes. (Eg, unlit?)
} else if (strcmp(szSymbol[0], "map_kd") == 0) {
pMaterial->setDiffuseMap(szSymbol[1], texture_scale, texture_offset);
pMaterial->m_baseColorTexture.texture.set(szSymbol[1]);
pMaterial->m_baseColorTexture.scale = texture_scale;
pMaterial->m_baseColorTexture.offset = texture_offset;
} else if (strcmp(szSymbol[0], "map_ks") == 0) {
pMaterial->setSpecularMap(szSymbol[1], texture_scale, texture_offset);
pMaterial->m_specularColorTexture.texture.set(szSymbol[1]);
pMaterial->m_specularColorTexture.scale = texture_scale;
pMaterial->m_specularColorTexture.offset = texture_offset;
} else if (strcmp(szSymbol[0], "map_normal") == 0) {
pMaterial->setNormalMap(szSymbol[1], texture_scale, texture_offset);
pMaterial->m_normalTexture.texture.set(szSymbol[1]);
pMaterial->m_normalTexture.scale = texture_scale;
pMaterial->m_normalTexture.offset = texture_offset;
} else if (strcmp(szSymbol[0], "map_reflection") == 0) {
pMaterial->setReflectionMap(szSymbol[1], texture_scale, texture_offset);
// pMaterial->setReflectionMap(szSymbol[1], texture_scale, texture_offset); // TODO - Map to modern material attributes.
} else if (strcmp(szSymbol[0], "map_reflectioncube") == 0) {
pMaterial->setReflectionCube(szSymbol[1]);
// pMaterial->setReflectionCube(szSymbol[1]); // TODO - Map to modern material attributes. Deprecated by reflection probes?
}
}
}

View File

@@ -52,7 +52,7 @@ public:
virtual KRResource* loadResource(const std::string& name, const std::string& extension, mimir::Block* data) override;
virtual KRResource* getResource(const std::string& name, const std::string& extension) override;
KRMaterial* load(const char* szName, mimir::Block* data);
KRMaterial* loadMtl(mimir::Block* data);
void add(KRMaterial* new_material);
KRMaterial* getMaterial(const std::string& name);

View File

@@ -270,16 +270,16 @@ void KRMesh::render(KRNode::RenderInfo& ri, const std::string& object_name, cons
pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullBack, bones, bone_bind_poses, matModel, pLightMap, lod_coverage);
renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage);
break;
case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE: // Blended alpha with backface culling
pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullBack, bones, bone_bind_poses, matModel, pLightMap, lod_coverage);
renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage);
break;
case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE: // Blended alpha rendered in two passes. First pass renders backfaces; second pass renders frontfaces.
// Render back faces first
pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullFront, bones, bone_bind_poses, matModel, pLightMap, lod_coverage);
renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage);
case KRMaterial::KRMATERIAL_ALPHA_MODE_BLEND: // Blended Alpha
if (pMaterial->m_doubleSided) {
// Blended alpha rendered in two passes. First pass renders backfaces; second pass renders frontfaces.
//
// Render back faces before front faces
pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullFront, bones, bone_bind_poses, matModel, pLightMap, lod_coverage);
renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage);
}
// Render front faces second
// Render front faces
pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullBack, bones, bone_bind_poses, matModel, pLightMap, lod_coverage);
renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage);
break;

View File

@@ -189,7 +189,7 @@ float KRTexture::getStreamPriority()
if (m_last_frame_usage & (TEXTURE_USAGE_SKY_CUBE | TEXTURE_USAGE_PARTICLE | TEXTURE_USAGE_SPRITE | TEXTURE_USAGE_LIGHT_FLARE)) {
priority += 1000000.0f;
}
if (m_last_frame_usage & (TEXTURE_USAGE_DIFFUSE_MAP | TEXTURE_USAGE_AMBIENT_MAP | TEXTURE_USAGE_SPECULAR_MAP | TEXTURE_USAGE_NORMAL_MAP | TEXTURE_USAGE_REFLECTION_MAP)) {
if (m_last_frame_usage & (TEXTURE_USAGE_MATERIAL)) {
priority += 100000.0f;
}
if (m_last_frame_usage & (TEXTURE_USAGE_LIGHT_MAP)) {

View File

@@ -64,16 +64,28 @@ public:
TEXTURE_USAGE_UI = 0x01,
TEXTURE_USAGE_SKY_CUBE = 0x02,
TEXTURE_USAGE_LIGHT_MAP = 0x04,
TEXTURE_USAGE_DIFFUSE_MAP = 0x08,
TEXTURE_USAGE_AMBIENT_MAP = 0x10,
TEXTURE_USAGE_SPECULAR_MAP = 0x20,
TEXTURE_USAGE_NORMAL_MAP = 0x40,
TEXTURE_USAGE_REFLECTION_MAP = 0x80,
TEXTURE_USAGE_REFECTION_CUBE = 0x100,
TEXTURE_USAGE_LIGHT_FLARE = 0x200,
TEXTURE_USAGE_SHADOW_DEPTH = 0x400,
TEXTURE_USAGE_PARTICLE = 0x800,
TEXTURE_USAGE_SPRITE = 0x1000
TEXTURE_USAGE_REFECTION_CUBE = 0x08,
TEXTURE_USAGE_LIGHT_FLARE = 0x10,
TEXTURE_USAGE_SHADOW_DEPTH = 0x20,
TEXTURE_USAGE_PARTICLE = 0x40,
TEXTURE_USAGE_SPRITE = 0x80,
TEXTURE_USAGE_MATERIAL = 0x01000000,
TEXTURE_USAGE_MATERIAL_BASE_COLOR = TEXTURE_USAGE_MATERIAL | 0x00,
TEXTURE_USAGE_MATERIAL_NORMAL = TEXTURE_USAGE_MATERIAL | 0x01,
TEXTURE_USAGE_MATERIAL_EMISSIVE = TEXTURE_USAGE_MATERIAL | 0x02,
TEXTURE_USAGE_MATERIAL_OCCLUSION = TEXTURE_USAGE_MATERIAL | 0x04,
TEXTURE_USAGE_MATERIAL_METALIC_ROUGHNESS = TEXTURE_USAGE_MATERIAL | 0x08,
TEXTURE_USAGE_MATERIAL_ANISOTROPY = TEXTURE_USAGE_MATERIAL | 0x10,
TEXTURE_USAGE_MATERIAL_CLEARCOAT = TEXTURE_USAGE_MATERIAL | 0x20,
TEXTURE_USAGE_MATERIAL_CLEARCOAT_ROUGHNESS = TEXTURE_USAGE_MATERIAL | 0x40,
TEXTURE_USAGE_MATERIAL_CLEARCOAT_NORMAL = TEXTURE_USAGE_MATERIAL | 0x80,
TEXTURE_USAGE_MATERIAL_SPECULAR = TEXTURE_USAGE_MATERIAL | 0x100,
TEXTURE_USAGE_MATERIAL_SPECULAR_COLOR = TEXTURE_USAGE_MATERIAL | 0x200,
TEXTURE_USAGE_MATERIAL_THICKNESS = TEXTURE_USAGE_MATERIAL | 0x400,
} texture_usage_t;
float getStreamPriority();