diff --git a/kraken/KRContext.cpp b/kraken/KRContext.cpp index 5f29f7f..f678040 100755 --- a/kraken/KRContext.cpp +++ b/kraken/KRContext.cpp @@ -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) { diff --git a/kraken/KRPipeline.cpp b/kraken/KRPipeline.cpp index 075fc8b..39bccdf 100644 --- a/kraken/KRPipeline.cpp +++ b/kraken/KRPipeline.cpp @@ -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); diff --git a/kraken/KRShaderReflection.h b/kraken/KRShaderReflection.h index 262797e..82cb0b3 100644 --- a/kraken/KRShaderReflection.h +++ b/kraken/KRShaderReflection.h @@ -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, diff --git a/kraken/resources/material/KRMaterial.cpp b/kraken/resources/material/KRMaterial.cpp index 05c40ca..3aa898c 100755 --- a/kraken/resources/material/KRMaterial.cpp +++ b/kraken/resources/material/KRMaterial.cpp @@ -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::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& 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; diff --git a/kraken/resources/material/KRMaterial.h b/kraken/resources/material/KRMaterial.h index 1e32fc1..bc6136b 100755 --- a/kraken/resources/material/KRMaterial.h +++ b/kraken/resources/material/KRMaterial.h @@ -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& bones, const std::vector& 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& 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::max() }; + hydra::Vector3 m_attenuationColor{ 1.f, 1.f, 1.f }; private: bool getShaderValue(ShaderValue value, float* output) const final; diff --git a/kraken/resources/material/KRMaterialManager.cpp b/kraken/resources/material/KRMaterialManager.cpp index 36a21cc..c4c6cf4 100755 --- a/kraken/resources/material/KRMaterialManager.cpp +++ b/kraken/resources/material/KRMaterialManager.cpp @@ -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? } } } diff --git a/kraken/resources/material/KRMaterialManager.h b/kraken/resources/material/KRMaterialManager.h index 716f973..e1927d1 100755 --- a/kraken/resources/material/KRMaterialManager.h +++ b/kraken/resources/material/KRMaterialManager.h @@ -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); diff --git a/kraken/resources/mesh/KRMesh.cpp b/kraken/resources/mesh/KRMesh.cpp index b85ff0e..e3bac29 100755 --- a/kraken/resources/mesh/KRMesh.cpp +++ b/kraken/resources/mesh/KRMesh.cpp @@ -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; diff --git a/kraken/resources/texture/KRTexture.cpp b/kraken/resources/texture/KRTexture.cpp index 21fc0a0..79c82bd 100755 --- a/kraken/resources/texture/KRTexture.cpp +++ b/kraken/resources/texture/KRTexture.cpp @@ -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)) { diff --git a/kraken/resources/texture/KRTexture.h b/kraken/resources/texture/KRTexture.h index 9cea722..23cdd15 100755 --- a/kraken/resources/texture/KRTexture.h +++ b/kraken/resources/texture/KRTexture.h @@ -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();