mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 18:42:58 +02:00
wip
This commit is contained in:
parent
1a62b59a8f
commit
a9d798070a
12 changed files with 231 additions and 208 deletions
|
@ -42,10 +42,23 @@ ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Pare
|
||||||
// TODO: move into Procedural.cpp
|
// TODO: move into Procedural.cpp
|
||||||
PrepareStencil::testMaskDrawShape(*_procedural._opaqueState);
|
PrepareStencil::testMaskDrawShape(*_procedural._opaqueState);
|
||||||
PrepareStencil::testMask(*_procedural._transparentState);
|
PrepareStencil::testMask(*_procedural._transparentState);
|
||||||
|
|
||||||
|
addMaterial(graphics::MaterialLayer(_material, 0), "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShapeEntityRenderer::needsRenderUpdate() const {
|
bool ShapeEntityRenderer::needsRenderUpdate() const {
|
||||||
if (_procedural.isEnabled() && _procedural.isFading()) {
|
if (resultWithReadLock<bool>([&] {
|
||||||
|
if (_procedural.isEnabled() && _procedural.isFading()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mat = _materials.find("0");
|
||||||
|
if (mat != _materials.end() && mat->second.needsUpdate()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
})) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +69,11 @@ bool ShapeEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin
|
||||||
if (_lastUserData != entity->getUserData()) {
|
if (_lastUserData != entity->getUserData()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (_material != entity->getMaterial()) {
|
|
||||||
|
if (_color != entity->getColor()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (_alpha != entity->getAlpha()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,10 +96,6 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
||||||
_procedural.setProceduralData(ProceduralData::parse(_lastUserData));
|
_procedural.setProceduralData(ProceduralData::parse(_lastUserData));
|
||||||
}
|
}
|
||||||
|
|
||||||
removeMaterial(_material, "0");
|
|
||||||
_material = entity->getMaterial();
|
|
||||||
addMaterial(graphics::MaterialLayer(_material, 0), "0");
|
|
||||||
|
|
||||||
_shape = entity->getShape();
|
_shape = entity->getShape();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -111,6 +124,15 @@ void ShapeEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint
|
||||||
_procedural.setIsFading(isFading);
|
_procedural.setIsFading(isFading);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_color = entity->getColor();
|
||||||
|
_alpha = entity->getAlpha();
|
||||||
|
_material->setAlbedo(toGlm(_color));
|
||||||
|
_material->setOpacity(_alpha);
|
||||||
|
auto materials = _materials.find("0");
|
||||||
|
if (materials != _materials.end()) {
|
||||||
|
materials->second.setNeedsUpdate(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShapeEntityRenderer::isTransparent() const {
|
bool ShapeEntityRenderer::isTransparent() const {
|
||||||
|
@ -120,11 +142,8 @@ bool ShapeEntityRenderer::isTransparent() const {
|
||||||
|
|
||||||
auto mat = _materials.find("0");
|
auto mat = _materials.find("0");
|
||||||
if (mat != _materials.end()) {
|
if (mat != _materials.end()) {
|
||||||
if (mat->second.top().material) {
|
if (mat->second.getMaterialKey().isTranslucent()) {
|
||||||
auto matKey = mat->second.top().material->getKey();
|
return true;
|
||||||
if (matKey.isTranslucent()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +165,7 @@ ItemKey ShapeEntityRenderer::getKey() {
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShapeEntityRenderer::useMaterialPipeline() const {
|
bool ShapeEntityRenderer::useMaterialPipeline(const graphics::MultiMaterial& materials) const {
|
||||||
bool proceduralReady = resultWithReadLock<bool>([&] {
|
bool proceduralReady = resultWithReadLock<bool>([&] {
|
||||||
return _procedural.isReady();
|
return _procedural.isReady();
|
||||||
});
|
});
|
||||||
|
@ -154,12 +173,7 @@ bool ShapeEntityRenderer::useMaterialPipeline() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics::MaterialKey drawMaterialKey;
|
graphics::MaterialKey drawMaterialKey = materials.getMaterialKey();
|
||||||
auto mat = _materials.find("0");
|
|
||||||
if (mat != _materials.end() && mat->second.top().material) {
|
|
||||||
drawMaterialKey = mat->second.top().material->getKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (drawMaterialKey.isEmissive() || drawMaterialKey.isUnlit() || drawMaterialKey.isMetallic() || drawMaterialKey.isScattering()) {
|
if (drawMaterialKey.isEmissive() || drawMaterialKey.isUnlit() || drawMaterialKey.isMetallic() || drawMaterialKey.isScattering()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -174,11 +188,13 @@ bool ShapeEntityRenderer::useMaterialPipeline() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeKey ShapeEntityRenderer::getShapeKey() {
|
ShapeKey ShapeEntityRenderer::getShapeKey() {
|
||||||
if (useMaterialPipeline()) {
|
auto mat = _materials.find("0");
|
||||||
graphics::MaterialKey drawMaterialKey;
|
if (mat != _materials.end() && mat->second.needsUpdate()) {
|
||||||
if (_materials["0"].top().material) {
|
RenderPipelines::updateMultiMaterial(mat->second);
|
||||||
drawMaterialKey = _materials["0"].top().material->getKey();
|
}
|
||||||
}
|
|
||||||
|
if (mat != _materials.end() && useMaterialPipeline(mat->second)) {
|
||||||
|
graphics::MaterialKey drawMaterialKey = mat->second.getMaterialKey();
|
||||||
|
|
||||||
bool isTranslucent = drawMaterialKey.isTranslucent();
|
bool isTranslucent = drawMaterialKey.isTranslucent();
|
||||||
bool hasTangents = drawMaterialKey.isNormalMap();
|
bool hasTangents = drawMaterialKey.isNormalMap();
|
||||||
|
@ -232,16 +248,13 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
||||||
geometryShape = geometryCache->getShapeForEntityShape(_shape);
|
geometryShape = geometryCache->getShapeForEntityShape(_shape);
|
||||||
batch.setModelTransform(_renderTransform); // use a transform with scale, rotation, registration point and translation
|
batch.setModelTransform(_renderTransform); // use a transform with scale, rotation, registration point and translation
|
||||||
materials = _materials["0"];
|
materials = _materials["0"];
|
||||||
auto topMat = materials.top().material;
|
auto& schema = materials.getSchemaBuffer().get<graphics::MultiMaterial::Schema>();
|
||||||
if (topMat) {
|
outColor = glm::vec4(schema._albedo, schema._opacity);
|
||||||
// FIXME: fallthrough to get proper albedo and opacity?
|
if (_procedural.isReady()) {
|
||||||
outColor = glm::vec4(topMat->getAlbedo(), topMat->getOpacity());
|
outColor = _procedural.getColor(outColor);
|
||||||
if (_procedural.isReady()) {
|
outColor.a *= _procedural.isFading() ? Interpolate::calculateFadeRatio(_procedural.getFadeStartTime()) : 1.0f;
|
||||||
outColor = _procedural.getColor(outColor);
|
_procedural.prepare(batch, _position, _dimensions, _orientation, ProceduralProgramKey(outColor.a < 1.0f));
|
||||||
outColor.a *= _procedural.isFading() ? Interpolate::calculateFadeRatio(_procedural.getFadeStartTime()) : 1.0f;
|
proceduralRender = true;
|
||||||
_procedural.prepare(batch, _position, _dimensions, _orientation, ProceduralProgramKey(outColor.a < 1.0f));
|
|
||||||
proceduralRender = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -251,7 +264,7 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
||||||
} else {
|
} else {
|
||||||
geometryCache->renderShape(batch, geometryShape, outColor);
|
geometryCache->renderShape(batch, geometryShape, outColor);
|
||||||
}
|
}
|
||||||
} else if (!useMaterialPipeline()) {
|
} else if (!useMaterialPipeline(materials)) {
|
||||||
// FIXME, support instanced multi-shape rendering using multidraw indirect
|
// FIXME, support instanced multi-shape rendering using multidraw indirect
|
||||||
outColor.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
outColor.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
||||||
auto pipeline = outColor.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline();
|
auto pipeline = outColor.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline();
|
||||||
|
@ -281,8 +294,9 @@ scriptable::ScriptableModelBase ShapeEntityRenderer::getScriptableModel() {
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_materialsLock);
|
std::lock_guard<std::mutex> lock(_materialsLock);
|
||||||
result.appendMaterials(_materials);
|
result.appendMaterials(_materials);
|
||||||
if (_materials["0"].top().material) {
|
auto& materials = _materials.find("0");
|
||||||
vertexColor = _materials["0"].top().material->getAlbedo();
|
if (materials != _materials.end()) {
|
||||||
|
vertexColor = materials->second.getSchemaBuffer().get<graphics::MultiMaterial::Schema>()._albedo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (auto mesh = geometryCache->meshFromShape(geometryShape, vertexColor)) {
|
if (auto mesh = geometryCache->meshFromShape(geometryShape, vertexColor)) {
|
||||||
|
|
|
@ -36,12 +36,14 @@ private:
|
||||||
virtual void doRender(RenderArgs* args) override;
|
virtual void doRender(RenderArgs* args) override;
|
||||||
virtual bool isTransparent() const override;
|
virtual bool isTransparent() const override;
|
||||||
|
|
||||||
bool useMaterialPipeline() const;
|
bool useMaterialPipeline(const graphics::MultiMaterial& materials) const;
|
||||||
|
|
||||||
Procedural _procedural;
|
Procedural _procedural;
|
||||||
QString _lastUserData;
|
QString _lastUserData;
|
||||||
entity::Shape _shape { entity::Sphere };
|
entity::Shape _shape { entity::Sphere };
|
||||||
std::shared_ptr<graphics::Material> _material;
|
std::shared_ptr<graphics::Material> _material { std::make_shared<graphics::Material>() };
|
||||||
|
glm::u8vec3 _color;
|
||||||
|
float _alpha;
|
||||||
glm::vec3 _position;
|
glm::vec3 _position;
|
||||||
glm::vec3 _dimensions;
|
glm::vec3 _dimensions;
|
||||||
glm::quat _orientation;
|
glm::quat _orientation;
|
||||||
|
|
|
@ -112,7 +112,6 @@ EntityItemPointer ShapeEntityItem::sphereFactory(const EntityItemID& entityID, c
|
||||||
ShapeEntityItem::ShapeEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) {
|
ShapeEntityItem::ShapeEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) {
|
||||||
_type = EntityTypes::Shape;
|
_type = EntityTypes::Shape;
|
||||||
_volumeMultiplier *= PI / 6.0f;
|
_volumeMultiplier *= PI / 6.0f;
|
||||||
_material = std::make_shared<graphics::Material>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties ShapeEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
EntityItemProperties ShapeEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
|
@ -215,7 +214,6 @@ void ShapeEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit
|
||||||
void ShapeEntityItem::setColor(const glm::u8vec3& value) {
|
void ShapeEntityItem::setColor(const glm::u8vec3& value) {
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
_color = value;
|
_color = value;
|
||||||
_material->setAlbedo(toGlm(_color));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +226,6 @@ glm::u8vec3 ShapeEntityItem::getColor() const {
|
||||||
void ShapeEntityItem::setAlpha(float alpha) {
|
void ShapeEntityItem::setAlpha(float alpha) {
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
_alpha = alpha;
|
_alpha = alpha;
|
||||||
_material->setOpacity(alpha);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,8 +99,6 @@ public:
|
||||||
virtual void computeShapeInfo(ShapeInfo& info) override;
|
virtual void computeShapeInfo(ShapeInfo& info) override;
|
||||||
virtual ShapeType getShapeType() const override;
|
virtual ShapeType getShapeType() const override;
|
||||||
|
|
||||||
std::shared_ptr<graphics::Material> getMaterial() { return _material; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
float _alpha { 1.0f };
|
float _alpha { 1.0f };
|
||||||
|
@ -111,8 +109,6 @@ protected:
|
||||||
//! prior functionality where new or unsupported shapes are treated as
|
//! prior functionality where new or unsupported shapes are treated as
|
||||||
//! ellipsoids.
|
//! ellipsoids.
|
||||||
ShapeType _collisionShapeType{ ShapeType::SHAPE_TYPE_ELLIPSOID };
|
ShapeType _collisionShapeType{ ShapeType::SHAPE_TYPE_ELLIPSOID };
|
||||||
|
|
||||||
std::shared_ptr<graphics::Material> _material;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_ShapeEntityItem_h
|
#endif // hifi_ShapeEntityItem_h
|
||||||
|
|
|
@ -380,22 +380,28 @@ namespace scriptable {
|
||||||
obj.setProperty("scatteringMap", material.propertyFallthroughs.at(graphics::MaterialKey::SCATTERING_MAP_BIT) ? FALLTHROUGH : material.scatteringMap);
|
obj.setProperty("scatteringMap", material.propertyFallthroughs.at(graphics::MaterialKey::SCATTERING_MAP_BIT) ? FALLTHROUGH : material.scatteringMap);
|
||||||
|
|
||||||
// Only set one of each of these
|
// Only set one of each of these
|
||||||
if (!material.metallicMap.isEmpty()) {
|
if (material.propertyFallthroughs.at(graphics::MaterialKey::METALLIC_MAP_BIT)) {
|
||||||
obj.setProperty("metallicMap", material.propertyFallthroughs.at(graphics::MaterialKey::METALLIC_MAP_BIT) ? FALLTHROUGH : material.metallicMap);
|
obj.setProperty("metallicMap", FALLTHROUGH);
|
||||||
} else {
|
} else if (!material.metallicMap.isEmpty()) {
|
||||||
obj.setProperty("specularMap", material.propertyFallthroughs.at(graphics::MaterialKey::METALLIC_MAP_BIT) ? FALLTHROUGH : material.specularMap);
|
obj.setProperty("metallicMap", material.metallicMap);
|
||||||
|
} else if (!material.specularMap.isEmpty()) {
|
||||||
|
obj.setProperty("specularMap", material.specularMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!material.roughnessMap.isEmpty()) {
|
if (material.propertyFallthroughs.at(graphics::MaterialKey::ROUGHNESS_MAP_BIT)) {
|
||||||
obj.setProperty("roughnessMap", material.propertyFallthroughs.at(graphics::MaterialKey::ROUGHNESS_MAP_BIT) ? FALLTHROUGH : material.roughnessMap);
|
obj.setProperty("roughnessMap", FALLTHROUGH);
|
||||||
} else {
|
} else if (!material.roughnessMap.isEmpty()) {
|
||||||
obj.setProperty("glossMap", material.propertyFallthroughs.at(graphics::MaterialKey::ROUGHNESS_MAP_BIT) ? FALLTHROUGH : material.glossMap);
|
obj.setProperty("roughnessMap", material.roughnessMap);
|
||||||
|
} else if (!material.glossMap.isEmpty()) {
|
||||||
|
obj.setProperty("glossMap", material.glossMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!material.normalMap.isEmpty()) {
|
if (material.propertyFallthroughs.at(graphics::MaterialKey::NORMAL_MAP_BIT)) {
|
||||||
obj.setProperty("normalMap", material.propertyFallthroughs.at(graphics::MaterialKey::NORMAL_MAP_BIT) ? FALLTHROUGH : material.normalMap);
|
obj.setProperty("normalMap", FALLTHROUGH);
|
||||||
} else {
|
} else if (!material.normalMap.isEmpty()) {
|
||||||
obj.setProperty("bumpMap", material.propertyFallthroughs.at(graphics::MaterialKey::NORMAL_MAP_BIT) ? FALLTHROUGH : material.bumpMap);
|
obj.setProperty("normalMap", material.normalMap);
|
||||||
|
} else if (!material.bumpMap.isEmpty()) {
|
||||||
|
obj.setProperty("bumpMap", material.bumpMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.setProperty("defaultFallthrough", material.defaultFallthrough);
|
obj.setProperty("defaultFallthrough", material.defaultFallthrough);
|
||||||
|
|
|
@ -119,7 +119,6 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur
|
||||||
_key.setMapChannel(channel, false);
|
_key.setMapChannel(channel, false);
|
||||||
_textureMaps.erase(channel);
|
_textureMaps.erase(channel);
|
||||||
}
|
}
|
||||||
_hasCalculatedTextureInfo = false;
|
|
||||||
|
|
||||||
if (channel == MaterialKey::ALBEDO_MAP) {
|
if (channel == MaterialKey::ALBEDO_MAP) {
|
||||||
resetOpacityMap();
|
resetOpacityMap();
|
||||||
|
@ -177,39 +176,6 @@ const TextureMapPointer Material::getTextureMap(MapChannel channel) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Material::calculateMaterialInfo() const {
|
|
||||||
if (!_hasCalculatedTextureInfo) {
|
|
||||||
QMutexLocker locker(&_textureMapsMutex);
|
|
||||||
|
|
||||||
bool allTextures = true; // assume we got this...
|
|
||||||
_textureSize = 0;
|
|
||||||
_textureCount = 0;
|
|
||||||
|
|
||||||
for (auto const &textureMapItem : _textureMaps) {
|
|
||||||
auto textureMap = textureMapItem.second;
|
|
||||||
if (textureMap) {
|
|
||||||
auto textureSoure = textureMap->getTextureSource();
|
|
||||||
if (textureSoure) {
|
|
||||||
auto texture = textureSoure->getGPUTexture();
|
|
||||||
if (texture) {
|
|
||||||
auto size = texture->getSize();
|
|
||||||
_textureSize += size;
|
|
||||||
_textureCount++;
|
|
||||||
} else {
|
|
||||||
allTextures = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
allTextures = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
allTextures = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_hasCalculatedTextureInfo = allTextures;
|
|
||||||
}
|
|
||||||
return _hasCalculatedTextureInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Material::setTextureTransforms(const Transform& transform, MaterialMappingMode mode, bool repeat) {
|
void Material::setTextureTransforms(const Transform& transform, MaterialMappingMode mode, bool repeat) {
|
||||||
for (auto &textureMapItem : _textureMaps) {
|
for (auto &textureMapItem : _textureMaps) {
|
||||||
if (textureMapItem.second) {
|
if (textureMapItem.second) {
|
||||||
|
@ -227,4 +193,24 @@ void Material::setTextureTransforms(const Transform& transform, MaterialMappingM
|
||||||
MultiMaterial::MultiMaterial() {
|
MultiMaterial::MultiMaterial() {
|
||||||
Schema schema;
|
Schema schema;
|
||||||
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema, sizeof(Schema)));
|
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema, sizeof(Schema)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MultiMaterial::calculateMaterialInfo() const {
|
||||||
|
if (!_hasCalculatedTextureInfo) {
|
||||||
|
bool allTextures = true; // assume we got this...
|
||||||
|
_textureSize = 0;
|
||||||
|
_textureCount = 0;
|
||||||
|
|
||||||
|
auto& textures = _textureTable->getTextures();
|
||||||
|
for (auto const &texture : textures) {
|
||||||
|
if (texture && texture->isDefined()) {
|
||||||
|
auto size = texture->getSize();
|
||||||
|
_textureSize += size;
|
||||||
|
_textureCount++;
|
||||||
|
} else {
|
||||||
|
allTextures = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_hasCalculatedTextureInfo = allTextures;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -315,10 +315,6 @@ public:
|
||||||
// conversion from legacy material properties to PBR equivalent
|
// conversion from legacy material properties to PBR equivalent
|
||||||
static float shininessToRoughness(float shininess) { return 1.0f - shininess / 100.0f; }
|
static float shininessToRoughness(float shininess) { return 1.0f - shininess / 100.0f; }
|
||||||
|
|
||||||
int getTextureCount() const { calculateMaterialInfo(); return _textureCount; }
|
|
||||||
size_t getTextureSize() const { calculateMaterialInfo(); return _textureSize; }
|
|
||||||
bool hasTextureInfo() const { return _hasCalculatedTextureInfo; }
|
|
||||||
|
|
||||||
void setTextureTransforms(const Transform& transform, MaterialMappingMode mode, bool repeat);
|
void setTextureTransforms(const Transform& transform, MaterialMappingMode mode, bool repeat);
|
||||||
|
|
||||||
const std::string& getName() const { return _name; }
|
const std::string& getName() const { return _name; }
|
||||||
|
@ -355,14 +351,10 @@ private:
|
||||||
std::unordered_map<MaterialKey::FlagBit, bool> _propertyFallthroughs;
|
std::unordered_map<MaterialKey::FlagBit, bool> _propertyFallthroughs;
|
||||||
|
|
||||||
mutable QMutex _textureMapsMutex { QMutex::Recursive };
|
mutable QMutex _textureMapsMutex { QMutex::Recursive };
|
||||||
mutable size_t _textureSize { 0 };
|
|
||||||
mutable int _textureCount { 0 };
|
|
||||||
mutable bool _hasCalculatedTextureInfo { false };
|
|
||||||
bool calculateMaterialInfo() const;
|
|
||||||
|
|
||||||
std::string _model { "hifi_pbr" };
|
std::string _model { "hifi_pbr" };
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr< Material > MaterialPointer;
|
typedef std::shared_ptr<Material> MaterialPointer;
|
||||||
|
|
||||||
class MaterialLayer {
|
class MaterialLayer {
|
||||||
public:
|
public:
|
||||||
|
@ -378,11 +370,18 @@ public:
|
||||||
return left.priority < right.priority;
|
return left.priority < right.priority;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
typedef std::priority_queue<MaterialLayer, std::vector<MaterialLayer>, MaterialLayerCompare> MaterialLayerQueue;
|
||||||
|
|
||||||
class MultiMaterial : public std::priority_queue<MaterialLayer, std::vector<MaterialLayer>, MaterialLayerCompare> {
|
class MultiMaterial : public MaterialLayerQueue {
|
||||||
public:
|
public:
|
||||||
MultiMaterial();
|
MultiMaterial();
|
||||||
|
|
||||||
|
void push(const MaterialLayer& value) {
|
||||||
|
MaterialLayerQueue::push(value);
|
||||||
|
_hasCalculatedTextureInfo = false;
|
||||||
|
_needsUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool remove(const MaterialPointer& value) {
|
bool remove(const MaterialPointer& value) {
|
||||||
auto it = c.begin();
|
auto it = c.begin();
|
||||||
while (it != c.end()) {
|
while (it != c.end()) {
|
||||||
|
@ -394,6 +393,8 @@ public:
|
||||||
if (it != c.end()) {
|
if (it != c.end()) {
|
||||||
c.erase(it);
|
c.erase(it);
|
||||||
std::make_heap(c.begin(), c.end(), comp);
|
std::make_heap(c.begin(), c.end(), comp);
|
||||||
|
_hasCalculatedTextureInfo = false;
|
||||||
|
_needsUpdate = true;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -437,11 +438,25 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
gpu::BufferView& getSchemaBuffer() { return _schemaBuffer; }
|
gpu::BufferView& getSchemaBuffer() { return _schemaBuffer; }
|
||||||
|
graphics::MaterialKey getMaterialKey() const { return graphics::MaterialKey(_schemaBuffer.get<graphics::MultiMaterial::Schema>()._key); }
|
||||||
const gpu::TextureTablePointer& getTextureTable() const { return _textureTable; }
|
const gpu::TextureTablePointer& getTextureTable() const { return _textureTable; }
|
||||||
|
|
||||||
|
bool needsUpdate() const { return _needsUpdate; }
|
||||||
|
void setNeedsUpdate(bool needsUpdate) { _needsUpdate = needsUpdate; }
|
||||||
|
|
||||||
|
int getTextureCount() const { calculateMaterialInfo(); return _textureCount; }
|
||||||
|
size_t getTextureSize() const { calculateMaterialInfo(); return _textureSize; }
|
||||||
|
bool hasTextureInfo() const { return _hasCalculatedTextureInfo; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gpu::BufferView _schemaBuffer;
|
gpu::BufferView _schemaBuffer;
|
||||||
gpu::TextureTablePointer _textureTable { std::make_shared<gpu::TextureTable>() };
|
gpu::TextureTablePointer _textureTable { std::make_shared<gpu::TextureTable>() };
|
||||||
|
bool _needsUpdate { false };
|
||||||
|
|
||||||
|
mutable size_t _textureSize { 0 };
|
||||||
|
mutable int _textureCount { 0 };
|
||||||
|
mutable bool _hasCalculatedTextureInfo { false };
|
||||||
|
void calculateMaterialInfo() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -160,13 +160,16 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater
|
||||||
std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource::parseJSONMaterial(const QJsonObject& materialJSON, const QUrl& baseUrl) {
|
std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource::parseJSONMaterial(const QJsonObject& materialJSON, const QUrl& baseUrl) {
|
||||||
std::string name = "";
|
std::string name = "";
|
||||||
std::shared_ptr<NetworkMaterial> material = std::make_shared<NetworkMaterial>();
|
std::shared_ptr<NetworkMaterial> material = std::make_shared<NetworkMaterial>();
|
||||||
std::string modelString = "hifi_pbr";
|
|
||||||
auto modelJSON = materialJSON.value("model");
|
const std::string HIFI_PBR = "hifi_pbr";
|
||||||
if (modelJSON.isString()) {
|
std::string modelString = HIFI_PBR;
|
||||||
modelString = modelJSON.toString().toStdString();
|
auto modelJSONIter = materialJSON.find("model");
|
||||||
|
if (modelJSONIter != materialJSON.end() && modelJSONIter.value().isString()) {
|
||||||
|
modelString = modelJSONIter.value().toString().toStdString();
|
||||||
material->setModel(modelString);
|
material->setModel(modelString);
|
||||||
}
|
}
|
||||||
if (modelString == "hifi_pbr") {
|
|
||||||
|
if (modelString == HIFI_PBR) {
|
||||||
const QString FALLTHROUGH("fallthrough");
|
const QString FALLTHROUGH("fallthrough");
|
||||||
for (auto& key : materialJSON.keys()) {
|
for (auto& key : materialJSON.keys()) {
|
||||||
if (key == "name") {
|
if (key == "name") {
|
||||||
|
|
|
@ -83,11 +83,13 @@ void MeshPartPayload::updateKey(const render::ItemKey& key) {
|
||||||
ItemKey::Builder builder(key);
|
ItemKey::Builder builder(key);
|
||||||
builder.withTypeShape();
|
builder.withTypeShape();
|
||||||
|
|
||||||
if (topMaterialExists()) {
|
if (_drawMaterials.needsUpdate()) {
|
||||||
auto matKey = _drawMaterials.top().material->getKey();
|
RenderPipelines::updateMultiMaterial(_drawMaterials);
|
||||||
if (matKey.isTranslucent()) {
|
}
|
||||||
builder.withTransparent();
|
|
||||||
}
|
auto matKey = _drawMaterials.getMaterialKey();
|
||||||
|
if (matKey.isTranslucent()) {
|
||||||
|
builder.withTransparent();
|
||||||
}
|
}
|
||||||
|
|
||||||
_itemKey = builder.build();
|
_itemKey = builder.build();
|
||||||
|
@ -102,10 +104,7 @@ Item::Bound MeshPartPayload::getBound() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeKey MeshPartPayload::getShapeKey() const {
|
ShapeKey MeshPartPayload::getShapeKey() const {
|
||||||
graphics::MaterialKey drawMaterialKey;
|
graphics::MaterialKey drawMaterialKey = _drawMaterials.getMaterialKey();
|
||||||
if (topMaterialExists()) {
|
|
||||||
drawMaterialKey = _drawMaterials.top().material->getKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShapeKey::Builder builder;
|
ShapeKey::Builder builder;
|
||||||
builder.withMaterial();
|
builder.withMaterial();
|
||||||
|
@ -330,11 +329,13 @@ void ModelMeshPartPayload::updateKey(const render::ItemKey& key) {
|
||||||
builder.withDeformed();
|
builder.withDeformed();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topMaterialExists()) {
|
if (_drawMaterials.needsUpdate()) {
|
||||||
auto matKey = _drawMaterials.top().material->getKey();
|
RenderPipelines::updateMultiMaterial(_drawMaterials);
|
||||||
if (matKey.isTranslucent()) {
|
}
|
||||||
builder.withTransparent();
|
|
||||||
}
|
auto matKey = _drawMaterials.getMaterialKey();
|
||||||
|
if (matKey.isTranslucent()) {
|
||||||
|
builder.withTransparent();
|
||||||
}
|
}
|
||||||
|
|
||||||
_itemKey = builder.build();
|
_itemKey = builder.build();
|
||||||
|
@ -346,10 +347,7 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, bool isWireframe
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics::MaterialKey drawMaterialKey;
|
graphics::MaterialKey drawMaterialKey = _drawMaterials.getMaterialKey();
|
||||||
if (topMaterialExists()) {
|
|
||||||
drawMaterialKey = _drawMaterials.top().material->getKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isTranslucent = drawMaterialKey.isTranslucent();
|
bool isTranslucent = drawMaterialKey.isTranslucent();
|
||||||
bool hasTangents = drawMaterialKey.isNormalMap() && _hasTangents;
|
bool hasTangents = drawMaterialKey.isNormalMap() && _hasTangents;
|
||||||
|
|
|
@ -66,17 +66,15 @@ public:
|
||||||
graphics::Mesh::Part _drawPart;
|
graphics::Mesh::Part _drawPart;
|
||||||
|
|
||||||
size_t getVerticesCount() const { return _drawMesh ? _drawMesh->getNumVertices() : 0; }
|
size_t getVerticesCount() const { return _drawMesh ? _drawMesh->getNumVertices() : 0; }
|
||||||
size_t getMaterialTextureSize() { return topMaterialExists() ? _drawMaterials.top().material->getTextureSize() : 0; }
|
size_t getMaterialTextureSize() { return _drawMaterials.getTextureSize(); }
|
||||||
int getMaterialTextureCount() { return topMaterialExists() ? _drawMaterials.top().material->getTextureCount() : 0; }
|
int getMaterialTextureCount() { return _drawMaterials.getTextureCount(); }
|
||||||
bool hasTextureInfo() const { return topMaterialExists() ? _drawMaterials.top().material->hasTextureInfo() : false; }
|
bool hasTextureInfo() const { return _drawMaterials.hasTextureInfo(); }
|
||||||
|
|
||||||
void addMaterial(graphics::MaterialLayer material);
|
void addMaterial(graphics::MaterialLayer material);
|
||||||
void removeMaterial(graphics::MaterialPointer material);
|
void removeMaterial(graphics::MaterialPointer material);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
render::ItemKey _itemKey{ render::ItemKey::Builder::opaqueShape().build() };
|
render::ItemKey _itemKey{ render::ItemKey::Builder::opaqueShape().build() };
|
||||||
|
|
||||||
bool topMaterialExists() const { return !_drawMaterials.empty() && _drawMaterials.top().material; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
|
@ -376,23 +376,25 @@ void initZPassPipelines(ShapePlumber& shapePlumber, gpu::StatePointer state, con
|
||||||
void RenderPipelines::bindMaterial(graphics::MaterialPointer& material, gpu::Batch& batch, bool enableTextures) {
|
void RenderPipelines::bindMaterial(graphics::MaterialPointer& material, gpu::Batch& batch, bool enableTextures) {
|
||||||
graphics::MultiMaterial multiMaterial;
|
graphics::MultiMaterial multiMaterial;
|
||||||
multiMaterial.push(graphics::MaterialLayer(material, 0));
|
multiMaterial.push(graphics::MaterialLayer(material, 0));
|
||||||
|
updateMultiMaterial(multiMaterial);
|
||||||
bindMaterials(multiMaterial, batch, enableTextures);
|
bindMaterials(multiMaterial, batch, enableTextures);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME find a better way to setup the default textures
|
void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial) {
|
||||||
void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, bool enableTextures) {
|
auto& schemaBuffer = multiMaterial.getSchemaBuffer();
|
||||||
|
|
||||||
if (multiMaterial.size() == 0) {
|
if (multiMaterial.size() == 0) {
|
||||||
|
schemaBuffer.edit<graphics::MultiMaterial::Schema>() = graphics::MultiMaterial::Schema();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto textureCache = DependencyManager::get<TextureCache>();
|
auto textureCache = DependencyManager::get<TextureCache>();
|
||||||
auto& drawMaterialTextures = multiMaterial.getTextureTable();
|
auto& drawMaterialTextures = multiMaterial.getTextureTable();
|
||||||
auto& schemaBuffer = multiMaterial.getSchemaBuffer();
|
|
||||||
|
|
||||||
// The total list of things we need to look for
|
// The total list of things we need to look for
|
||||||
static std::set<graphics::MaterialKey::FlagBit> allFlagBits;
|
static std::set<graphics::MaterialKey::FlagBit> allFlagBits;
|
||||||
static std::once_flag once;
|
static std::once_flag once;
|
||||||
std::call_once(once, [] {
|
std::call_once(once, [textureCache] {
|
||||||
for (int i = 0; i < graphics::MaterialKey::NUM_FLAGS; i++) {
|
for (int i = 0; i < graphics::MaterialKey::NUM_FLAGS; i++) {
|
||||||
auto flagBit = graphics::MaterialKey::FlagBit(i);
|
auto flagBit = graphics::MaterialKey::FlagBit(i);
|
||||||
// The opacity mask/map are derived from the albedo map
|
// The opacity mask/map are derived from the albedo map
|
||||||
|
@ -472,16 +474,12 @@ void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu:
|
||||||
break;
|
break;
|
||||||
case graphics::MaterialKey::ALBEDO_MAP_BIT:
|
case graphics::MaterialKey::ALBEDO_MAP_BIT:
|
||||||
if (materialKey.isAlbedoMap()) {
|
if (materialKey.isAlbedoMap()) {
|
||||||
if (!enableTextures) {
|
auto itr = textureMaps.find(graphics::MaterialKey::ALBEDO_MAP);
|
||||||
forceDefault = true;
|
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||||
|
drawMaterialTextures->setTexture(gr::Texture::MaterialAlbedo, itr->second->getTextureView());
|
||||||
|
wasSet = true;
|
||||||
} else {
|
} else {
|
||||||
auto itr = textureMaps.find(graphics::MaterialKey::ALBEDO_MAP);
|
forceDefault = true;
|
||||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
|
||||||
drawMaterialTextures->setTexture(gr::Texture::MaterialAlbedo, itr->second->getTextureView());
|
|
||||||
wasSet = true;
|
|
||||||
} else {
|
|
||||||
forceDefault = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
schemaKey.setAlbedoMap(true);
|
schemaKey.setAlbedoMap(true);
|
||||||
schemaKey.setOpacityMaskMap(materialKey.isOpacityMaskMap());
|
schemaKey.setOpacityMaskMap(materialKey.isOpacityMaskMap());
|
||||||
|
@ -490,80 +488,60 @@ void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu:
|
||||||
break;
|
break;
|
||||||
case graphics::MaterialKey::METALLIC_MAP_BIT:
|
case graphics::MaterialKey::METALLIC_MAP_BIT:
|
||||||
if (materialKey.isMetallicMap()) {
|
if (materialKey.isMetallicMap()) {
|
||||||
if (!enableTextures) {
|
auto itr = textureMaps.find(graphics::MaterialKey::METALLIC_MAP);
|
||||||
forceDefault = true;
|
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||||
|
drawMaterialTextures->setTexture(gr::Texture::MaterialMetallic, itr->second->getTextureView());
|
||||||
|
wasSet = true;
|
||||||
} else {
|
} else {
|
||||||
auto itr = textureMaps.find(graphics::MaterialKey::METALLIC_MAP);
|
forceDefault = true;
|
||||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
|
||||||
drawMaterialTextures->setTexture(gr::Texture::MaterialMetallic, itr->second->getTextureView());
|
|
||||||
wasSet = true;
|
|
||||||
} else {
|
|
||||||
forceDefault = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
schemaKey.setMetallicMap(true);
|
schemaKey.setMetallicMap(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case graphics::MaterialKey::ROUGHNESS_MAP_BIT:
|
case graphics::MaterialKey::ROUGHNESS_MAP_BIT:
|
||||||
if (materialKey.isRoughnessMap()) {
|
if (materialKey.isRoughnessMap()) {
|
||||||
if (!enableTextures) {
|
auto itr = textureMaps.find(graphics::MaterialKey::ROUGHNESS_MAP);
|
||||||
forceDefault = true;
|
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||||
|
drawMaterialTextures->setTexture(gr::Texture::MaterialRoughness, itr->second->getTextureView());
|
||||||
|
wasSet = true;
|
||||||
} else {
|
} else {
|
||||||
auto itr = textureMaps.find(graphics::MaterialKey::ROUGHNESS_MAP);
|
forceDefault = true;
|
||||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
|
||||||
drawMaterialTextures->setTexture(gr::Texture::MaterialRoughness, itr->second->getTextureView());
|
|
||||||
wasSet = true;
|
|
||||||
} else {
|
|
||||||
forceDefault = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
schemaKey.setRoughnessMap(true);
|
schemaKey.setRoughnessMap(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case graphics::MaterialKey::NORMAL_MAP_BIT:
|
case graphics::MaterialKey::NORMAL_MAP_BIT:
|
||||||
if (materialKey.isNormalMap()) {
|
if (materialKey.isNormalMap()) {
|
||||||
if (!enableTextures) {
|
auto itr = textureMaps.find(graphics::MaterialKey::NORMAL_MAP);
|
||||||
forceDefault = true;
|
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||||
|
drawMaterialTextures->setTexture(gr::Texture::MaterialNormal, itr->second->getTextureView());
|
||||||
|
wasSet = true;
|
||||||
} else {
|
} else {
|
||||||
auto itr = textureMaps.find(graphics::MaterialKey::NORMAL_MAP);
|
forceDefault = true;
|
||||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
|
||||||
drawMaterialTextures->setTexture(gr::Texture::MaterialNormal, itr->second->getTextureView());
|
|
||||||
wasSet = true;
|
|
||||||
} else {
|
|
||||||
forceDefault = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
schemaKey.setNormalMap(true);
|
schemaKey.setNormalMap(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case graphics::MaterialKey::OCCLUSION_MAP_BIT:
|
case graphics::MaterialKey::OCCLUSION_MAP_BIT:
|
||||||
if (materialKey.isOcclusionMap()) {
|
if (materialKey.isOcclusionMap()) {
|
||||||
if (!enableTextures) {
|
auto itr = textureMaps.find(graphics::MaterialKey::OCCLUSION_MAP);
|
||||||
forceDefault = true;
|
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||||
|
drawMaterialTextures->setTexture(gr::Texture::MaterialOcclusion, itr->second->getTextureView());
|
||||||
|
wasSet = true;
|
||||||
} else {
|
} else {
|
||||||
auto itr = textureMaps.find(graphics::MaterialKey::OCCLUSION_MAP);
|
forceDefault = true;
|
||||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
|
||||||
drawMaterialTextures->setTexture(gr::Texture::MaterialOcclusion, itr->second->getTextureView());
|
|
||||||
wasSet = true;
|
|
||||||
} else {
|
|
||||||
forceDefault = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
schemaKey.setOcclusionMap(true);
|
schemaKey.setOcclusionMap(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case graphics::MaterialKey::SCATTERING_MAP_BIT:
|
case graphics::MaterialKey::SCATTERING_MAP_BIT:
|
||||||
if (materialKey.isScatteringMap()) {
|
if (materialKey.isScatteringMap()) {
|
||||||
if (!enableTextures) {
|
auto itr = textureMaps.find(graphics::MaterialKey::SCATTERING_MAP);
|
||||||
forceDefault = true;
|
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||||
|
drawMaterialTextures->setTexture(gr::Texture::MaterialScattering, itr->second->getTextureView());
|
||||||
|
wasSet = true;
|
||||||
} else {
|
} else {
|
||||||
auto itr = textureMaps.find(graphics::MaterialKey::SCATTERING_MAP);
|
forceDefault = true;
|
||||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
|
||||||
drawMaterialTextures->setTexture(gr::Texture::MaterialScattering, itr->second->getTextureView());
|
|
||||||
wasSet = true;
|
|
||||||
} else {
|
|
||||||
forceDefault = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
schemaKey.setScattering(true);
|
schemaKey.setScattering(true);
|
||||||
}
|
}
|
||||||
|
@ -571,16 +549,12 @@ void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu:
|
||||||
case graphics::MaterialKey::EMISSIVE_MAP_BIT:
|
case graphics::MaterialKey::EMISSIVE_MAP_BIT:
|
||||||
// Lightmap takes precendence over emissive map for legacy reasons
|
// Lightmap takes precendence over emissive map for legacy reasons
|
||||||
if (materialKey.isEmissiveMap() && !materialKey.isLightmapMap()) {
|
if (materialKey.isEmissiveMap() && !materialKey.isLightmapMap()) {
|
||||||
if (!enableTextures) {
|
auto itr = textureMaps.find(graphics::MaterialKey::EMISSIVE_MAP);
|
||||||
forceDefault = true;
|
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||||
|
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, itr->second->getTextureView());
|
||||||
|
wasSet = true;
|
||||||
} else {
|
} else {
|
||||||
auto itr = textureMaps.find(graphics::MaterialKey::EMISSIVE_MAP);
|
forceDefault = true;
|
||||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
|
||||||
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, itr->second->getTextureView());
|
|
||||||
wasSet = true;
|
|
||||||
} else {
|
|
||||||
forceDefault = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
schemaKey.setEmissiveMap(true);
|
schemaKey.setEmissiveMap(true);
|
||||||
} else if (materialKey.isLightmapMap()) {
|
} else if (materialKey.isLightmapMap()) {
|
||||||
|
@ -590,16 +564,12 @@ void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu:
|
||||||
break;
|
break;
|
||||||
case graphics::MaterialKey::LIGHTMAP_MAP_BIT:
|
case graphics::MaterialKey::LIGHTMAP_MAP_BIT:
|
||||||
if (materialKey.isLightmapMap()) {
|
if (materialKey.isLightmapMap()) {
|
||||||
if (!enableTextures) {
|
auto itr = textureMaps.find(graphics::MaterialKey::LIGHTMAP_MAP);
|
||||||
forceDefault = true;
|
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||||
|
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, itr->second->getTextureView());
|
||||||
|
wasSet = true;
|
||||||
} else {
|
} else {
|
||||||
auto itr = textureMaps.find(graphics::MaterialKey::LIGHTMAP_MAP);
|
forceDefault = true;
|
||||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
|
||||||
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, itr->second->getTextureView());
|
|
||||||
wasSet = true;
|
|
||||||
} else {
|
|
||||||
forceDefault = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
schemaKey.setLightmapMap(true);
|
schemaKey.setLightmapMap(true);
|
||||||
}
|
}
|
||||||
|
@ -608,9 +578,10 @@ void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fallthrough = defaultFallthrough || material->getPropertyFallthrough(flagBit);
|
||||||
if (wasSet) {
|
if (wasSet) {
|
||||||
flagBitsToCheck.erase(it++);
|
flagBitsToCheck.erase(it++);
|
||||||
} else if (forceDefault || !defaultFallthrough || !material->getPropertyFallthrough(flagBit)) {
|
} else if (forceDefault || !fallthrough) {
|
||||||
flagBitsToSetDefault.insert(flagBit);
|
flagBitsToSetDefault.insert(flagBit);
|
||||||
flagBitsToCheck.erase(it++);
|
flagBitsToCheck.erase(it++);
|
||||||
} else {
|
} else {
|
||||||
|
@ -687,8 +658,44 @@ void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME:
|
||||||
|
// set transforms and params
|
||||||
|
|
||||||
schema._key = (uint32_t)schemaKey._flags.to_ulong();
|
schema._key = (uint32_t)schemaKey._flags.to_ulong();
|
||||||
schemaBuffer.edit<graphics::MultiMaterial::Schema>() = schema;
|
schemaBuffer.edit<graphics::MultiMaterial::Schema>() = schema;
|
||||||
batch.setUniformBuffer(gr::Buffer::Material, schemaBuffer);
|
multiMaterial.setNeedsUpdate(false);
|
||||||
batch.setResourceTextureTable(drawMaterialTextures);
|
}
|
||||||
|
|
||||||
|
void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, bool enableTextures) {
|
||||||
|
if (multiMaterial.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto textureCache = DependencyManager::get<TextureCache>();
|
||||||
|
|
||||||
|
static gpu::TextureTablePointer defaultMaterialTextures = std::make_shared<gpu::TextureTable>();
|
||||||
|
static std::once_flag once;
|
||||||
|
std::call_once(once, [textureCache] {
|
||||||
|
defaultMaterialTextures->setTexture(gr::Texture::MaterialAlbedo, textureCache->getWhiteTexture());
|
||||||
|
defaultMaterialTextures->setTexture(gr::Texture::MaterialMetallic, textureCache->getBlackTexture());
|
||||||
|
defaultMaterialTextures->setTexture(gr::Texture::MaterialRoughness, textureCache->getWhiteTexture());
|
||||||
|
defaultMaterialTextures->setTexture(gr::Texture::MaterialNormal, textureCache->getBlueTexture());
|
||||||
|
defaultMaterialTextures->setTexture(gr::Texture::MaterialOcclusion, textureCache->getWhiteTexture());
|
||||||
|
defaultMaterialTextures->setTexture(gr::Texture::MaterialScattering, textureCache->getWhiteTexture());
|
||||||
|
// MaterialEmissiveLightmap has to be set later
|
||||||
|
});
|
||||||
|
|
||||||
|
auto& schemaBuffer = multiMaterial.getSchemaBuffer();
|
||||||
|
batch.setUniformBuffer(gr::Buffer::Material, schemaBuffer);
|
||||||
|
if (enableTextures) {
|
||||||
|
batch.setResourceTextureTable(multiMaterial.getTextureTable());
|
||||||
|
} else {
|
||||||
|
auto key = multiMaterial.getMaterialKey();
|
||||||
|
if (key.isLightmapMap()) {
|
||||||
|
defaultMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getBlackTexture());
|
||||||
|
} else if (key.isEmissiveMap()) {
|
||||||
|
defaultMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getGrayTexture());
|
||||||
|
}
|
||||||
|
batch.setResourceTextureTable(defaultMaterialTextures);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
class RenderPipelines {
|
class RenderPipelines {
|
||||||
public:
|
public:
|
||||||
static void bindMaterial(graphics::MaterialPointer& material, gpu::Batch& batch, bool enableTextures);
|
static void bindMaterial(graphics::MaterialPointer& material, gpu::Batch& batch, bool enableTextures);
|
||||||
|
static void updateMultiMaterial(graphics::MultiMaterial& multiMaterial);
|
||||||
static void bindMaterials(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, bool enableTextures);
|
static void bindMaterials(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, bool enableTextures);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue