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 // shader pre-processor options definition file
resource = m_pSourceManager->load(name, extension, data); resource = m_pSourceManager->load(name, extension, data);
} else if (extension.compare("mtl") == 0) { } 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) { } else if (extension.compare("mp3") == 0) {
resource = m_pSoundManager->load(name.c_str(), extension, data); resource = m_pSoundManager->load(name.c_str(), extension, data);
} else if (extension.compare("wav") == 0) { } 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::lightmaptexture, 5);
setPushConstant(ShaderValue::gbuffer_frame, 6); 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::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::depth_frame, 0);
setPushConstant(ShaderValue::render_frame, 1); setPushConstant(ShaderValue::render_frame, 1);
setPushConstant(ShaderValue::volumetric_environment_frame, 2); setPushConstant(ShaderValue::volumetric_environment_frame, 2);

View File

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

View File

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

View File

@@ -61,26 +61,31 @@ public:
{ {
KRMATERIAL_ALPHA_MODE_OPAQUE, // Non-transparent materials 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_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_BLEND // Blended alpha with backface culling
KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE // Blended alpha rendered in two passes. First pass renders backfaces; second pass renders frontfaces.
} alpha_mode_type; } alpha_mode_type;
struct TransformedTexture struct TransformedTexture
{ {
KRTextureBinding texture; KRTextureBinding texture;
int texCoord = 0; // uv texture index int texCoord{ 0 };
hydra::Vector2 scale{}; hydra::Vector2 scale{ 1.f, 1.f };
hydra::Vector2 offset{}; hydra::Vector2 offset{ 0.f, 0.f };
float rotation = 0; float rotation{ 0.f };
TransformedTexture(KRTexture::texture_usage_t usage)
: texture{ usage }
{
}
}; };
KRMaterial(KRContext& context, const char* szName); KRMaterial(KRContext& context, const char* szName);
KRMaterial(KRContext& context, std::string name, mimir::Block* data);
virtual ~KRMaterial(); virtual ~KRMaterial();
virtual std::string getExtension(); virtual std::string getExtension();
virtual bool save(mimir::Block& data); virtual bool save(mimir::Block& data);
/*
void setAmbientMap(std::string texture_name, hydra::Vector2 texture_scale, hydra::Vector2 texture_offset); 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 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); void setSpecularMap(std::string texture_name, hydra::Vector2 texture_scale, hydra::Vector2 texture_offset);
@@ -91,14 +96,15 @@ public:
void setDiffuse(const hydra::Vector3& c); void setDiffuse(const hydra::Vector3& c);
void setSpecular(const hydra::Vector3& c); void setSpecular(const hydra::Vector3& c);
void setReflection(const hydra::Vector3& c); void setReflection(const hydra::Vector3& c);
*/
void setTransparency(float a); void setTransparency(float a);
void setShininess(float s); void setShininess(float s);
void setAlphaMode(alpha_mode_type blend_mode); void setAlphaMode(alpha_mode_type blend_mode);
alpha_mode_type getAlphaMode(); alpha_mode_type getAlphaMode();
bool isTransparent(); bool isTransparent();
const std::string& getName() const;
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); 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);
@@ -108,29 +114,45 @@ public:
virtual void getResourceBindings(std::list<KRResourceBinding*>& bindings) override; virtual void getResourceBindings(std::list<KRResourceBinding*>& bindings) override;
private: // --- Serialized Material Attributes ---
std::string m_name; TransformedTexture m_baseColorTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_BASE_COLOR };
TransformedTexture m_ambient;// mtl map_Ka value hydra::Vector4 m_baseColorFactor{ 1.f, 1.f, 1.f, 1.f };
TransformedTexture m_diffuse; // mtl map_Kd value TransformedTexture m_normalTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_NORMAL };
TransformedTexture m_specular; // mtl map_Ks value float m_normalScale{ 1.f };
TransformedTexture m_reflection; // mtl refl value TransformedTexture m_emissiveTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_EMISSIVE };
KRTextureBinding m_reflectionCube; hydra::Vector3 m_emissiveFactor{ 0.f, 0.f, 0.f };
TransformedTexture m_normal; // mtl map_Normal value 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 TransformedTexture m_anisotropyTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_ANISOTROPY };
hydra::Vector3 m_diffuseColor; // Diffuse rgb float m_anisotropyStrength{ 0.f };
hydra::Vector3 m_specularColor; // Specular rgb float m_anisotropyRotation{ 0.f };
hydra::Vector3 m_reflectionColor; // Reflection rgb
//float m_ka_r, m_ka_g, m_ka_b; // Ambient rgb TransformedTexture m_clearcoatTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_CLEARCOAT };
//float m_kd_r, m_kd_g, m_kd_b; // Diffuse rgb float m_clearcoatFactor{ 0.f };
//float m_ks_r, m_ks_g, m_ks_b; // Specular rgb TransformedTexture m_clearcoatRoughnessTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_CLEARCOAT_ROUGHNESS };
//float m_kr_r, m_kr_g, m_kr_b; // Reflection rgb float m_clearcoatRoughnessFactor{ 0.f };
TransformedTexture m_clearcoatNormalTexture{ KRTexture::TEXTURE_USAGE_MATERIAL_CLEARCOAT_NORMAL };
float m_tr; // Transparency float m_dispersion{ 0.f };
float m_ns; // Shininess
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: private:
bool getShaderValue(ShaderValue value, float* output) const final; 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) KRResource* KRMaterialManager::loadResource(const std::string& name, const std::string& extension, Block* data)
{ {
if (extension.compare("mtl") == 0) { 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; return nullptr;
} }
KRResource* KRMaterialManager::getResource(const std::string& name, const std::string& extension) KRResource* KRMaterialManager::getResource(const std::string& name, const std::string& extension)
{ {
if (extension.compare("mtl") == 0) { if (extension.compare("krmaterial") == 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.
return m_materials[name]; return m_materials[name];
} }
return nullptr; return nullptr;
@@ -97,7 +99,7 @@ void KRMaterialManager::add(KRMaterial* new_material)
m_materials[lowerName] = new_material; m_materials[lowerName] = new_material;
} }
KRMaterial* KRMaterialManager::load(const char* szName, Block* data) KRMaterial* KRMaterialManager::loadMtl(Block* data)
{ {
KRMaterial* pMaterial = NULL; KRMaterial* pMaterial = NULL;
char szSymbol[16][256]; char szSymbol[16][256];
@@ -151,61 +153,65 @@ KRMaterial* KRMaterialManager::load(const char* szName, Block* data)
if (cSymbols == 2) { if (cSymbols == 2) {
if (strcmp(szSymbol[1], "test") == 0) { if (strcmp(szSymbol[1], "test") == 0) {
pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_TEST); pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_TEST);
pMaterial->m_doubleSided = false;
} else if (strcmp(szSymbol[1], "blendoneside") == 0) { } 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) { } 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 { } else {
pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE); pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE);
pMaterial->m_doubleSided = false;
} }
} }
} else if (strcmp(szSymbol[0], "ka") == 0) { } else if (strcmp(szSymbol[0], "ka") == 0) {
char* pScan2 = szSymbol[1]; char* pScan2 = szSymbol[1];
float r = strtof(pScan2, &pScan2); float r = strtof(pScan2, &pScan2);
if (cSymbols == 2) { 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) { } else if (cSymbols == 4) {
pScan2 = szSymbol[2]; pScan2 = szSymbol[2];
float g = strtof(pScan2, &pScan2); float g = strtof(pScan2, &pScan2);
pScan2 = szSymbol[3]; pScan2 = szSymbol[3];
float b = strtof(pScan2, &pScan2); 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) { } else if (strcmp(szSymbol[0], "kd") == 0) {
char* pScan2 = szSymbol[1]; char* pScan2 = szSymbol[1];
float r = strtof(pScan2, &pScan2); float r = strtof(pScan2, &pScan2);
if (cSymbols == 2) { if (cSymbols == 2) {
pMaterial->setDiffuse(Vector3::Create(r, r, r)); pMaterial->m_baseColorFactor = Vector4::Create(r, r, r, 1.f);
} else if (cSymbols == 4) { } else if (cSymbols == 4) {
pScan2 = szSymbol[2]; pScan2 = szSymbol[2];
float g = strtof(pScan2, &pScan2); float g = strtof(pScan2, &pScan2);
pScan2 = szSymbol[3]; pScan2 = szSymbol[3];
float b = strtof(pScan2, &pScan2); 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) { } else if (strcmp(szSymbol[0], "ks") == 0) {
char* pScan2 = szSymbol[1]; char* pScan2 = szSymbol[1];
float r = strtof(pScan2, &pScan2); float r = strtof(pScan2, &pScan2);
if (cSymbols == 2) { if (cSymbols == 2) {
pMaterial->setSpecular(Vector3::Create(r, r, r)); pMaterial->m_specularColorFactor = Vector3::Create(r, r, r);
} else if (cSymbols == 4) { } else if (cSymbols == 4) {
pScan2 = szSymbol[2]; pScan2 = szSymbol[2];
float g = strtof(pScan2, &pScan2); float g = strtof(pScan2, &pScan2);
pScan2 = szSymbol[3]; pScan2 = szSymbol[3];
float b = strtof(pScan2, &pScan2); 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) { } else if (strcmp(szSymbol[0], "kr") == 0) {
char* pScan2 = szSymbol[1]; char* pScan2 = szSymbol[1];
float r = strtof(pScan2, &pScan2); float r = strtof(pScan2, &pScan2);
if (cSymbols == 2) { if (cSymbols == 2) {
pMaterial->setReflection(Vector3::Create(r, r, r)); pMaterial->m_roughnessFactor = 1.f - r;
} else if (cSymbols == 4) { } else if (cSymbols == 4) {
pScan2 = szSymbol[2]; pScan2 = szSymbol[2];
float g = strtof(pScan2, &pScan2); float g = strtof(pScan2, &pScan2);
pScan2 = szSymbol[3]; pScan2 = szSymbol[3];
float b = strtof(pScan2, &pScan2); 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) { } else if (strcmp(szSymbol[0], "tr") == 0) {
char* pScan2 = szSymbol[1]; char* pScan2 = szSymbol[1];
@@ -265,17 +271,23 @@ KRMaterial* KRMaterialManager::load(const char* szName, Block* data)
} }
if (strcmp(szSymbol[0], "map_ka") == 0) { 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) { } 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) { } 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) { } 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) { } 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) { } 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* 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; 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); void add(KRMaterial* new_material);
KRMaterial* getMaterial(const std::string& name); 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); 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); renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage);
break; break;
case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE: // Blended alpha with backface culling case KRMaterial::KRMATERIAL_ALPHA_MODE_BLEND: // Blended Alpha
pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullBack, bones, bone_bind_poses, matModel, pLightMap, lod_coverage); if (pMaterial->m_doubleSided) {
renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage); // Blended alpha rendered in two passes. First pass renders backfaces; second pass renders frontfaces.
break; //
case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE: // Blended alpha rendered in two passes. First pass renders backfaces; second pass renders frontfaces. // Render back faces before front faces
// Render back faces first
pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullFront, bones, bone_bind_poses, matModel, pLightMap, lod_coverage); 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); 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); 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); renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage);
break; 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)) { if (m_last_frame_usage & (TEXTURE_USAGE_SKY_CUBE | TEXTURE_USAGE_PARTICLE | TEXTURE_USAGE_SPRITE | TEXTURE_USAGE_LIGHT_FLARE)) {
priority += 1000000.0f; 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; priority += 100000.0f;
} }
if (m_last_frame_usage & (TEXTURE_USAGE_LIGHT_MAP)) { if (m_last_frame_usage & (TEXTURE_USAGE_LIGHT_MAP)) {

View File

@@ -64,16 +64,28 @@ public:
TEXTURE_USAGE_UI = 0x01, TEXTURE_USAGE_UI = 0x01,
TEXTURE_USAGE_SKY_CUBE = 0x02, TEXTURE_USAGE_SKY_CUBE = 0x02,
TEXTURE_USAGE_LIGHT_MAP = 0x04, TEXTURE_USAGE_LIGHT_MAP = 0x04,
TEXTURE_USAGE_DIFFUSE_MAP = 0x08, TEXTURE_USAGE_REFECTION_CUBE = 0x08,
TEXTURE_USAGE_AMBIENT_MAP = 0x10, TEXTURE_USAGE_LIGHT_FLARE = 0x10,
TEXTURE_USAGE_SPECULAR_MAP = 0x20, TEXTURE_USAGE_SHADOW_DEPTH = 0x20,
TEXTURE_USAGE_NORMAL_MAP = 0x40, TEXTURE_USAGE_PARTICLE = 0x40,
TEXTURE_USAGE_REFLECTION_MAP = 0x80, TEXTURE_USAGE_SPRITE = 0x80,
TEXTURE_USAGE_REFECTION_CUBE = 0x100,
TEXTURE_USAGE_LIGHT_FLARE = 0x200, TEXTURE_USAGE_MATERIAL = 0x01000000,
TEXTURE_USAGE_SHADOW_DEPTH = 0x400,
TEXTURE_USAGE_PARTICLE = 0x800, TEXTURE_USAGE_MATERIAL_BASE_COLOR = TEXTURE_USAGE_MATERIAL | 0x00,
TEXTURE_USAGE_SPRITE = 0x1000 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; } texture_usage_t;
float getStreamPriority(); float getStreamPriority();