mirror of
https://github.com/overte-org/overte.git
synced 2025-04-07 15:34:05 +02:00
native MToon materials
This commit is contained in:
parent
ce11eb3920
commit
c04c037588
38 changed files with 2992 additions and 990 deletions
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Brad Hefta-Gaub on 12/6/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -196,6 +197,8 @@ ItemKey EntityRenderer::getKey() {
|
|||
builder.withInvisible();
|
||||
}
|
||||
|
||||
updateItemKeyBuilderFromMaterials(builder);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
@ -221,6 +224,20 @@ bool EntityRenderer::passesZoneOcclusionTest(const std::unordered_set<QUuid>& co
|
|||
return true;
|
||||
}
|
||||
|
||||
HighlightStyle EntityRenderer::getOutlineStyle(const ViewFrustum& viewFrustum, const size_t height) const {
|
||||
std::lock_guard<std::mutex> lock(_materialsLock);
|
||||
auto materials = _materials.find("0");
|
||||
if (materials != _materials.end()) {
|
||||
glm::vec3 position;
|
||||
withReadLock([&] {
|
||||
position = _renderTransform.getTranslation();
|
||||
});
|
||||
return HighlightStyle::calculateOutlineStyle(materials->second.getOutlineWidthMode(), materials->second.getOutlineWidth(),
|
||||
materials->second.getOutline(), position, viewFrustum, height);
|
||||
}
|
||||
return HighlightStyle();
|
||||
}
|
||||
|
||||
void EntityRenderer::render(RenderArgs* args) {
|
||||
if (!isValidRenderItem()) {
|
||||
return;
|
||||
|
@ -510,7 +527,7 @@ EntityRenderer::Pipeline EntityRenderer::getPipelineType(const graphics::MultiMa
|
|||
}
|
||||
|
||||
graphics::MaterialKey drawMaterialKey = materials.getMaterialKey();
|
||||
if (drawMaterialKey.isEmissive() || drawMaterialKey.isMetallic() || drawMaterialKey.isScattering()) {
|
||||
if (materials.isMToon() || drawMaterialKey.isEmissive() || drawMaterialKey.isMetallic() || drawMaterialKey.isScattering()) {
|
||||
return Pipeline::MATERIAL;
|
||||
}
|
||||
|
||||
|
@ -630,6 +647,26 @@ Item::Bound EntityRenderer::getMaterialBound(RenderArgs* args) {
|
|||
return EntityRenderer::getBound(args);
|
||||
}
|
||||
|
||||
void EntityRenderer::updateItemKeyBuilderFromMaterials(ItemKey::Builder& builder) {
|
||||
MaterialMap::iterator materials;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_materialsLock);
|
||||
materials = _materials.find("0");
|
||||
|
||||
if (materials != _materials.end()) {
|
||||
if (materials->second.shouldUpdate()) {
|
||||
RenderPipelines::updateMultiMaterial(materials->second);
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (materials->second.hasOutline()) {
|
||||
builder.withOutline();
|
||||
}
|
||||
}
|
||||
|
||||
void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& builder) {
|
||||
MaterialMap::iterator materials;
|
||||
{
|
||||
|
@ -656,7 +693,7 @@ void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& build
|
|||
builder.withCullFaceMode(materials->second.getCullFaceMode());
|
||||
|
||||
graphics::MaterialKey drawMaterialKey = materials->second.getMaterialKey();
|
||||
if (drawMaterialKey.isUnlit()) {
|
||||
if (!materials->second.isMToon() && drawMaterialKey.isUnlit()) {
|
||||
builder.withUnlit();
|
||||
}
|
||||
|
||||
|
@ -666,8 +703,12 @@ void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& build
|
|||
if (drawMaterialKey.isNormalMap()) {
|
||||
builder.withTangents();
|
||||
}
|
||||
if (drawMaterialKey.isLightMap()) {
|
||||
builder.withLightMap();
|
||||
if (!materials->second.isMToon()) {
|
||||
if (drawMaterialKey.isLightMap()) {
|
||||
builder.withLightMap();
|
||||
}
|
||||
} else {
|
||||
builder.withMToon();
|
||||
}
|
||||
} else if (pipelineType == Pipeline::PROCEDURAL) {
|
||||
builder.withOwnPipeline();
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Brad Hefta-Gaub on 12/6/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -13,6 +14,8 @@
|
|||
#define hifi_RenderableEntityItem_h
|
||||
|
||||
#include <render/Scene.h>
|
||||
#include <render/HighlightStyle.h>
|
||||
|
||||
#include <EntityItem.h>
|
||||
#include <Sound.h>
|
||||
#include "AbstractViewStateInterface.h"
|
||||
|
@ -74,6 +77,7 @@ public:
|
|||
virtual uint32_t metaFetchMetaSubItems(ItemIDs& subItems) const override;
|
||||
virtual Item::Bound getBound(RenderArgs* args) override;
|
||||
bool passesZoneOcclusionTest(const std::unordered_set<QUuid>& containingZones) const override;
|
||||
virtual HighlightStyle getOutlineStyle(const ViewFrustum& viewFrustum, const size_t height) const override;
|
||||
|
||||
protected:
|
||||
virtual bool needsRenderUpdateFromEntity() const final { return needsRenderUpdateFromEntity(_entity); }
|
||||
|
@ -131,6 +135,7 @@ protected:
|
|||
void updateMaterials(bool baseMaterialChanged = false);
|
||||
bool materialsTransparent() const;
|
||||
Item::Bound getMaterialBound(RenderArgs* args);
|
||||
void updateItemKeyBuilderFromMaterials(ItemKey::Builder& builder);
|
||||
void updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& builder);
|
||||
|
||||
Item::Bound _bound;
|
||||
|
|
|
@ -130,8 +130,7 @@ void ImageEntityRenderer::doRender(RenderArgs* args) {
|
|||
materials = _materials["0"];
|
||||
}
|
||||
|
||||
auto& schema = materials.getSchemaBuffer().get<graphics::MultiMaterial::Schema>();
|
||||
glm::vec4 color = glm::vec4(ColorUtils::tosRGBVec3(schema._albedo), schema._opacity);
|
||||
glm::vec4 color = materials.getColor();
|
||||
color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created);
|
||||
|
||||
if (!_texture || !_texture->isLoaded() || color.a == 0.0f) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//
|
||||
// Created by Sam Gondelman on 1/18/2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -219,7 +220,7 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
|
|||
ItemKey MaterialEntityRenderer::getKey() {
|
||||
auto builder = ItemKey::Builder().withTypeShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
||||
|
||||
if (!_visible) {
|
||||
if (!_visible || !_parentID.isNull()) {
|
||||
builder.withInvisible();
|
||||
}
|
||||
|
||||
|
@ -229,6 +230,10 @@ ItemKey MaterialEntityRenderer::getKey() {
|
|||
if (matKey.isTranslucent()) {
|
||||
builder.withTransparent();
|
||||
}
|
||||
|
||||
if (drawMaterial->getOutlineWidthMode() != NetworkMToonMaterial::OutlineWidthMode::OUTLINE_NONE && drawMaterial->getOutlineWidth() > 0.0f) {
|
||||
builder.withOutline();
|
||||
}
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
|
@ -258,11 +263,16 @@ ShapeKey MaterialEntityRenderer::getShapeKey() {
|
|||
if (drawMaterialKey.isNormalMap()) {
|
||||
builder.withTangents();
|
||||
}
|
||||
if (drawMaterialKey.isLightMap()) {
|
||||
builder.withLightMap();
|
||||
}
|
||||
if (drawMaterialKey.isUnlit()) {
|
||||
builder.withUnlit();
|
||||
|
||||
if (drawMaterial && drawMaterial->isMToon()) {
|
||||
builder.withMToon();
|
||||
} else {
|
||||
if (drawMaterialKey.isLightMap()) {
|
||||
builder.withLightMap();
|
||||
}
|
||||
if (drawMaterialKey.isUnlit()) {
|
||||
builder.withUnlit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,6 +283,18 @@ ShapeKey MaterialEntityRenderer::getShapeKey() {
|
|||
return builder.build();
|
||||
}
|
||||
|
||||
HighlightStyle MaterialEntityRenderer::getOutlineStyle(const ViewFrustum& viewFrustum, const size_t height) const {
|
||||
if (const auto drawMaterial = getMaterial()) {
|
||||
glm::vec3 position;
|
||||
withReadLock([&] {
|
||||
position = _renderTransform.getTranslation();
|
||||
});
|
||||
return HighlightStyle::calculateOutlineStyle(drawMaterial->getOutlineWidthMode(), drawMaterial->getOutlineWidth(),
|
||||
drawMaterial->getOutline(), position, viewFrustum, height);
|
||||
}
|
||||
return HighlightStyle();
|
||||
}
|
||||
|
||||
void MaterialEntityRenderer::doRender(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderableMaterialEntityItem::render");
|
||||
Q_ASSERT(args->_batch);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//
|
||||
// Created by Sam Gondelman on 1/18/2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -32,6 +33,7 @@ private:
|
|||
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
|
||||
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
|
||||
virtual void doRender(RenderArgs* args) override;
|
||||
virtual HighlightStyle getOutlineStyle(const ViewFrustum& viewFrustum, const size_t height) const override;
|
||||
|
||||
ItemKey getKey() override;
|
||||
ShapeKey getShapeKey() override;
|
||||
|
|
|
@ -99,8 +99,7 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
|||
materials = _materials["0"];
|
||||
}
|
||||
|
||||
auto& schema = materials.getSchemaBuffer().get<graphics::MultiMaterial::Schema>();
|
||||
glm::vec4 outColor = glm::vec4(ColorUtils::tosRGBVec3(schema._albedo), schema._opacity);
|
||||
glm::vec4 outColor = materials.getColor();
|
||||
outColor = EntityRenderer::calculatePulseColor(outColor, _pulseProperties, _created);
|
||||
|
||||
if (outColor.a == 0.0f) {
|
||||
|
@ -178,7 +177,7 @@ scriptable::ScriptableModelBase ShapeEntityRenderer::getScriptableModel() {
|
|||
result.appendMaterials(_materials);
|
||||
auto materials = _materials.find("0");
|
||||
if (materials != _materials.end()) {
|
||||
vertexColor = ColorUtils::tosRGBVec3(materials->second.getSchemaBuffer().get<graphics::MultiMaterial::Schema>()._albedo);
|
||||
vertexColor = materials->second.getColor();
|
||||
}
|
||||
}
|
||||
if (auto mesh = geometryCache->meshFromShape(geometryShape, vertexColor)) {
|
||||
|
|
|
@ -147,8 +147,7 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
|
|||
materials = _materials["0"];
|
||||
}
|
||||
|
||||
auto& schema = materials.getSchemaBuffer().get<graphics::MultiMaterial::Schema>();
|
||||
glm::vec4 backgroundColor = glm::vec4(ColorUtils::tosRGBVec3(schema._albedo), schema._opacity);
|
||||
glm::vec4 backgroundColor = materials.getColor();
|
||||
backgroundColor = EntityRenderer::calculatePulseColor(backgroundColor, _pulseProperties, _created);
|
||||
|
||||
if (backgroundColor.a <= 0.0f) {
|
||||
|
|
|
@ -82,13 +82,33 @@ namespace scriptable {
|
|||
|
||||
QString procedural;
|
||||
|
||||
glm::vec3 shade;
|
||||
QString shadeMap;
|
||||
float shadingShift;
|
||||
QString shadingShiftMap;
|
||||
float shadingToony;
|
||||
glm::vec3 matcap;
|
||||
QString matcapMap;
|
||||
glm::vec3 parametricRim;
|
||||
float parametricRimFresnelPower;
|
||||
float parametricRimLift;
|
||||
QString rimMap;
|
||||
float rimLightingMix;
|
||||
QString outlineWidthMode;
|
||||
float outlineWidth;
|
||||
glm::vec3 outline;
|
||||
QString uvAnimationMaskMap;
|
||||
float uvAnimationScrollXSpeed;
|
||||
float uvAnimationScrollYSpeed;
|
||||
float uvAnimationRotationSpeed;
|
||||
|
||||
graphics::MaterialKey key { 0 };
|
||||
};
|
||||
|
||||
/*@jsdoc
|
||||
* A material layer.
|
||||
* @typedef {object} Graphics.MaterialLayer
|
||||
* @property {Graphics.Material} material - The layer's material.
|
||||
* @property {Entities.Material} material - The layer's material.
|
||||
* @property {number} priority - The priority of the layer. If multiple materials are applied to a mesh part, only the
|
||||
* layer with the highest priority is applied, with materials of the same priority randomly assigned.
|
||||
*/
|
||||
|
|
|
@ -369,120 +369,6 @@ namespace scriptable {
|
|||
return true;
|
||||
}
|
||||
|
||||
/*@jsdoc
|
||||
* A material in a {@link GraphicsModel}.
|
||||
* @typedef {object} Graphics.Material
|
||||
* @property {string} name - The name of the material.
|
||||
* @property {string} model - Different material models support different properties and rendering modes. Supported models
|
||||
* are: <code>"hifi_pbr"</code> and <code>"hifi_shader_simple"</code>.
|
||||
* @property {Vec3|string} [albedo] - The albedo color. Component values are in the range <code>0.0</code> –
|
||||
* <code>1.0</code>.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* @property {number|string} [opacity] - The opacity, range <code>0.0</code> – <code>1.0</code>.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
*
|
||||
* @property {number|string} [opacityCutoff] - The opacity cutoff threshold used to determine the opaque texels of the
|
||||
* <code>opacityMap</code> when <code>opacityMapMode</code> is <code>"OPACITY_MAP_MASK"</code>. Range <code>0.0</code>
|
||||
* – <code>1.0</code>.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {number|string} [roughness] - The roughness, range <code>0.0</code> – <code>1.0</code>.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {number|string} [metallic] - The metallicness, range <code>0.0</code> – <code>1.0</code>.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {number|string} [scattering] - The scattering, range <code>0.0</code> – <code>1.0</code>.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {boolean|string} [unlit] - <code>true</code> if the material is unaffected by lighting, <code>false</code> if it
|
||||
* it is lit by the key light and local lights.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {Vec3|string} [emissive] - The emissive color, i.e., the color that the material emits. Component values are
|
||||
* in the range <code>0.0</code> – <code>1.0</code>.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} [albedoMap] - The URL of the albedo texture image.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} [opacityMap] - The URL of the opacity texture image.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} [opacityMapMode] - The mode defining the interpretation of the opacity map. Values can be:
|
||||
* <ul>
|
||||
* <li><code>"OPACITY_MAP_OPAQUE"</code> for ignoring the opacity map information.</li>
|
||||
* <li><code>"OPACITY_MAP_MASK"</code> for using the <code>opacityMap</code> as a mask, where only the texel greater
|
||||
* than <code>opacityCutoff</code> are visible and rendered opaque.</li>
|
||||
* <li><code>"OPACITY_MAP_BLEND"</code> for using the <code>opacityMap</code> for alpha blending the material surface
|
||||
* with the background.</li>
|
||||
* </ul>
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} [occlusionMap] - The URL of the occlusion texture image.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} [lightMap] - The URL of the light map texture image.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} [lightmapParams] - Parameters for controlling how <code>lightMap</code> is used.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* <p><em>Currently not used.</em></p>
|
||||
* @property {string} [scatteringMap] - The URL of the scattering texture image.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} [emissiveMap] - The URL of the emissive texture image.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} [metallicMap] - The URL of the metallic texture image.
|
||||
* If <code>"fallthrough"</code> then it and <code>specularMap</code> fall through to the material below.
|
||||
* Only use one of <code>metallicMap</code> and <code>specularMap</code>.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} [specularMap] - The URL of the specular texture image.
|
||||
* Only use one of <code>metallicMap</code> and <code>specularMap</code>.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} [roughnessMap] - The URL of the roughness texture image.
|
||||
* If <code>"fallthrough"</code> then it and <code>glossMap</code> fall through to the material below.
|
||||
* Only use one of <code>roughnessMap</code> and <code>glossMap</code>.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} [glossMap] - The URL of the gloss texture image.
|
||||
* Only use one of <code>roughnessMap</code> and <code>glossMap</code>.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} [normalMap] - The URL of the normal texture image.
|
||||
* If <code>"fallthrough"</code> then it and <code>bumpMap</code> fall through to the material below.
|
||||
* Only use one of <code>normalMap</code> and <code>bumpMap</code>.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} [bumpMap] - The URL of the bump texture image.
|
||||
* Only use one of <code>normalMap</code> and <code>bumpMap</code>.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} [materialParams] - Parameters for controlling the material projection and repetition.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* <p><em>Currently not used.</em></p>
|
||||
* @property {string} [cullFaceMode="CULL_BACK"] - Specifies Which faces of the geometry to render. Values can be:
|
||||
* <ul>
|
||||
* <li><code>"CULL_NONE"</code> to render both sides of the geometry.</li>
|
||||
* <li><code>"CULL_FRONT"</code> to cull the front faces of the geometry.</li>
|
||||
* <li><code>"CULL_BACK"</code> (the default) to cull the back faces of the geometry.</li>
|
||||
* </ul>
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {Mat4|string} [texCoordTransform0] - The transform to use for all of the maps apart from
|
||||
* <code>occlusionMap</code> and <code>lightMap</code>.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* @property {Mat4|string} [texCoordTransform1] - The transform to use for <code>occlusionMap</code> and
|
||||
* <code>lightMap</code>.
|
||||
* If <code>"fallthrough"</code> then it falls through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
*
|
||||
* @property {string} procedural - The definition of a procedural shader material.
|
||||
* <code>"hifi_shader_simple"</code> model only.
|
||||
* <p><em>Currently not used.</em></p>
|
||||
*
|
||||
* @property {boolean} defaultFallthrough - <code>true</code> if all properties fall through to the material below unless
|
||||
* they are set, <code>false</code> if properties respect their individual fall-through settings.
|
||||
*/
|
||||
ScriptValue scriptableMaterialToScriptValue(ScriptEngine* engine, const scriptable::ScriptableMaterial &material) {
|
||||
ScriptValue obj = engine->newObject();
|
||||
obj.setProperty("name", material.name);
|
||||
|
@ -503,7 +389,7 @@ namespace scriptable {
|
|||
obj.setProperty("albedo", vec3ColorToScriptValue(engine, material.albedo));
|
||||
}
|
||||
|
||||
if (material.model.toStdString() == graphics::Material::HIFI_PBR) {
|
||||
if (material.model.toStdString() == graphics::Material::HIFI_PBR || material.model.toStdString() == graphics::Material::VRM_MTOON) {
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OPACITY_CUTOFF_VAL_BIT)) {
|
||||
obj.setProperty("opacityCutoff", FALLTHROUGH);
|
||||
} else if (material.key.isOpacityCutoff()) {
|
||||
|
@ -516,30 +402,6 @@ namespace scriptable {
|
|||
obj.setProperty("opacityMapMode", material.opacityMapMode);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::GLOSSY_VAL_BIT)) {
|
||||
obj.setProperty("roughness", FALLTHROUGH);
|
||||
} else if (material.key.isGlossy()) {
|
||||
obj.setProperty("roughness", material.roughness);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::METALLIC_VAL_BIT)) {
|
||||
obj.setProperty("metallic", FALLTHROUGH);
|
||||
} else if (material.key.isMetallic()) {
|
||||
obj.setProperty("metallic", material.metallic);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::SCATTERING_VAL_BIT)) {
|
||||
obj.setProperty("scattering", FALLTHROUGH);
|
||||
} else if (material.key.isScattering()) {
|
||||
obj.setProperty("scattering", material.scattering);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::UNLIT_VAL_BIT)) {
|
||||
obj.setProperty("unlit", FALLTHROUGH);
|
||||
} else if (material.key.isUnlit()) {
|
||||
obj.setProperty("unlit", material.unlit);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::EMISSIVE_VAL_BIT)) {
|
||||
obj.setProperty("emissive", FALLTHROUGH);
|
||||
} else if (material.key.isEmissive()) {
|
||||
|
@ -562,41 +424,6 @@ namespace scriptable {
|
|||
obj.setProperty("opacityMap", material.opacityMap);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OCCLUSION_MAP_BIT)) {
|
||||
obj.setProperty("occlusionMap", FALLTHROUGH);
|
||||
} else if (!material.occlusionMap.isEmpty()) {
|
||||
obj.setProperty("occlusionMap", material.occlusionMap);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::LIGHT_MAP_BIT)) {
|
||||
obj.setProperty("lightMap", FALLTHROUGH);
|
||||
} else if (!material.lightMap.isEmpty()) {
|
||||
obj.setProperty("lightMap", material.lightMap);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::SCATTERING_MAP_BIT)) {
|
||||
obj.setProperty("scatteringMap", FALLTHROUGH);
|
||||
} else if (!material.scatteringMap.isEmpty()) {
|
||||
obj.setProperty("scatteringMap", material.scatteringMap);
|
||||
}
|
||||
|
||||
// Only set one of each of these
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::METALLIC_MAP_BIT)) {
|
||||
obj.setProperty("metallicMap", FALLTHROUGH);
|
||||
} else if (!material.metallicMap.isEmpty()) {
|
||||
obj.setProperty("metallicMap", material.metallicMap);
|
||||
} else if (!material.specularMap.isEmpty()) {
|
||||
obj.setProperty("specularMap", material.specularMap);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::ROUGHNESS_MAP_BIT)) {
|
||||
obj.setProperty("roughnessMap", FALLTHROUGH);
|
||||
} else if (!material.roughnessMap.isEmpty()) {
|
||||
obj.setProperty("roughnessMap", material.roughnessMap);
|
||||
} else if (!material.glossMap.isEmpty()) {
|
||||
obj.setProperty("glossMap", material.glossMap);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::NORMAL_MAP_BIT)) {
|
||||
obj.setProperty("normalMap", FALLTHROUGH);
|
||||
} else if (!material.normalMap.isEmpty()) {
|
||||
|
@ -616,10 +443,7 @@ namespace scriptable {
|
|||
obj.setProperty("texCoordTransform1", mat4toScriptValue(engine, material.texCoordTransforms[1]));
|
||||
}
|
||||
|
||||
// These need to be implemented, but set the fallthrough for now
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::Material::LIGHTMAP_PARAMS)) {
|
||||
obj.setProperty("lightmapParams", FALLTHROUGH);
|
||||
}
|
||||
// This needs to be implemented, but set the fallthrough for now
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::Material::MATERIAL_PARAMS)) {
|
||||
obj.setProperty("materialParams", FALLTHROUGH);
|
||||
}
|
||||
|
@ -629,6 +453,179 @@ namespace scriptable {
|
|||
} else if (!material.cullFaceMode.isEmpty()) {
|
||||
obj.setProperty("cullFaceMode", material.cullFaceMode);
|
||||
}
|
||||
|
||||
if (material.model.toStdString() == graphics::Material::HIFI_PBR) {
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::GLOSSY_VAL_BIT)) {
|
||||
obj.setProperty("roughness", FALLTHROUGH);
|
||||
} else if (material.key.isGlossy()) {
|
||||
obj.setProperty("roughness", material.roughness);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::METALLIC_VAL_BIT)) {
|
||||
obj.setProperty("metallic", FALLTHROUGH);
|
||||
} else if (material.key.isMetallic()) {
|
||||
obj.setProperty("metallic", material.metallic);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::SCATTERING_VAL_BIT)) {
|
||||
obj.setProperty("scattering", FALLTHROUGH);
|
||||
} else if (material.key.isScattering()) {
|
||||
obj.setProperty("scattering", material.scattering);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::UNLIT_VAL_BIT)) {
|
||||
obj.setProperty("unlit", FALLTHROUGH);
|
||||
} else if (material.key.isUnlit()) {
|
||||
obj.setProperty("unlit", material.unlit);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OCCLUSION_MAP_BIT)) {
|
||||
obj.setProperty("occlusionMap", FALLTHROUGH);
|
||||
} else if (!material.occlusionMap.isEmpty()) {
|
||||
obj.setProperty("occlusionMap", material.occlusionMap);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::LIGHT_MAP_BIT)) {
|
||||
obj.setProperty("lightMap", FALLTHROUGH);
|
||||
} else if (!material.lightMap.isEmpty()) {
|
||||
obj.setProperty("lightMap", material.lightMap);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::SCATTERING_MAP_BIT)) {
|
||||
obj.setProperty("scatteringMap", FALLTHROUGH);
|
||||
} else if (!material.scatteringMap.isEmpty()) {
|
||||
obj.setProperty("scatteringMap", material.scatteringMap);
|
||||
}
|
||||
|
||||
// Only set one of each of these
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::METALLIC_MAP_BIT)) {
|
||||
obj.setProperty("metallicMap", FALLTHROUGH);
|
||||
} else if (!material.metallicMap.isEmpty()) {
|
||||
obj.setProperty("metallicMap", material.metallicMap);
|
||||
} else if (!material.specularMap.isEmpty()) {
|
||||
obj.setProperty("specularMap", material.specularMap);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::ROUGHNESS_MAP_BIT)) {
|
||||
obj.setProperty("roughnessMap", FALLTHROUGH);
|
||||
} else if (!material.roughnessMap.isEmpty()) {
|
||||
obj.setProperty("roughnessMap", material.roughnessMap);
|
||||
} else if (!material.glossMap.isEmpty()) {
|
||||
obj.setProperty("glossMap", material.glossMap);
|
||||
}
|
||||
|
||||
// This needs to be implemented, but set the fallthrough for now
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::Material::LIGHTMAP_PARAMS)) {
|
||||
obj.setProperty("lightmapParams", FALLTHROUGH);
|
||||
}
|
||||
} else {
|
||||
// See the mappings in ProceduralMatericalCache.h
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::UNLIT_VAL_BIT)) {
|
||||
obj.setProperty("shade", FALLTHROUGH);
|
||||
} else if (material.key._flags[graphics::MaterialKey::UNLIT_VAL_BIT]) {
|
||||
obj.setProperty("shade", vec3ColorToScriptValue(engine, material.shade));
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::ROUGHNESS_MAP_BIT)) {
|
||||
obj.setProperty("shadeMap", FALLTHROUGH);
|
||||
} else if (!material.shadeMap.isEmpty()) {
|
||||
obj.setProperty("shadeMap", material.shadeMap);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::METALLIC_VAL_BIT)) {
|
||||
obj.setProperty("shadingShift", FALLTHROUGH);
|
||||
} else if (material.key._flags[graphics::MaterialKey::METALLIC_VAL_BIT]) {
|
||||
obj.setProperty("shadingShift", material.shadingShift);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::METALLIC_MAP_BIT)) {
|
||||
obj.setProperty("shadingShiftMap", FALLTHROUGH);
|
||||
} else if (!material.shadingShiftMap.isEmpty()) {
|
||||
obj.setProperty("shadingShiftMap", material.shadingShiftMap);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::GLOSSY_VAL_BIT)) {
|
||||
obj.setProperty("shadingToony", FALLTHROUGH);
|
||||
} else if (material.key._flags[graphics::MaterialKey::GLOSSY_VAL_BIT]) {
|
||||
obj.setProperty("shadingToony", material.shadingToony);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::EXTRA_1_BIT)) {
|
||||
obj.setProperty("matcap", FALLTHROUGH);
|
||||
} else if (material.key._flags[graphics::MaterialKey::EXTRA_1_BIT]) {
|
||||
obj.setProperty("matcap", vec3ColorToScriptValue(engine, material.matcap));
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OCCLUSION_MAP_BIT)) {
|
||||
obj.setProperty("matcapMap", FALLTHROUGH);
|
||||
} else if (!material.matcapMap.isEmpty()) {
|
||||
obj.setProperty("matcapMap", material.matcapMap);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::EXTRA_2_BIT)) {
|
||||
obj.setProperty("parametricRim", FALLTHROUGH);
|
||||
} else if (material.key._flags[graphics::MaterialKey::EXTRA_2_BIT]) {
|
||||
obj.setProperty("parametricRim", vec3ColorToScriptValue(engine, material.parametricRim));
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::EXTRA_3_BIT)) {
|
||||
obj.setProperty("parametricRimFresnelPower", FALLTHROUGH);
|
||||
} else if (material.key._flags[graphics::MaterialKey::EXTRA_3_BIT]) {
|
||||
obj.setProperty("parametricRimFresnelPower", material.parametricRimFresnelPower);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::EXTRA_4_BIT)) {
|
||||
obj.setProperty("parametricRimLift", FALLTHROUGH);
|
||||
} else if (material.key._flags[graphics::MaterialKey::EXTRA_4_BIT]) {
|
||||
obj.setProperty("parametricRimLift", material.parametricRimLift);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::SCATTERING_MAP_BIT)) {
|
||||
obj.setProperty("rimMap", FALLTHROUGH);
|
||||
} else if (!material.rimMap.isEmpty()) {
|
||||
obj.setProperty("rimMap", material.rimMap);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::EXTRA_5_BIT)) {
|
||||
obj.setProperty("rimLightingMix", FALLTHROUGH);
|
||||
} else if (material.key._flags[graphics::MaterialKey::EXTRA_5_BIT]) {
|
||||
obj.setProperty("rimLightingMix", material.rimLightingMix);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::LIGHT_MAP_BIT)) {
|
||||
obj.setProperty("uvAnimationMaskMap", FALLTHROUGH);
|
||||
} else if (!material.uvAnimationMaskMap.isEmpty()) {
|
||||
obj.setProperty("uvAnimationMaskMap", material.uvAnimationMaskMap);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::SCATTERING_VAL_BIT)) {
|
||||
obj.setProperty("uvAnimationScrollXSpeed", FALLTHROUGH);
|
||||
obj.setProperty("uvAnimationScrollYSpeed", FALLTHROUGH);
|
||||
obj.setProperty("uvAnimationRotationSpeed", FALLTHROUGH);
|
||||
} else if (material.key._flags[graphics::MaterialKey::SCATTERING_VAL_BIT]) {
|
||||
obj.setProperty("uvAnimationScrollXSpeed", material.uvAnimationScrollXSpeed);
|
||||
obj.setProperty("uvAnimationScrollYSpeed", material.uvAnimationScrollYSpeed);
|
||||
obj.setProperty("uvAnimationRotationSpeed", material.uvAnimationRotationSpeed);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::Material::EXTRA_1_BIT)) {
|
||||
obj.setProperty("outlineWidthMode", FALLTHROUGH);
|
||||
} else {
|
||||
obj.setProperty("outlineWidthMode", material.outlineWidthMode);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::Material::EXTRA_2_BIT)) {
|
||||
obj.setProperty("outlineWidth", FALLTHROUGH);
|
||||
} else {
|
||||
obj.setProperty("outlineWidth", material.outlineWidth);
|
||||
}
|
||||
|
||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::Material::EXTRA_3_BIT)) {
|
||||
obj.setProperty("outline", FALLTHROUGH);
|
||||
} else {
|
||||
obj.setProperty("outline", vec3ColorToScriptValue(engine, material.outline));
|
||||
}
|
||||
}
|
||||
} else if (material.model.toStdString() == graphics::Material::HIFI_SHADER_SIMPLE) {
|
||||
obj.setProperty("procedural", material.procedural);
|
||||
}
|
||||
|
|
|
@ -27,27 +27,50 @@ scriptable::ScriptableMaterial& scriptable::ScriptableMaterial::operator=(const
|
|||
opacity = material.opacity;
|
||||
albedo = material.albedo;
|
||||
|
||||
if (model.toStdString() == graphics::Material::HIFI_PBR) {
|
||||
if (model.toStdString() == graphics::Material::HIFI_PBR || model.toStdString() == graphics::Material::VRM_MTOON) {
|
||||
opacityCutoff = material.opacityCutoff;
|
||||
opacityMapMode = material.opacityMapMode;
|
||||
roughness = material.roughness;
|
||||
metallic = material.metallic;
|
||||
scattering = material.scattering;
|
||||
unlit = material.unlit;
|
||||
emissive = material.emissive;
|
||||
emissiveMap = material.emissiveMap;
|
||||
albedoMap = material.albedoMap;
|
||||
opacityMap = material.opacityMap;
|
||||
metallicMap = material.metallicMap;
|
||||
specularMap = material.specularMap;
|
||||
roughnessMap = material.roughnessMap;
|
||||
glossMap = material.glossMap;
|
||||
normalMap = material.normalMap;
|
||||
bumpMap = material.bumpMap;
|
||||
occlusionMap = material.occlusionMap;
|
||||
lightMap = material.lightMap;
|
||||
scatteringMap = material.scatteringMap;
|
||||
cullFaceMode = material.cullFaceMode;
|
||||
|
||||
if (model.toStdString() == graphics::Material::HIFI_PBR) {
|
||||
roughness = material.roughness;
|
||||
metallic = material.metallic;
|
||||
scattering = material.scattering;
|
||||
unlit = material.unlit;
|
||||
metallicMap = material.metallicMap;
|
||||
specularMap = material.specularMap;
|
||||
roughnessMap = material.roughnessMap;
|
||||
glossMap = material.glossMap;
|
||||
occlusionMap = material.occlusionMap;
|
||||
lightMap = material.lightMap;
|
||||
scatteringMap = material.scatteringMap;
|
||||
} else {
|
||||
shade = material.shade;
|
||||
shadeMap = material.shadeMap;
|
||||
shadingShift = material.shadingShift;
|
||||
shadingShiftMap = material.shadingShiftMap;
|
||||
shadingToony = material.shadingToony;
|
||||
matcap = material.matcap;
|
||||
matcapMap = material.matcapMap;
|
||||
parametricRim = material.parametricRim;
|
||||
parametricRimFresnelPower = material.parametricRimFresnelPower;
|
||||
parametricRimLift = material.parametricRimLift;
|
||||
rimMap = material.rimMap;
|
||||
rimLightingMix = material.rimLightingMix;
|
||||
outlineWidthMode = material.outlineWidthMode;
|
||||
outlineWidth = material.outlineWidth;
|
||||
outline = material.outline;
|
||||
uvAnimationMaskMap = material.uvAnimationMaskMap;
|
||||
uvAnimationScrollXSpeed = material.uvAnimationScrollXSpeed;
|
||||
uvAnimationScrollYSpeed = material.uvAnimationScrollYSpeed;
|
||||
uvAnimationRotationSpeed = material.uvAnimationRotationSpeed;
|
||||
}
|
||||
} else if (model.toStdString() == graphics::Material::HIFI_SHADER_SIMPLE) {
|
||||
procedural = material.procedural;
|
||||
}
|
||||
|
@ -67,13 +90,9 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialPoint
|
|||
opacity = material->getOpacity();
|
||||
albedo = material->getAlbedo();
|
||||
|
||||
if (model.toStdString() == graphics::Material::HIFI_PBR) {
|
||||
if (model.toStdString() == graphics::Material::HIFI_PBR || model.toStdString() == graphics::Material::VRM_MTOON) {
|
||||
opacityCutoff = material->getOpacityCutoff();
|
||||
opacityMapMode = QString(graphics::MaterialKey::getOpacityMapModeName(material->getOpacityMapMode()).c_str());
|
||||
roughness = material->getRoughness();
|
||||
metallic = material->getMetallic();
|
||||
scattering = material->getScattering();
|
||||
unlit = material->isUnlit();
|
||||
emissive = material->getEmissive();
|
||||
|
||||
auto map = material->getTextureMap(graphics::Material::MapChannel::EMISSIVE_MAP);
|
||||
|
@ -89,24 +108,6 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialPoint
|
|||
}
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::METALLIC_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
if (map->getTextureSource()->getType() == image::TextureUsage::Type::METALLIC_TEXTURE) {
|
||||
metallicMap = map->getTextureSource()->getUrl().toString();
|
||||
} else if (map->getTextureSource()->getType() == image::TextureUsage::Type::SPECULAR_TEXTURE) {
|
||||
specularMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::ROUGHNESS_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
if (map->getTextureSource()->getType() == image::TextureUsage::Type::ROUGHNESS_TEXTURE) {
|
||||
roughnessMap = map->getTextureSource()->getUrl().toString();
|
||||
} else if (map->getTextureSource()->getType() == image::TextureUsage::Type::GLOSS_TEXTURE) {
|
||||
glossMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::NORMAL_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
if (map->getTextureSource()->getType() == image::TextureUsage::Type::NORMAL_TEXTURE) {
|
||||
|
@ -116,26 +117,92 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialPoint
|
|||
}
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::OCCLUSION_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
occlusionMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::LIGHT_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
lightMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::SCATTERING_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
scatteringMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
|
||||
for (int i = 0; i < graphics::Material::NUM_TEXCOORD_TRANSFORMS; i++) {
|
||||
texCoordTransforms[i] = material->getTexCoordTransform(i);
|
||||
}
|
||||
|
||||
cullFaceMode = QString(graphics::MaterialKey::getCullFaceModeName(material->getCullFaceMode()).c_str());
|
||||
|
||||
if (model.toStdString() == graphics::Material::HIFI_PBR) {
|
||||
roughness = material->getRoughness();
|
||||
metallic = material->getMetallic();
|
||||
scattering = material->getScattering();
|
||||
unlit = material->isUnlit();
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::METALLIC_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
if (map->getTextureSource()->getType() == image::TextureUsage::Type::METALLIC_TEXTURE) {
|
||||
metallicMap = map->getTextureSource()->getUrl().toString();
|
||||
} else if (map->getTextureSource()->getType() == image::TextureUsage::Type::SPECULAR_TEXTURE) {
|
||||
specularMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::ROUGHNESS_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
if (map->getTextureSource()->getType() == image::TextureUsage::Type::ROUGHNESS_TEXTURE) {
|
||||
roughnessMap = map->getTextureSource()->getUrl().toString();
|
||||
} else if (map->getTextureSource()->getType() == image::TextureUsage::Type::GLOSS_TEXTURE) {
|
||||
glossMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::OCCLUSION_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
occlusionMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::LIGHT_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
lightMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::SCATTERING_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
scatteringMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
} else {
|
||||
shade = material->getShade();
|
||||
shadingShift = material->getShadingShift();
|
||||
shadingToony = material->getShadingToony();
|
||||
matcap = material->getMatcap();
|
||||
parametricRim = material->getParametricRim();
|
||||
parametricRimFresnelPower = material->getParametricRimFresnelPower();
|
||||
parametricRimLift = material->getParametricRimLift();
|
||||
rimLightingMix = material->getRimLightingMix();
|
||||
outlineWidthMode = material->getOutlineWidthMode();
|
||||
outlineWidth = material->getOutlineWidth();
|
||||
outline = material->getOutline();
|
||||
uvAnimationScrollXSpeed = material->getUVAnimationScrollXSpeed();
|
||||
uvAnimationScrollYSpeed = material->getUVAnimationScrollYSpeed();
|
||||
uvAnimationRotationSpeed = material->getUVAnimationRotationSpeed();
|
||||
|
||||
// See the mappings in ProceduralMatericalCache.h
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::ROUGHNESS_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
shadeMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::METALLIC_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
shadingShiftMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::OCCLUSION_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
matcapMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::SCATTERING_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
rimMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::LIGHT_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
uvAnimationMaskMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
}
|
||||
} else if (model.toStdString() == graphics::Material::HIFI_SHADER_SIMPLE) {
|
||||
procedural = material->getProceduralString();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Sam Gateau on 12/10/2014.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -60,7 +61,8 @@ bool MaterialKey::getCullFaceModeFromName(const std::string& modeName, CullFaceM
|
|||
}
|
||||
|
||||
const std::string Material::HIFI_PBR { "hifi_pbr" };
|
||||
const std::string Material::HIFI_SHADER_SIMPLE { "hifi_shader_simple" };
|
||||
const std::string Material::HIFI_SHADER_SIMPLE{ "hifi_shader_simple" };
|
||||
const std::string Material::VRM_MTOON { "vrm_mtoon" };
|
||||
|
||||
Material::Material() {
|
||||
for (int i = 0; i < NUM_TOTAL_FLAGS; i++) {
|
||||
|
@ -258,6 +260,17 @@ void Material::setTextureTransforms(const Transform& transform, MaterialMappingM
|
|||
_materialParams = glm::vec2(mode, repeat);
|
||||
}
|
||||
|
||||
const glm::vec3 Material::DEFAULT_SHADE = glm::vec3(0.0f);
|
||||
const float Material::DEFAULT_SHADING_SHIFT = 0.0f;
|
||||
const float Material::DEFAULT_SHADING_TOONY = 0.9f;
|
||||
const glm::vec3 Material::DEFAULT_MATCAP = glm::vec3(1.0f);
|
||||
const glm::vec3 Material::DEFAULT_PARAMETRIC_RIM = glm::vec3(0.0f);
|
||||
const float Material::DEFAULT_PARAMETRIC_RIM_FRESNEL_POWER = 5.0f;
|
||||
const float Material::DEFAULT_PARAMETRIC_RIM_LIFT = 0.0f;
|
||||
const float Material::DEFAULT_RIM_LIGHTING_MIX = 1.0f;
|
||||
const float Material::DEFAULT_UV_ANIMATION_SCROLL_SPEED = 0.0f;
|
||||
const glm::vec3 Material::DEFAULT_OUTLINE = glm::vec3(0.0f);
|
||||
|
||||
MultiMaterial::MultiMaterial() {
|
||||
Schema schema;
|
||||
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema, sizeof(Schema)));
|
||||
|
@ -311,3 +324,30 @@ bool MultiMaterial::anyReferenceMaterialsOrTexturesChanged() const {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MultiMaterial::setisMToon(bool isMToon) {
|
||||
if (isMToon != _isMToon) {
|
||||
if (isMToon) {
|
||||
MToonSchema toonSchema;
|
||||
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(MToonSchema), (const gpu::Byte*) &toonSchema, sizeof(MToonSchema)));
|
||||
} else {
|
||||
Schema schema;
|
||||
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema, sizeof(Schema)));
|
||||
}
|
||||
}
|
||||
_isMToon = isMToon;
|
||||
}
|
||||
|
||||
void MultiMaterial::setMToonTime() {
|
||||
assert(_isMToon);
|
||||
|
||||
// Some objects, like material entities, don't have persistent MultiMaterials to store this in, so we just store it once statically
|
||||
static uint64_t mtoonStartTime;
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [] {
|
||||
mtoonStartTime = usecTimestampNow();
|
||||
});
|
||||
|
||||
// Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds
|
||||
_schemaBuffer.edit<graphics::MultiMaterial::MToonSchema>()._time = (float)((usecTimestampNow() - mtoonStartTime) / USECS_PER_MSEC) / MSECS_PER_SECOND;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Sam Gateau on 12/10/2014.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -34,6 +35,7 @@ typedef std::shared_ptr< TextureMap > TextureMapPointer;
|
|||
// Material Key is a coarse trait description of a material used to classify the materials
|
||||
class MaterialKey {
|
||||
public:
|
||||
// Be careful changing these, they need to match up with the bits in graphics/Material.slh
|
||||
enum FlagBit {
|
||||
EMISSIVE_VAL_BIT = 0,
|
||||
UNLIT_VAL_BIT,
|
||||
|
@ -57,6 +59,12 @@ public:
|
|||
LIGHT_MAP_BIT,
|
||||
SCATTERING_MAP_BIT,
|
||||
|
||||
EXTRA_1_BIT,
|
||||
EXTRA_2_BIT,
|
||||
EXTRA_3_BIT,
|
||||
EXTRA_4_BIT,
|
||||
EXTRA_5_BIT,
|
||||
|
||||
NUM_FLAGS,
|
||||
};
|
||||
typedef std::bitset<NUM_FLAGS> Flags;
|
||||
|
@ -419,6 +427,10 @@ public:
|
|||
MATERIAL_PARAMS,
|
||||
CULL_FACE_MODE,
|
||||
|
||||
EXTRA_1_BIT,
|
||||
EXTRA_2_BIT,
|
||||
EXTRA_3_BIT,
|
||||
|
||||
NUM_TOTAL_FLAGS
|
||||
};
|
||||
std::unordered_map<uint, bool> getPropertyFallthroughs() { return _propertyFallthroughs; }
|
||||
|
@ -432,15 +444,43 @@ public:
|
|||
|
||||
virtual bool isReference() const { return false; }
|
||||
|
||||
virtual bool isMToon() const { return false; }
|
||||
static const glm::vec3 DEFAULT_SHADE;
|
||||
virtual glm::vec3 getShade(bool SRGB = true) const { return glm::vec3(0.0f); }
|
||||
static const float DEFAULT_SHADING_SHIFT;
|
||||
virtual float getShadingShift() const { return 0.0f; }
|
||||
static const float DEFAULT_SHADING_TOONY;
|
||||
virtual float getShadingToony() const { return 0.0f; }
|
||||
static const glm::vec3 DEFAULT_MATCAP;
|
||||
virtual glm::vec3 getMatcap(bool SRGB = true) const { return glm::vec3(0.0f); }
|
||||
static const glm::vec3 DEFAULT_PARAMETRIC_RIM;
|
||||
virtual glm::vec3 getParametricRim(bool SRGB = true) const { return glm::vec3(0.0f); }
|
||||
static const float DEFAULT_PARAMETRIC_RIM_FRESNEL_POWER;
|
||||
virtual float getParametricRimFresnelPower() const { return 0.0f; }
|
||||
static const float DEFAULT_PARAMETRIC_RIM_LIFT;
|
||||
virtual float getParametricRimLift() const { return 0.0f; }
|
||||
static const float DEFAULT_RIM_LIGHTING_MIX;
|
||||
virtual float getRimLightingMix() const { return 0.0f; }
|
||||
static const float DEFAULT_UV_ANIMATION_SCROLL_SPEED;
|
||||
virtual float getUVAnimationScrollXSpeed() const { return 0.0f; }
|
||||
virtual float getUVAnimationScrollYSpeed() const { return 0.0f; }
|
||||
virtual float getUVAnimationRotationSpeed() const { return 0.0f; }
|
||||
|
||||
static const glm::vec3 DEFAULT_OUTLINE;
|
||||
virtual uint8_t getOutlineWidthMode() { return 0; }
|
||||
virtual float getOutlineWidth() { return 0.0f; }
|
||||
virtual glm::vec3 getOutline(bool SRGB = true) const { return glm::vec3(0.0f); }
|
||||
|
||||
static const std::string HIFI_PBR;
|
||||
static const std::string HIFI_SHADER_SIMPLE;
|
||||
static const std::string VRM_MTOON;
|
||||
|
||||
protected:
|
||||
std::string _name { "" };
|
||||
mutable MaterialKey _key { 0 };
|
||||
|
||||
private:
|
||||
std::string _model { HIFI_PBR };
|
||||
mutable MaterialKey _key { 0 };
|
||||
|
||||
// Material properties
|
||||
glm::vec3 _emissive { DEFAULT_EMISSIVE };
|
||||
|
@ -525,12 +565,12 @@ public:
|
|||
// Texture Coord Transform Array
|
||||
glm::mat4 _texcoordTransforms[Material::NUM_TEXCOORD_TRANSFORMS];
|
||||
|
||||
glm::vec2 _lightmapParams { 0.0, 1.0 };
|
||||
|
||||
// x: material mode (0 for UV, 1 for PROJECTED)
|
||||
// y: 1 for texture repeat, 0 for discard outside of 0 - 1
|
||||
glm::vec2 _materialParams { 0.0, 1.0 };
|
||||
|
||||
glm::vec2 _lightmapParams { 0.0, 1.0 };
|
||||
|
||||
Schema() {
|
||||
for (auto& transform : _texcoordTransforms) {
|
||||
transform = glm::mat4();
|
||||
|
@ -538,8 +578,68 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class MToonSchema {
|
||||
public:
|
||||
glm::vec3 _emissive { Material::DEFAULT_EMISSIVE }; // No Emissive
|
||||
float _opacity { Material::DEFAULT_OPACITY }; // Opacity = 1 => Not Transparent
|
||||
|
||||
glm::vec3 _albedo { Material::DEFAULT_ALBEDO }; // Grey albedo => isAlbedo
|
||||
float _opacityCutoff { Material::DEFAULT_OPACITY_CUTOFF }; // Opacity cutoff applyed when using opacityMap as Mask
|
||||
|
||||
glm::vec3 _shade { Material::DEFAULT_SHADE };
|
||||
float _shadingShift { Material::DEFAULT_SHADING_SHIFT };
|
||||
|
||||
glm::vec3 _matcap { Material::DEFAULT_MATCAP };
|
||||
float _shadingToony { Material::DEFAULT_SHADING_TOONY };
|
||||
|
||||
glm::vec3 _parametricRim { Material::DEFAULT_PARAMETRIC_RIM };
|
||||
float _parametricRimFresnelPower { Material::DEFAULT_PARAMETRIC_RIM_FRESNEL_POWER };
|
||||
|
||||
float _parametricRimLift { Material::DEFAULT_PARAMETRIC_RIM_LIFT };
|
||||
float _rimLightingMix { Material::DEFAULT_RIM_LIGHTING_MIX };
|
||||
glm::vec2 _uvAnimationScrollSpeed { Material::DEFAULT_UV_ANIMATION_SCROLL_SPEED };
|
||||
|
||||
float _uvAnimationScrollRotationSpeed { Material::DEFAULT_UV_ANIMATION_SCROLL_SPEED };
|
||||
float _time { 0.0f };
|
||||
uint32_t _key { 0 }; // a copy of the materialKey
|
||||
float _spare { 0.0f };
|
||||
|
||||
// Texture Coord Transform Array
|
||||
glm::mat4 _texcoordTransforms[Material::NUM_TEXCOORD_TRANSFORMS];
|
||||
|
||||
// x: material mode (0 for UV, 1 for PROJECTED)
|
||||
// y: 1 for texture repeat, 0 for discard outside of 0 - 1
|
||||
glm::vec2 _materialParams { 0.0, 1.0 };
|
||||
|
||||
MToonSchema() {
|
||||
for (auto& transform : _texcoordTransforms) {
|
||||
transform = glm::mat4();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
gpu::BufferView& getSchemaBuffer() { return _schemaBuffer; }
|
||||
graphics::MaterialKey getMaterialKey() const { return graphics::MaterialKey(_schemaBuffer.get<graphics::MultiMaterial::Schema>()._key); }
|
||||
graphics::MaterialKey getMaterialKey() const {
|
||||
if (_isMToon) {
|
||||
return graphics::MaterialKey(_schemaBuffer.get<graphics::MultiMaterial::MToonSchema>()._key);
|
||||
} else {
|
||||
return graphics::MaterialKey(_schemaBuffer.get<graphics::MultiMaterial::Schema>()._key);
|
||||
}
|
||||
}
|
||||
glm::vec4 getColor() const {
|
||||
glm::vec3 albedo;
|
||||
float opacity;
|
||||
if (_isMToon) {
|
||||
const auto& schema = _schemaBuffer.get<graphics::MultiMaterial::MToonSchema>();
|
||||
albedo = schema._albedo;
|
||||
opacity = schema._opacity;
|
||||
} else {
|
||||
const auto& schema = _schemaBuffer.get<graphics::MultiMaterial::Schema>();
|
||||
albedo = schema._albedo;
|
||||
opacity = schema._opacity;
|
||||
}
|
||||
return glm::vec4(ColorUtils::tosRGBVec3(albedo), opacity);
|
||||
}
|
||||
const gpu::TextureTablePointer& getTextureTable() const { return _textureTable; }
|
||||
|
||||
void setCullFaceMode(graphics::MaterialKey::CullFaceMode cullFaceMode) { _cullFaceMode = cullFaceMode; }
|
||||
|
@ -559,6 +659,18 @@ public:
|
|||
void addReferenceTexture(const std::function<gpu::TexturePointer()>& textureOperator);
|
||||
void addReferenceMaterial(const std::function<graphics::MaterialPointer()>& materialOperator);
|
||||
|
||||
void setisMToon(bool isMToon);
|
||||
bool isMToon() const { return _isMToon; }
|
||||
void setMToonTime();
|
||||
bool hasOutline() const { return _outlineWidthMode != 0 && _outlineWidth > 0.0f; }
|
||||
uint8_t getOutlineWidthMode() const { return _outlineWidthMode; }
|
||||
float getOutlineWidth() const { return _outlineWidth; }
|
||||
glm::vec3 getOutline() const { return _outline; }
|
||||
void resetOutline() { _outlineWidthMode = 0; _outlineWidth = 0.0f; _outline = glm::vec3(0.0f); }
|
||||
void setOutlineWidthMode(uint8_t mode) { _outlineWidthMode = mode; }
|
||||
void setOutlineWidth(float width) { _outlineWidth = width; }
|
||||
void setOutline(const glm::vec3& outline) { _outline = outline; }
|
||||
|
||||
private:
|
||||
gpu::BufferView _schemaBuffer;
|
||||
graphics::MaterialKey::CullFaceMode _cullFaceMode { graphics::Material::DEFAULT_CULL_FACE_MODE };
|
||||
|
@ -576,6 +688,11 @@ private:
|
|||
|
||||
std::vector<std::pair<std::function<gpu::TexturePointer()>, gpu::TexturePointer>> _referenceTextures;
|
||||
std::vector<std::pair<std::function<graphics::MaterialPointer()>, graphics::MaterialPointer>> _referenceMaterials;
|
||||
|
||||
bool _isMToon { false };
|
||||
uint8_t _outlineWidthMode { 0 };
|
||||
float _outlineWidth { 0.0f };
|
||||
glm::vec3 _outline { graphics::Material::DEFAULT_OUTLINE };
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Sam Gateau on 12/16/14.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -18,8 +19,10 @@ const int MAX_TEXCOORDS = 2;
|
|||
struct TexMapArray {
|
||||
mat4 _texcoordTransforms0;
|
||||
mat4 _texcoordTransforms1;
|
||||
vec2 _lightmapParams;
|
||||
vec2 _materialParams;
|
||||
<@if not HIFI_USE_MTOON@>
|
||||
vec2 _lightmapParams;
|
||||
<@endif@>
|
||||
};
|
||||
|
||||
<@func declareMaterialTexMapArrayBuffer()@>
|
||||
|
@ -45,11 +48,24 @@ struct TexMapArray {
|
|||
// The material values (at least the material key) must be precisely bitwise accurate
|
||||
// to what is provided by the uniform buffer, or the material key has the wrong bits
|
||||
|
||||
<@if not HIFI_USE_MTOON@>
|
||||
struct Material {
|
||||
vec4 _emissiveOpacity;
|
||||
vec4 _albedoRoughness;
|
||||
vec4 _metallicScatteringOpacityCutoffKey;
|
||||
};
|
||||
<@else@>
|
||||
struct Material {
|
||||
vec4 _emissiveOpacity;
|
||||
vec4 _albedoOpacityCutoff;
|
||||
|
||||
vec4 _shadeShadingShift;
|
||||
vec4 _matcapShadingToony;
|
||||
vec4 _parametricRimAndFresnelPower;
|
||||
vec4 _parametricRimLiftMixUVAnimationScrollSpeedXY;
|
||||
vec4 _uvAnimationScrollRotationSpeedTimeKeySpare;
|
||||
};
|
||||
<@endif@>
|
||||
|
||||
LAYOUT_STD140(binding=GRAPHICS_BUFFER_MATERIAL) uniform materialBuffer {
|
||||
Material _mat;
|
||||
|
@ -63,39 +79,91 @@ TexMapArray getTexMapArray() {
|
|||
return _texMapArray;
|
||||
}
|
||||
|
||||
vec3 getMaterialEmissive(Material m) { return m._emissiveOpacity.rgb; }
|
||||
float getMaterialOpacity(Material m) { return m._emissiveOpacity.a; }
|
||||
<@if not HIFI_USE_MTOON@>
|
||||
vec3 getMaterialEmissive(Material m) { return m._emissiveOpacity.rgb; }
|
||||
float getMaterialOpacity(Material m) { return m._emissiveOpacity.a; }
|
||||
|
||||
vec3 getMaterialAlbedo(Material m) { return m._albedoRoughness.rgb; }
|
||||
float getMaterialRoughness(Material m) { return m._albedoRoughness.a; }
|
||||
float getMaterialShininess(Material m) { return 1.0 - getMaterialRoughness(m); }
|
||||
vec3 getMaterialAlbedo(Material m) { return m._albedoRoughness.rgb; }
|
||||
float getMaterialRoughness(Material m) { return m._albedoRoughness.a; }
|
||||
float getMaterialShininess(Material m) { return 1.0 - getMaterialRoughness(m); }
|
||||
|
||||
float getMaterialMetallic(Material m) { return m._metallicScatteringOpacityCutoffKey.x; }
|
||||
float getMaterialScattering(Material m) { return m._metallicScatteringOpacityCutoffKey.y; }
|
||||
float getMaterialOpacityCutoff(Material m) { return m._metallicScatteringOpacityCutoffKey.z; }
|
||||
float getMaterialMetallic(Material m) { return m._metallicScatteringOpacityCutoffKey.x; }
|
||||
float getMaterialScattering(Material m) { return m._metallicScatteringOpacityCutoffKey.y; }
|
||||
float getMaterialOpacityCutoff(Material m) { return m._metallicScatteringOpacityCutoffKey.z; }
|
||||
|
||||
BITFIELD getMaterialKey(Material m) { return floatBitsToInt(m._metallicScatteringOpacityCutoffKey.w); }
|
||||
BITFIELD getMaterialKey(Material m) { return floatBitsToInt(m._metallicScatteringOpacityCutoffKey.w); }
|
||||
|
||||
const BITFIELD EMISSIVE_VAL_BIT = 0x00000001;
|
||||
const BITFIELD UNLIT_VAL_BIT = 0x00000002;
|
||||
const BITFIELD ALBEDO_VAL_BIT = 0x00000004;
|
||||
const BITFIELD METALLIC_VAL_BIT = 0x00000008;
|
||||
const BITFIELD GLOSSY_VAL_BIT = 0x00000010;
|
||||
const BITFIELD OPACITY_VAL_BIT = 0x00000020;
|
||||
const BITFIELD OPACITY_MASK_MAP_BIT = 0x00000040;
|
||||
const BITFIELD OPACITY_TRANSLUCENT_MAP_BIT = 0x00000080;
|
||||
const BITFIELD OPACITY_MAP_MODE_BIT = 0x00000100;
|
||||
const BITFIELD OPACITY_CUTOFF_VAL_BIT = 0x00000200;
|
||||
const BITFIELD SCATTERING_VAL_BIT = 0x00000400;
|
||||
const BITFIELD EMISSIVE_VAL_BIT = 0x00000001;
|
||||
const BITFIELD UNLIT_VAL_BIT = 0x00000002;
|
||||
const BITFIELD ALBEDO_VAL_BIT = 0x00000004;
|
||||
const BITFIELD METALLIC_VAL_BIT = 0x00000008;
|
||||
const BITFIELD GLOSSY_VAL_BIT = 0x00000010;
|
||||
const BITFIELD OPACITY_VAL_BIT = 0x00000020;
|
||||
const BITFIELD OPACITY_MASK_MAP_BIT = 0x00000040;
|
||||
const BITFIELD OPACITY_TRANSLUCENT_MAP_BIT = 0x00000080;
|
||||
const BITFIELD OPACITY_MAP_MODE_BIT = 0x00000100;
|
||||
const BITFIELD OPACITY_CUTOFF_VAL_BIT = 0x00000200;
|
||||
const BITFIELD SCATTERING_VAL_BIT = 0x00000400;
|
||||
|
||||
|
||||
const BITFIELD EMISSIVE_MAP_BIT = 0x00000800;
|
||||
const BITFIELD ALBEDO_MAP_BIT = 0x00001000;
|
||||
const BITFIELD METALLIC_MAP_BIT = 0x00002000;
|
||||
const BITFIELD ROUGHNESS_MAP_BIT = 0x00004000;
|
||||
const BITFIELD NORMAL_MAP_BIT = 0x00008000;
|
||||
const BITFIELD OCCLUSION_MAP_BIT = 0x00010000;
|
||||
const BITFIELD LIGHTMAP_MAP_BIT = 0x00020000;
|
||||
const BITFIELD SCATTERING_MAP_BIT = 0x00040000;
|
||||
const BITFIELD EMISSIVE_MAP_BIT = 0x00000800;
|
||||
const BITFIELD ALBEDO_MAP_BIT = 0x00001000;
|
||||
const BITFIELD METALLIC_MAP_BIT = 0x00002000;
|
||||
const BITFIELD ROUGHNESS_MAP_BIT = 0x00004000;
|
||||
const BITFIELD NORMAL_MAP_BIT = 0x00008000;
|
||||
const BITFIELD OCCLUSION_MAP_BIT = 0x00010000;
|
||||
const BITFIELD LIGHTMAP_MAP_BIT = 0x00020000;
|
||||
const BITFIELD SCATTERING_MAP_BIT = 0x00040000;
|
||||
<@else@>
|
||||
vec3 getMaterialEmissive(Material m) { return m._emissiveOpacity.rgb; }
|
||||
float getMaterialOpacity(Material m) { return m._emissiveOpacity.a; }
|
||||
|
||||
vec3 getMaterialAlbedo(Material m) { return m._albedoOpacityCutoff.rgb; }
|
||||
float getMaterialOpacityCutoff(Material m) { return m._albedoOpacityCutoff.z; }
|
||||
|
||||
vec3 getMaterialShade(Material m) { return m._shadeShadingShift.rgb; }
|
||||
float getMaterialShadingShift(Material m) { return m._shadeShadingShift.a; }
|
||||
|
||||
vec3 getMaterialMatcap(Material m) { return m._matcapShadingToony.rgb; }
|
||||
float getMaterialShadingToony(Material m) { return m._matcapShadingToony.a; }
|
||||
|
||||
vec3 getMaterialParametricRim(Material m) { return m._parametricRimAndFresnelPower.rgb; }
|
||||
float getMaterialParametricRimFresnelPower(Material m) { return m._parametricRimAndFresnelPower.a; }
|
||||
|
||||
float getMaterialParametricRimLift(Material m) { return m._parametricRimLiftMixUVAnimationScrollSpeedXY.r; }
|
||||
float getMaterialRimLightingMix(Material m) { return m._parametricRimLiftMixUVAnimationScrollSpeedXY.g; }
|
||||
|
||||
vec3 getMaterialUVScrollSpeed(Material m) { return vec3(m._parametricRimLiftMixUVAnimationScrollSpeedXY.ba, m._uvAnimationScrollRotationSpeedTimeKeySpare.r); }
|
||||
float getMaterialTime(Material m) { return m._uvAnimationScrollRotationSpeedTimeKeySpare.g; }
|
||||
|
||||
BITFIELD getMaterialKey(Material m) { return floatBitsToInt(m._uvAnimationScrollRotationSpeedTimeKeySpare.b); }
|
||||
|
||||
const BITFIELD EMISSIVE_VAL_BIT = 0x00000001;
|
||||
const BITFIELD SHADE_VAL_BIT = 0x00000002;
|
||||
const BITFIELD ALBEDO_VAL_BIT = 0x00000004;
|
||||
const BITFIELD SHADING_SHIFT_VAL_BIT = 0x00000008;
|
||||
const BITFIELD SHADING_TOONY_VAL_BIT = 0x00000010;
|
||||
const BITFIELD OPACITY_VAL_BIT = 0x00000020;
|
||||
const BITFIELD OPACITY_MASK_MAP_BIT = 0x00000040;
|
||||
const BITFIELD OPACITY_TRANSLUCENT_MAP_BIT = 0x00000080;
|
||||
const BITFIELD OPACITY_MAP_MODE_BIT = 0x00000100;
|
||||
const BITFIELD OPACITY_CUTOFF_VAL_BIT = 0x00000200;
|
||||
const BITFIELD UV_ANIMATION_SCROLL_VAL_BIT = 0x00000400;
|
||||
|
||||
const BITFIELD EMISSIVE_MAP_BIT = 0x00000800;
|
||||
const BITFIELD ALBEDO_MAP_BIT = 0x00001000;
|
||||
const BITFIELD SHADING_SHIFT_MAP_BIT = 0x00002000;
|
||||
const BITFIELD SHADE_MAP_BIT = 0x00004000;
|
||||
const BITFIELD NORMAL_MAP_BIT = 0x00008000;
|
||||
const BITFIELD MATCAP_MAP_BIT = 0x00010000;
|
||||
const BITFIELD UV_ANIMATION_MASK_MAP_BIT = 0x00020000;
|
||||
const BITFIELD RIM_MAP_BIT = 0x00040000;
|
||||
|
||||
const BITFIELD MATCAP_VAL_BIT = 0x00080000;
|
||||
const BITFIELD PARAMETRIC_RIM_VAL_BIT = 0x00100000;
|
||||
const BITFIELD PARAMETRIC_RIM_POWER_VAL_BIT = 0x00200000;
|
||||
const BITFIELD PARAMETRIC_RIM_LIFT_VAL_BIT = 0x00400000;
|
||||
const BITFIELD RIM_LIGHTING_MIX_VAL_BIT = 0x00800000;
|
||||
<@endif@>
|
||||
|
||||
<@endif@>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Sam Gateau on 2/22/16
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -14,10 +15,70 @@
|
|||
<@include graphics/ShaderConstants.h@>
|
||||
<@include graphics/Material.slh@>
|
||||
|
||||
<@func declareMaterialTextures(withAlbedo, withRoughness, withNormal, withMetallic, withEmissive, withOcclusion, withScattering)@>
|
||||
|
||||
#define TAA_TEXTURE_LOD_BIAS -1.0
|
||||
|
||||
<@func evalMaterialNormalLOD(fragPosES, fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@>
|
||||
{
|
||||
vec3 normalizedNormal = normalize(<$interpolatedNormal$>.xyz);
|
||||
vec3 normalizedTangent = normalize(<$interpolatedTangent$>.xyz);
|
||||
vec3 normalizedBitangent = cross(normalizedNormal, normalizedTangent);
|
||||
// attenuate the normal map divergence from the mesh normal based on distance
|
||||
// The attenuation range [30,100] meters from the eye is arbitrary for now
|
||||
vec3 localNormal = mix(<$fetchedNormal$>, vec3(0.0, 1.0, 0.0), smoothstep(30.0, 100.0, (-<$fragPosES$>).z));
|
||||
<$normal$> = vec3(normalizedBitangent * localNormal.x + normalizedNormal * localNormal.y + normalizedTangent * localNormal.z);
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialAlbedo(fetchedAlbedo, materialAlbedo, matKey, albedo)@>
|
||||
{
|
||||
<$albedo$>.xyz = mix(vec3(1.0), <$materialAlbedo$>, float((<$matKey$> & ALBEDO_VAL_BIT) != 0));
|
||||
<$albedo$>.xyz *= mix(vec3(1.0), <$fetchedAlbedo$>.xyz, float((<$matKey$> & ALBEDO_MAP_BIT) != 0));
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialOpacityMask(fetchedOpacity, materialOpacityCutoff, materialOpacity, matKey, opacity)@>
|
||||
{
|
||||
// This path only valid for opaque or texel opaque material
|
||||
<$opacity$> = mix(<$materialOpacity$>,
|
||||
step(<$materialOpacityCutoff$>, <$fetchedOpacity$>),
|
||||
float((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0));
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialOpacity(fetchedOpacity, materialOpacityCutoff, materialOpacity, matKey, opacity)@>
|
||||
{
|
||||
// This path only valid for transparent material
|
||||
<$opacity$> = mix(<$fetchedOpacity$>,
|
||||
step(<$materialOpacityCutoff$>, <$fetchedOpacity$>),
|
||||
float((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0))
|
||||
* <$materialOpacity$>;
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialEmissive(fetchedEmissive, materialEmissive, matKey, emissive)@>
|
||||
{
|
||||
<$emissive$> = mix(<$materialEmissive$>, <$fetchedEmissive$>, float((<$matKey$> & EMISSIVE_MAP_BIT) != 0));
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func discardTransparent(opacity)@>
|
||||
{
|
||||
if (<$opacity$> < 1.0) {
|
||||
discard;
|
||||
}
|
||||
}
|
||||
<@endfunc@>
|
||||
<@func discardInvisible(opacity)@>
|
||||
{
|
||||
if (<$opacity$> <= 0.0) {
|
||||
discard;
|
||||
}
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@if not HIFI_USE_MTOON@>
|
||||
<@func declareMaterialTextures(withAlbedo, withRoughness, withNormal, withMetallic, withEmissive, withOcclusion, withScattering)@>
|
||||
|
||||
<@include gpu/TextureTable.slh@>
|
||||
|
||||
#ifdef GPU_TEXTURE_TABLE_BINDLESS
|
||||
|
@ -41,14 +102,6 @@ vec4 fetchAlbedoMap(vec2 uv) {
|
|||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withRoughness@>
|
||||
#define roughnessMap 4
|
||||
float fetchRoughnessMap(vec2 uv) {
|
||||
// Should take into account TAA_TEXTURE_LOD_BIAS?
|
||||
return tableTexValue(matTex, roughnessMap, uv).r;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withNormal@>
|
||||
#define normalMap 1
|
||||
vec3 fetchNormalMap(vec2 uv) {
|
||||
|
@ -73,6 +126,14 @@ vec3 fetchEmissiveMap(vec2 uv) {
|
|||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withRoughness@>
|
||||
#define roughnessMap 4
|
||||
float fetchRoughnessMap(vec2 uv) {
|
||||
// Should take into account TAA_TEXTURE_LOD_BIAS?
|
||||
return tableTexValue(matTex, roughnessMap, uv).r;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withOcclusion@>
|
||||
#define occlusionMap 5
|
||||
float fetchOcclusionMap(vec2 uv) {
|
||||
|
@ -98,13 +159,6 @@ vec4 fetchAlbedoMap(vec2 uv) {
|
|||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withRoughness@>
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS) uniform sampler2D roughnessMap;
|
||||
float fetchRoughnessMap(vec2 uv) {
|
||||
return (texture(roughnessMap, uv, TAA_TEXTURE_LOD_BIAS).r);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withNormal@>
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL) uniform sampler2D normalMap;
|
||||
vec3 fetchNormalMap(vec2 uv) {
|
||||
|
@ -129,6 +183,13 @@ vec3 fetchEmissiveMap(vec2 uv) {
|
|||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withRoughness@>
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS) uniform sampler2D roughnessMap;
|
||||
float fetchRoughnessMap(vec2 uv) {
|
||||
return (texture(roughnessMap, uv, TAA_TEXTURE_LOD_BIAS).r);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withOcclusion@>
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_OCCLUSION) uniform sampler2D occlusionMap;
|
||||
float fetchOcclusionMap(vec2 uv) {
|
||||
|
@ -183,7 +244,6 @@ float fetchScatteringMap(vec2 uv) {
|
|||
<@endfunc@>
|
||||
|
||||
|
||||
|
||||
<@func declareMaterialLightmap()@>
|
||||
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
@ -195,59 +255,6 @@ vec3 fetchLightMap(vec2 uv) {
|
|||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialNormalLOD(fragPosES, fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@>
|
||||
{
|
||||
vec3 normalizedNormal = normalize(<$interpolatedNormal$>.xyz);
|
||||
vec3 normalizedTangent = normalize(<$interpolatedTangent$>.xyz);
|
||||
vec3 normalizedBitangent = cross(normalizedNormal, normalizedTangent);
|
||||
// attenuate the normal map divergence from the mesh normal based on distance
|
||||
// The attenuation range [30,100] meters from the eye is arbitrary for now
|
||||
vec3 localNormal = mix(<$fetchedNormal$>, vec3(0.0, 1.0, 0.0), smoothstep(30.0, 100.0, (-<$fragPosES$>).z));
|
||||
<$normal$> = vec3(normalizedBitangent * localNormal.x + normalizedNormal * localNormal.y + normalizedTangent * localNormal.z);
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialAlbedo(fetchedAlbedo, materialAlbedo, matKey, albedo)@>
|
||||
{
|
||||
<$albedo$>.xyz = mix(vec3(1.0), <$materialAlbedo$>, float((<$matKey$> & ALBEDO_VAL_BIT) != 0));
|
||||
<$albedo$>.xyz *= mix(vec3(1.0), <$fetchedAlbedo$>.xyz, float((<$matKey$> & ALBEDO_MAP_BIT) != 0));
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialOpacityMask(fetchedOpacity, materialOpacityCutoff, materialOpacity, matKey, opacity)@>
|
||||
{
|
||||
// This path only valid for opaque or texel opaque material
|
||||
<$opacity$> = mix(<$materialOpacity$>,
|
||||
step(<$materialOpacityCutoff$>, <$fetchedOpacity$>),
|
||||
float((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0));
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialOpacity(fetchedOpacity, materialOpacityCutoff, materialOpacity, matKey, opacity)@>
|
||||
{
|
||||
// This path only valid for transparent material
|
||||
<$opacity$> = mix(<$fetchedOpacity$>,
|
||||
step(<$materialOpacityCutoff$>, <$fetchedOpacity$>),
|
||||
float((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0))
|
||||
* <$materialOpacity$>;
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func discardTransparent(opacity)@>
|
||||
{
|
||||
if (<$opacity$> < 1.0) {
|
||||
discard;
|
||||
}
|
||||
}
|
||||
<@endfunc@>
|
||||
<@func discardInvisible(opacity)@>
|
||||
{
|
||||
if (<$opacity$> <= 0.0) {
|
||||
discard;
|
||||
}
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialRoughness(fetchedRoughness, materialRoughness, matKey, roughness)@>
|
||||
{
|
||||
<$roughness$> = mix(<$materialRoughness$>, <$fetchedRoughness$>, float((<$matKey$> & ROUGHNESS_MAP_BIT) != 0));
|
||||
|
@ -260,12 +267,6 @@ vec3 fetchLightMap(vec2 uv) {
|
|||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialEmissive(fetchedEmissive, materialEmissive, matKey, emissive)@>
|
||||
{
|
||||
<$emissive$> = mix(<$materialEmissive$>, <$fetchedEmissive$>, float((<$matKey$> & EMISSIVE_MAP_BIT) != 0));
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialOcclusion(fetchedOcclusion, matKey, occlusion)@>
|
||||
{
|
||||
<$occlusion$> = <$fetchedOcclusion$>;
|
||||
|
@ -277,5 +278,214 @@ vec3 fetchLightMap(vec2 uv) {
|
|||
<$scattering$> = mix(<$materialScattering$>, <$fetchedScattering$>, float((<$matKey$> & SCATTERING_MAP_BIT) != 0));
|
||||
}
|
||||
<@endfunc@>
|
||||
<@else@>
|
||||
<@func declareMToonMaterialTextures(withAlbedo, withNormal, withShade, withEmissive, withShadingShift, withMatcap, withRim, withUVAnimationMask)@>
|
||||
|
||||
<@endif@>
|
||||
<@include gpu/TextureTable.slh@>
|
||||
|
||||
#ifdef GPU_TEXTURE_TABLE_BINDLESS
|
||||
|
||||
TextureTable(0, matTex);
|
||||
<!
|
||||
ALBEDO = 0,
|
||||
NORMAL, 1
|
||||
SHADE, 2
|
||||
EMISSIVE, 3
|
||||
SHADING_SHIFT, 4
|
||||
MATCAP, 5
|
||||
RIM, 6
|
||||
UV_ANIMATION_MASK, 7
|
||||
!>
|
||||
|
||||
<@if withAlbedo@>
|
||||
#define albedoMap 0
|
||||
vec4 fetchAlbedoMap(vec2 uv) {
|
||||
return tableTexValue(matTex, albedoMap, uv);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withNormal@>
|
||||
#define normalMap 1
|
||||
vec3 fetchNormalMap(vec2 uv) {
|
||||
return tableTexValue(matTex, normalMap, uv).xyz;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withShade@>
|
||||
#define shadeMap 2
|
||||
vec3 fetchShadeMap(vec2 uv) {
|
||||
return tableTexValue(matTex, shadeMap, uv).rgb;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withEmissive@>
|
||||
#define emissiveMap 3
|
||||
vec3 fetchEmissiveMap(vec2 uv) {
|
||||
return tableTexValue(matTex, emissiveMap, uv).rgb;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withShadingShift@>
|
||||
#define shadingShiftMap 4
|
||||
float fetchShadingShiftMap(vec2 uv) {
|
||||
return tableTexValue(matTex, shadingShiftMap, uv).r;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withMatcap@>
|
||||
#define matcapMap 5
|
||||
vec3 fetchMatcapMap(vec2 uv) {
|
||||
return tableTexValue(matTex, matcapMap, uv).rgb;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withRim@>
|
||||
#define rimMap 6
|
||||
vec3 fetchRimMap(vec2 uv) {
|
||||
return tableTexValue(matTex, rimMap, uv).rgb;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withUVAnimationMask@>
|
||||
#define uvAnimationMaskMap 7
|
||||
float fetchUVAnimationMaskMap(vec2 uv) {
|
||||
return tableTexValue(matTex, uvAnimationMaskMap, uv).r;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
#else
|
||||
|
||||
<@if withAlbedo@>
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO) uniform sampler2D albedoMap;
|
||||
vec4 fetchAlbedoMap(vec2 uv) {
|
||||
return texture(albedoMap, uv, TAA_TEXTURE_LOD_BIAS);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withNormal@>
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL) uniform sampler2D normalMap;
|
||||
vec3 fetchNormalMap(vec2 uv) {
|
||||
// unpack normal, swizzle to get into hifi tangent space with Y axis pointing out
|
||||
vec2 t = 2.0 * (texture(normalMap, uv, TAA_TEXTURE_LOD_BIAS).rg - vec2(0.5, 0.5));
|
||||
vec2 t2 = t*t;
|
||||
return vec3(t.x, sqrt(max(0.0, 1.0 - t2.x - t2.y)), t.y);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withShade@>
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_SHADE) uniform sampler2D shadeMap;
|
||||
vec3 fetchShadeMap(vec2 uv) {
|
||||
return texture(shadeMap, uv, TAA_TEXTURE_LOD_BIAS).rgb;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withEmissive@>
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap;
|
||||
vec3 fetchEmissiveMap(vec2 uv) {
|
||||
return texture(emissiveMap, uv, TAA_TEXTURE_LOD_BIAS).rgb;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withShadingShift@>
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_SHADING_SHIFT) uniform sampler2D shadingShiftMap;
|
||||
float fetchShadingShiftMap(vec2 uv) {
|
||||
return texture(shadingShiftMap, uv, TAA_TEXTURE_LOD_BIAS).r;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withMatcap@>
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_MATCAP) uniform sampler2D matcapMap;
|
||||
vec3 fetchMatcapMap(vec2 uv) {
|
||||
return texture(matcapMap, uv, TAA_TEXTURE_LOD_BIAS).rgb;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withRim@>
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_RIM) uniform sampler2D rimMap;
|
||||
vec3 fetchRimMap(vec2 uv) {
|
||||
return texture(rimMap, uv, TAA_TEXTURE_LOD_BIAS).rgb;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withUVAnimationMask@>
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_UV_ANIMATION_MASK) uniform sampler2D uvAnimationMaskMap;
|
||||
float fetchUVAnimationMaskMap(vec2 uv) {
|
||||
return texture(uvAnimationMaskMap, uv, TAA_TEXTURE_LOD_BIAS).r;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
#endif
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
<@func fetchMToonMaterialTexturesCoord0(matKey, texcoord0, albedo, normal, shade, emissive, shadingShift, rim, uvScrollSpeed, time)@>
|
||||
if (getTexMapArray()._materialParams.y != 1.0 && clamp(<$texcoord0$>, vec2(0.0), vec2(1.0)) != <$texcoord0$>) {
|
||||
discard;
|
||||
}
|
||||
|
||||
vec2 texCoord = <$texcoord0$>;
|
||||
|
||||
<@if uvScrollSpeed and time@>
|
||||
if ((<$matKey$> & UV_ANIMATION_SCROLL_VAL_BIT) != 0) {
|
||||
<$uvScrollSpeed$> *= mix(1.0, fetchUVAnimationMaskMap(texCoord), float((<$matKey$> & UV_ANIMATION_MASK_MAP_BIT) != 0));
|
||||
<$uvScrollSpeed$> *= time;
|
||||
float cosTime = cos(<$uvScrollSpeed$>.z);
|
||||
float sinTime = sin(<$uvScrollSpeed$>.z);
|
||||
texCoord = (mat3(cosTime, sinTime, 0, -sinTime, cosTime, 0, 0, 0, 1) * vec3(texCoord - vec2(0.5), 1.0)).xy + vec2(0.5) + <$uvScrollSpeed$>.xy;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if albedo@>
|
||||
vec4 <$albedo$> = mix(vec4(1.0), fetchAlbedoMap(texCoord), float((<$matKey$> & (ALBEDO_MAP_BIT | OPACITY_MASK_MAP_BIT | OPACITY_TRANSLUCENT_MAP_BIT)) != 0));
|
||||
<@endif@>
|
||||
<@if normal@>
|
||||
vec3 <$normal$> = mix(vec3(0.0, 1.0, 0.0), fetchNormalMap(texCoord), float((<$matKey$> & NORMAL_MAP_BIT) != 0));
|
||||
<@endif@>
|
||||
<@if shade@>
|
||||
vec3 <$shade$> = float((<$matKey$> & SHADE_MAP_BIT) != 0) * fetchShadeMap(texCoord);
|
||||
<@endif@>
|
||||
<@if emissive@>
|
||||
vec3 <$emissive$> = float((<$matKey$> & EMISSIVE_MAP_BIT) != 0) * fetchEmissiveMap(texCoord);
|
||||
<@endif@>
|
||||
<@if shadingShift@>
|
||||
float <$shadingShift$> = float((<$matKey$> & SHADING_SHIFT_MAP_BIT) != 0) * fetchShadingShiftMap(texCoord);
|
||||
<@endif@>
|
||||
<@if rim@>
|
||||
vec3 <$rim$> = mix(vec3(1.0), fetchRimMap(texCoord), float((<$matKey$> & RIM_MAP_BIT) != 0));
|
||||
<@endif@>
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialShade(fetchedShade, materialShade, matKey, shade)@>
|
||||
{
|
||||
<$shade$> = mix(vec3(1.0), <$materialShade$>, float((<$matKey$> & SHADE_VAL_BIT) != 0));
|
||||
<$shade$> *= mix(vec3(1.0), <$fetchedShade$>.rgb, float((<$matKey$> & SHADE_MAP_BIT) != 0));
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialShadingShift(fetchedShadingShift, materialShadingShift, matKey, shadingShift)@>
|
||||
{
|
||||
<$shadingShift$> = mix(0.0, <$materialShadingShift$>, float((<$matKey$> & SHADING_SHIFT_VAL_BIT) != 0));
|
||||
<$shadingShift$> += mix(0.0, <$fetchedShadingShift$>.r, float((<$matKey$> & SHADING_SHIFT_MAP_BIT) != 0));
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialMatcap(texcoord0, materialMatcap, matKey, matcap)@>
|
||||
{
|
||||
if ((<$matKey$> & (MATCAP_VAL_BIT | MATCAP_MAP_BIT)) == 0) {
|
||||
<$matcap$> = vec3(0.0);
|
||||
} else {
|
||||
<$matcap$> = mix(vec3(1.0), <$materialMatcap$>, float((<$matKey$> & MATCAP_VAL_BIT) != 0));
|
||||
<$matcap$> *= mix(vec3(1.0), fetchMatcapMap(<$texcoord0$>), float((<$matKey$> & MATCAP_MAP_BIT) != 0));
|
||||
}
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialUVScrollSpeed(fetchedUVScrollMask, materialUVScrollMask, matKey, uvScrollSpeed)@>
|
||||
{
|
||||
<$uvScrollSpeed$> = mix(vec3(1.0), <$materialUVScrollMask$>, float((<$matKey$> & UV_ANIMATION_MASK_MAP_BIT) != 0));
|
||||
<$uvScrollSpeed$> *= mix(1.0, <$fetchedUVScrollMask$>.r, float((<$matKey$> & UV_ANIMATION_MASK_MAP_BIT) != 0));
|
||||
}
|
||||
<@endfunc@>
|
||||
<@endif@>
|
||||
|
||||
<@endif@>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// <!
|
||||
// Created by Bradley Austin Davis on 2018/05/25
|
||||
// Copyright 2013-2018 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -28,6 +29,13 @@
|
|||
#define GRAPHICS_TEXTURE_MATERIAL_OCCLUSION 5
|
||||
#define GRAPHICS_TEXTURE_MATERIAL_SCATTERING 6
|
||||
|
||||
// Keep aligned with procedural/ProceduralMaterialCache.h
|
||||
#define GRAPHICS_TEXTURE_MATERIAL_SHADE GRAPHICS_TEXTURE_MATERIAL_METALLIC
|
||||
#define GRAPHICS_TEXTURE_MATERIAL_SHADING_SHIFT GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS
|
||||
#define GRAPHICS_TEXTURE_MATERIAL_MATCAP GRAPHICS_TEXTURE_MATERIAL_OCCLUSION
|
||||
#define GRAPHICS_TEXTURE_MATERIAL_RIM GRAPHICS_TEXTURE_MATERIAL_SCATTERING
|
||||
#define GRAPHICS_TEXTURE_MATERIAL_UV_ANIMATION_MASK 7
|
||||
|
||||
// Make sure these match the ones in render-utils/ShaderConstants.h
|
||||
#define GRAPHICS_TEXTURE_SKYBOX 11
|
||||
#define GRAPHICS_BUFFER_SKYBOX_PARAMS 5
|
||||
|
@ -59,7 +67,13 @@ enum Texture {
|
|||
MaterialRoughness = GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS,
|
||||
MaterialOcclusion = GRAPHICS_TEXTURE_MATERIAL_OCCLUSION,
|
||||
MaterialScattering = GRAPHICS_TEXTURE_MATERIAL_SCATTERING,
|
||||
Skybox = GRAPHICS_TEXTURE_SKYBOX
|
||||
Skybox = GRAPHICS_TEXTURE_SKYBOX,
|
||||
|
||||
MaterialShade = GRAPHICS_TEXTURE_MATERIAL_SHADE,
|
||||
MaterialShadingShift = GRAPHICS_TEXTURE_MATERIAL_SHADING_SHIFT,
|
||||
MaterialMatcap = GRAPHICS_TEXTURE_MATERIAL_MATCAP,
|
||||
MaterialRim = GRAPHICS_TEXTURE_MATERIAL_RIM,
|
||||
MaterialUVAnimationMask = GRAPHICS_TEXTURE_MATERIAL_UV_ANIMATION_MASK,
|
||||
};
|
||||
} // namespace texture
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//
|
||||
// Created by Sam Gondelman on 2/9/2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -128,36 +129,35 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseMaterialF
|
|||
* @typedef {object} Entities.Material
|
||||
* @property {string} name="" - A name for the material. Supported by all material models.
|
||||
* @property {string} model="hifi_pbr" - Different material models support different properties and rendering modes.
|
||||
* Supported models are: <code>"hifi_pbr"</code>, <code>"hifi_shader_simple"</code>.
|
||||
* Supported models are: <code>"hifi_pbr"</code>, <code>"hifi_shader_simple"</code>, and <code>"vrm_mtoon"</code>.
|
||||
* @property {ColorFloat|RGBS|string} emissive - The emissive color, i.e., the color that the material emits. A
|
||||
* {@link ColorFloat} value is treated as sRGB and must have component values in the range <code>0.0</code> –
|
||||
* <code>1.0</code>. A {@link RGBS} value can be either RGB or sRGB.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>,
|
||||
* <code>"vrm_mtoon"</code>.
|
||||
* @property {number|string} opacity=1.0 - The opacity, range <code>0.0</code> – <code>1.0</code>.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> and
|
||||
* <code>"hifi_shader_simple"</code> models only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: all.
|
||||
* @property {boolean|string} unlit=false - <code>true</code> if the material is unaffected by lighting, <code>false</code> if
|
||||
* it is lit by the key light and local lights.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>.
|
||||
* @property {ColorFloat|RGBS|string} albedo - The albedo color. A {@link ColorFloat} value is treated as sRGB and must have
|
||||
* component values in the range <code>0.0</code> – <code>1.0</code>. A {@link RGBS} value can be either RGB or sRGB.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> and
|
||||
* <code>"hifi_shader_simple"</code> models only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: all.
|
||||
* @property {number|string} roughness - The roughness, range <code>0.0</code> – <code>1.0</code>.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>.
|
||||
* @property {number|string} metallic - The metallicness, range <code>0.0</code> – <code>1.0</code>.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>.
|
||||
* @property {number|string} scattering - The scattering, range <code>0.0</code> – <code>1.0</code>.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>.
|
||||
* @property {string} emissiveMap - The URL of the emissive texture image, or an entity ID. An entity ID may be that of an
|
||||
* Image or Web entity. Set to <code>"fallthrough"</code> to fall through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* Image or Web entity. Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>,
|
||||
* <code>"vrm_mtoon"</code>.
|
||||
* @property {string} albedoMap - The URL of the albedo texture image, or an entity ID. An entity ID may be that of an Image
|
||||
* or Web entity. Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code>
|
||||
* model only.
|
||||
* or Web entity. Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>,
|
||||
* <code>"vrm_mtoon"</code>.
|
||||
* @property {string} opacityMap - The URL of the opacity texture image, or an entity ID. An entity ID may be that of an Image
|
||||
* or Web entity. Set the value the same as the <code>albedoMap</code> value for transparency.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* or Web entity. Set the value the same as the <code>albedoMap</code> value for transparency. Supported models: <code>"hifi_pbr"</code>,
|
||||
* <code>"vrm_mtoon"</code>.
|
||||
* @property {string} opacityMapMode - The mode defining the interpretation of the opacity map. Values can be:
|
||||
* <ul>
|
||||
* <li><code>"OPACITY_MAP_OPAQUE"</code> for ignoring the opacity map information.</li>
|
||||
|
@ -166,67 +166,113 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseMaterialF
|
|||
* <li><code>"OPACITY_MAP_BLEND"</code> for using the <code>opacityMap</code> for alpha blending the material surface
|
||||
* with the background.</li>
|
||||
* </ul>
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: all.
|
||||
* @property {number|string} opacityCutoff - The opacity cutoff threshold used to determine the opaque texels of the
|
||||
* <code>opacityMap</code> when <code>opacityMapMode</code> is <code>"OPACITY_MAP_MASK"</code>. Range <code>0.0</code>
|
||||
* – <code>1.0</code>.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: all.
|
||||
* @property {string} cullFaceMode="CULL_BACK" - The mode defining which side of the geometry should be rendered. Values can be:
|
||||
* <ul>
|
||||
* <li><code>"CULL_NONE"</code> to render both sides of the geometry.</li>
|
||||
* <li><code>"CULL_FRONT"</code> to cull the front faces of the geometry.</li>
|
||||
* <li><code>"CULL_BACK"</code> (the default) to cull the back faces of the geometry.</li>
|
||||
* </ul>
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* @property {string} cullFaceMode - The mode defining which side of the geometry should be rendered. Values can be:
|
||||
* <ul>
|
||||
* <li><code>"CULL_NONE"</code> for rendering both sides of the geometry.</li>
|
||||
* <li><code>"CULL_FRONT"</code> for culling the front faces of the geometry.</li>
|
||||
* <li><code>"CULL_BACK"</code> (the default) for culling the back faces of the geometry.</li>
|
||||
* </ul>
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: all.
|
||||
* @property {string} roughnessMap - The URL of the roughness texture image. You can use this or <code>glossMap</code>, but not
|
||||
* both.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>.
|
||||
* @property {string} glossMap - The URL of the gloss texture image. You can use this or <code>roughnessMap</code>, but not
|
||||
* both.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>.
|
||||
* @property {string} metallicMap - The URL of the metallic texture image, or an entity ID. An entity ID may be that of an
|
||||
* Image or Web entity. You can use this or <code>specularMap</code>, but not both.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>.
|
||||
* @property {string} specularMap - The URL of the specular texture image, or an entity ID. An entity ID may be that of an
|
||||
* Image or Web entity. You can use this or <code>metallicMap</code>, but not both.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>.
|
||||
* @property {string} normalMap - The URL of the normal texture image, or an entity ID. An entity ID may be that of an Image
|
||||
* or Web entity. You can use this or <code>bumpMap</code>, but not both. Set to <code>"fallthrough"</code> to fall
|
||||
* through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* through to the material below. Supported models: <code>"hifi_pbr"</code>, <code>"vrm_mtoon"</code>.
|
||||
* @property {string} bumpMap - The URL of the bump texture image, or an entity ID. An entity ID may be that of an Image
|
||||
* or Web entity. You can use this or <code>normalMap</code>, but not both. Set to <code>"fallthrough"</code> to
|
||||
* fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* fall through to the material below. Supported models: <code>"hifi_pbr"</code>, <code>"vrm_mtoon"</code>.
|
||||
* @property {string} occlusionMap - The URL of the occlusion texture image, or an entity ID. An entity ID may be that of
|
||||
* an Image or Web entity. Set to <code>"fallthrough"</code> to fall through to the material below.
|
||||
* <code>"hifi_pbr"</code> model only.
|
||||
* Supported models: <code>"hifi_pbr"</code>.
|
||||
* @property {string} scatteringMap - The URL of the scattering texture image, or an entity ID. An entity ID may be that of an
|
||||
* Image or Web entity. Only used if <code>normalMap</code> or <code>bumpMap</code> is specified.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>.
|
||||
* @property {string} lightMap - The URL of the light map texture image, or an entity ID. An entity ID may be that of an Image
|
||||
* or Web entity. Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code>
|
||||
* model only.
|
||||
* or Web entity. Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>.
|
||||
* @property {Mat4|string} texCoordTransform0 - The transform to use for all of the maps apart from <code>occlusionMap</code>
|
||||
* and <code>lightMap</code>.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>, <code>"vrm_mtoon"</code>.
|
||||
* @property {Mat4|string} texCoordTransform1 - The transform to use for <code>occlusionMap</code> and <code>lightMap</code>.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>, <code>"vrm_mtoon"</code>.
|
||||
* @property {string} lightmapParams - Parameters for controlling how <code>lightMap</code> is used.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>.
|
||||
* <p><em>Currently not used.</em></p>
|
||||
* @property {string} materialParams - Parameters for controlling the material projection and repetition.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"hifi_pbr"</code>, <code>"vrm_mtoon"</code>.
|
||||
* <p><em>Currently not used.</em></p>
|
||||
* @property {boolean} defaultFallthrough=false - <code>true</code> if all properties fall through to the material below
|
||||
* unless they are set, <code>false</code> if properties respect their individual fall-through settings.
|
||||
* <code>"hifi_pbr"</code> and <code>"hifi_shader_simple"</code> models only.
|
||||
* @property {ProceduralData} procedural - The definition of a procedural shader material. <code>"hifi_shader_simple"</code> model only.
|
||||
* Supported models: all.
|
||||
* @property {ProceduralData} procedural - The definition of a procedural shader material. Supported models: <code>"hifi_shader_simple"</code>.
|
||||
* @property {ColorFloat|RGBS|string} shade - The shade color. A {@link ColorFloat} value is treated as sRGB and must have
|
||||
* component values in the range <code>0.0</code> – <code>1.0</code>. A {@link RGBS} value can be either RGB or sRGB.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {string} shadeMap - The URL of the shade texture image, or an entity ID. An entity ID may be that of an
|
||||
* Image or Web entity.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {number|string} shadingShift - The shading shift.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {string} shadingShiftMap - The URL of the shading shift texture image, or an entity ID. An entity ID may be that of an
|
||||
* Image or Web entity.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {number|string} shadingToony - The shading toony factor. Range <code>0.0</code> – <code>1.0</code>.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {ColorFloat|RGBS|string} matcap - The matcap color. A {@link ColorFloat} value is treated as sRGB and must have
|
||||
* component values in the range <code>0.0</code> – <code>1.0</code>. A {@link RGBS} value can be either RGB or sRGB.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {string} matcapMap - The URL of the matcap texture image, or an entity ID. An entity ID may be that of an
|
||||
* Image or Web entity.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {ColorFloat|RGBS|string} parametricRim - The rim color. A {@link ColorFloat} value is treated as sRGB and must have
|
||||
* component values in the range <code>0.0</code> – <code>1.0</code>. A {@link RGBS} value can be either RGB or sRGB.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {number|string} parametricRimFresnelPower - The parametric rim fresnel exponent.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {number|string} parametricRimLift - The parametric rim lift factor.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {string} rimMap - The URL of the rim texture image, or an entity ID. An entity ID may be that of an
|
||||
* Image or Web entity.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {number|string} rimLightingMix - How much to mix between the rim color and normal lighting. Range <code>0.0</code>
|
||||
* – <code>1.0</code>.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {string} outlineWidthMode="none" - The mode defining how to render the outline. Values can be:
|
||||
* <ul>
|
||||
* <li><code>"none"</code> (the default) to not render an outline.</li>
|
||||
* <li><code>"worldCoordinates"</code> to render an outline with a constant world size, i.e. its apparent size depends on distance.</li>
|
||||
* <li><code>"screenCoordinates"</code> to render an outline with a constant screen size, i.e. its apparent size remains constant.</li>
|
||||
* </ul>
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {number|string} outlineWidth - The width of the outline, in meters if <code>outlineWidthMode</code> is <code>"worldCoordinates"</code>,
|
||||
* or a ratio of the screen height if <code>outlineWidthMode</code> is <code>"screenCoordinates"</code>.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {ColorFloat|RGBS|string} outline - The outline color. A {@link ColorFloat} value is treated as sRGB and must have
|
||||
* component values in the range <code>0.0</code> – <code>1.0</code>. A {@link RGBS} value can be either RGB or sRGB.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {string} uvAnimationMaskMap - The URL of the UV animation mask texture image, or an entity ID. An entity ID may be that of an
|
||||
* Image or Web entity.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {number|string} uvAnimationScrollXSpeed - The speed of the UV scrolling animation in the X dimension, in UV units per second.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {number|string} uvAnimationScrollYSpeed - The speed of the UV scrolling animation in the Y dimension, in UV units per second.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
* @property {number|string} uvAnimationRotationSpeed - The speed of the UV scrolling rotation about (0.5, 0.5), in radians per second.
|
||||
* Set to <code>"fallthrough"</code> to fall through to the material below. Supported models: <code>"vrm_mtoon"</code>.
|
||||
*/
|
||||
// Note: See MaterialEntityItem.h for default values used in practice.
|
||||
std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource::parseJSONMaterial(const QJsonValue& materialJSONValue, const QUrl& baseUrl) {
|
||||
|
@ -254,8 +300,13 @@ std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource
|
|||
std::array<glm::mat4, graphics::Material::NUM_TEXCOORD_TRANSFORMS> texcoordTransforms;
|
||||
|
||||
const QString FALLTHROUGH("fallthrough");
|
||||
if (modelString == graphics::Material::HIFI_PBR) {
|
||||
auto material = std::make_shared<NetworkMaterial>();
|
||||
if (modelString == graphics::Material::HIFI_PBR || modelString == graphics::Material::VRM_MTOON) {
|
||||
std::shared_ptr<NetworkMaterial> material;
|
||||
if (modelString == graphics::Material::HIFI_PBR) {
|
||||
material = std::make_shared<NetworkMaterial>();
|
||||
} else {
|
||||
material = std::make_shared<NetworkMToonMaterial>();
|
||||
}
|
||||
for (auto& key : materialJSON.keys()) {
|
||||
if (key == "name") {
|
||||
auto nameJSON = materialJSON.value(key);
|
||||
|
@ -282,13 +333,6 @@ std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource
|
|||
} else if (value.isDouble()) {
|
||||
material->setOpacity(value.toDouble());
|
||||
}
|
||||
} else if (key == "unlit") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::UNLIT_VAL_BIT);
|
||||
} else if (value.isBool()) {
|
||||
material->setUnlit(value.toBool());
|
||||
}
|
||||
} else if (key == "albedo") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
|
@ -301,21 +345,7 @@ std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource
|
|||
material->setAlbedo(color, isSRGB);
|
||||
}
|
||||
}
|
||||
} else if (key == "roughness") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::GLOSSY_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
material->setRoughness(value.toDouble());
|
||||
}
|
||||
} else if (key == "metallic") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::METALLIC_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
material->setMetallic(value.toDouble());
|
||||
}
|
||||
} else if (key == "opacityMapMode") {
|
||||
} else if (key == "opacityMapMode") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
|
@ -348,14 +378,7 @@ std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (key == "scattering") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::SCATTERING_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
material->setScattering(value.toDouble());
|
||||
}
|
||||
} else if (key == "emissiveMap") {
|
||||
} else if (key == "emissiveMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
|
@ -380,46 +403,6 @@ std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource
|
|||
material->setAlbedoMap(baseUrl.resolved(valueString), useAlphaChannel);
|
||||
}
|
||||
}
|
||||
} else if (key == "roughnessMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::ROUGHNESS_MAP_BIT);
|
||||
} else {
|
||||
material->setRoughnessMap(baseUrl.resolved(valueString), false);
|
||||
}
|
||||
}
|
||||
} else if (key == "glossMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::ROUGHNESS_MAP_BIT);
|
||||
} else {
|
||||
material->setRoughnessMap(baseUrl.resolved(valueString), true);
|
||||
}
|
||||
}
|
||||
} else if (key == "metallicMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::METALLIC_MAP_BIT);
|
||||
} else {
|
||||
material->setMetallicMap(baseUrl.resolved(valueString), false);
|
||||
}
|
||||
}
|
||||
} else if (key == "specularMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::METALLIC_MAP_BIT);
|
||||
} else {
|
||||
material->setMetallicMap(baseUrl.resolved(valueString), true);
|
||||
}
|
||||
}
|
||||
} else if (key == "normalMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
|
@ -440,36 +423,6 @@ std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource
|
|||
material->setNormalMap(baseUrl.resolved(valueString), true);
|
||||
}
|
||||
}
|
||||
} else if (key == "occlusionMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::OCCLUSION_MAP_BIT);
|
||||
} else {
|
||||
material->setOcclusionMap(baseUrl.resolved(valueString));
|
||||
}
|
||||
}
|
||||
} else if (key == "scatteringMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::SCATTERING_MAP_BIT);
|
||||
} else {
|
||||
material->setScatteringMap(baseUrl.resolved(valueString));
|
||||
}
|
||||
}
|
||||
} else if (key == "lightMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::LIGHT_MAP_BIT);
|
||||
} else {
|
||||
material->setLightMap(baseUrl.resolved(valueString));
|
||||
}
|
||||
}
|
||||
} else if (key == "texCoordTransform0") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
|
@ -494,15 +447,6 @@ std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource
|
|||
glm::mat4 transform = mat4FromVariant(valueVariant);
|
||||
texcoordTransforms[1] = transform;
|
||||
}
|
||||
} else if (key == "lightmapParams") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::Material::ExtraFlagBit::LIGHTMAP_PARAMS);
|
||||
}
|
||||
}
|
||||
// TODO: implement lightmapParams and update JSDoc
|
||||
} else if (key == "materialParams") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
|
@ -518,6 +462,295 @@ std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource
|
|||
material->setDefaultFallthrough(value.toBool());
|
||||
}
|
||||
}
|
||||
|
||||
if (modelString == graphics::Material::HIFI_PBR) {
|
||||
if (key == "unlit") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::UNLIT_VAL_BIT);
|
||||
} else if (value.isBool()) {
|
||||
material->setUnlit(value.toBool());
|
||||
}
|
||||
} else if (key == "roughness") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::GLOSSY_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
material->setRoughness(value.toDouble());
|
||||
}
|
||||
} else if (key == "metallic") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::METALLIC_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
material->setMetallic(value.toDouble());
|
||||
}
|
||||
} else if (key == "scattering") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::SCATTERING_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
material->setScattering(value.toDouble());
|
||||
}
|
||||
} else if (key == "roughnessMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::ROUGHNESS_MAP_BIT);
|
||||
} else {
|
||||
material->setRoughnessMap(baseUrl.resolved(valueString), false);
|
||||
}
|
||||
}
|
||||
} else if (key == "glossMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::ROUGHNESS_MAP_BIT);
|
||||
} else {
|
||||
material->setRoughnessMap(baseUrl.resolved(valueString), true);
|
||||
}
|
||||
}
|
||||
} else if (key == "metallicMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::METALLIC_MAP_BIT);
|
||||
} else {
|
||||
material->setMetallicMap(baseUrl.resolved(valueString), false);
|
||||
}
|
||||
}
|
||||
} else if (key == "specularMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::METALLIC_MAP_BIT);
|
||||
} else {
|
||||
material->setMetallicMap(baseUrl.resolved(valueString), true);
|
||||
}
|
||||
}
|
||||
} else if (key == "occlusionMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::OCCLUSION_MAP_BIT);
|
||||
} else {
|
||||
material->setOcclusionMap(baseUrl.resolved(valueString));
|
||||
}
|
||||
}
|
||||
} else if (key == "scatteringMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::SCATTERING_MAP_BIT);
|
||||
} else {
|
||||
material->setScatteringMap(baseUrl.resolved(valueString));
|
||||
}
|
||||
}
|
||||
} else if (key == "lightMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::LIGHT_MAP_BIT);
|
||||
} else {
|
||||
material->setLightMap(baseUrl.resolved(valueString));
|
||||
}
|
||||
}
|
||||
} else if (key == "lightmapParams") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::Material::ExtraFlagBit::LIGHTMAP_PARAMS);
|
||||
}
|
||||
}
|
||||
// TODO: implement lightmapParams and update JSDoc
|
||||
}
|
||||
} else if (modelString == graphics::Material::VRM_MTOON) {
|
||||
auto toonMaterial = std::static_pointer_cast<NetworkMToonMaterial>(material);
|
||||
if (key == "shade") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::SHADE_VAL_BIT);
|
||||
} else {
|
||||
glm::vec3 color;
|
||||
bool isSRGB;
|
||||
bool valid = parseJSONColor(value, color, isSRGB);
|
||||
if (valid) {
|
||||
toonMaterial->setShade(color, isSRGB);
|
||||
}
|
||||
}
|
||||
} else if (key == "shadeMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::SHADE_MAP_BIT);
|
||||
} else {
|
||||
toonMaterial->setShadeMap(baseUrl.resolved(valueString));
|
||||
}
|
||||
}
|
||||
} else if (key == "shadingShift") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::SHADING_SHIFT_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
toonMaterial->setShadingShift(value.toDouble());
|
||||
}
|
||||
} else if (key == "shadingShiftMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::SHADING_SHIFT_MAP_BIT);
|
||||
} else {
|
||||
toonMaterial->setShadingShiftMap(baseUrl.resolved(valueString));
|
||||
}
|
||||
}
|
||||
} else if (key == "shadingToony") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::SHADING_TOONY_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
toonMaterial->setShadingToony(value.toDouble());
|
||||
}
|
||||
} else if (key == "matcap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::MATCAP_VAL_BIT);
|
||||
} else {
|
||||
glm::vec3 color;
|
||||
bool isSRGB;
|
||||
bool valid = parseJSONColor(value, color, isSRGB);
|
||||
if (valid) {
|
||||
toonMaterial->setMatcap(color, isSRGB);
|
||||
}
|
||||
}
|
||||
} else if (key == "matcapMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::MATCAP_MAP_BIT);
|
||||
} else {
|
||||
toonMaterial->setMatcapMap(baseUrl.resolved(valueString));
|
||||
}
|
||||
}
|
||||
} else if (key == "parametricRim") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_VAL_BIT);
|
||||
} else {
|
||||
glm::vec3 color;
|
||||
bool isSRGB;
|
||||
bool valid = parseJSONColor(value, color, isSRGB);
|
||||
if (valid) {
|
||||
toonMaterial->setParametricRim(color, isSRGB);
|
||||
}
|
||||
}
|
||||
} else if (key == "parametricRimFresnelPower") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_POWER_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
toonMaterial->setParametricRimFresnelPower(value.toDouble());
|
||||
}
|
||||
} else if (key == "parametricRimLift") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_LIFT_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
toonMaterial->setParametricRimLift(value.toDouble());
|
||||
}
|
||||
} else if (key == "rimMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::RIM_MAP_BIT);
|
||||
} else {
|
||||
toonMaterial->setRimMap(baseUrl.resolved(valueString));
|
||||
}
|
||||
}
|
||||
} else if (key == "rimLightingMix") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::RIM_LIGHTING_MIX_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
toonMaterial->setRimLightingMix(value.toDouble());
|
||||
}
|
||||
} else if (key == "uvAnimationMaskMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_MASK_MAP_BIT);
|
||||
} else {
|
||||
toonMaterial->setUVAnimationMaskMap(baseUrl.resolved(valueString));
|
||||
}
|
||||
}
|
||||
} else if (key == "uvAnimationScrollXSpeed") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_SCROLL_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
toonMaterial->setUVAnimationScrollXSpeed(value.toDouble());
|
||||
}
|
||||
} else if (key == "uvAnimationScrollYSpeed") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_SCROLL_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
toonMaterial->setUVAnimationScrollYSpeed(value.toDouble());
|
||||
}
|
||||
} else if (key == "uvAnimationRotationSpeed") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_SCROLL_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
toonMaterial->setUVAnimationRotationSpeed(value.toDouble());
|
||||
}
|
||||
} else if (key == "outlineWidthMode") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::OUTLINE_WIDTH_MODE_VAL_BIT);
|
||||
} else {
|
||||
NetworkMToonMaterial::OutlineWidthMode mode;
|
||||
if (NetworkMToonMaterial::getOutlineWidthModeFromName(valueString.toStdString(), mode)) {
|
||||
toonMaterial->setOutlineWidthMode(mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (key == "outlineWidth") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::OUTLINE_WIDTH_VAL_BIT);
|
||||
} else if (value.isDouble()) {
|
||||
toonMaterial->setOutlineWidth(value.toDouble());
|
||||
}
|
||||
} else if (key == "outline") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString() && value.toString() == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(NetworkMToonMaterial::MToonFlagBit::OUTLINE_VAL_BIT);
|
||||
} else {
|
||||
glm::vec3 color;
|
||||
bool isSRGB;
|
||||
bool valid = parseJSONColor(value, color, isSRGB);
|
||||
if (valid) {
|
||||
toonMaterial->setOutline(color, isSRGB);
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: support outlineWidthTexture and outlineLightingMix
|
||||
}
|
||||
}
|
||||
|
||||
// Do this after the texture maps are defined, so it overrides the default transforms
|
||||
|
@ -893,3 +1126,138 @@ bool NetworkMaterial::checkResetOpacityMap() {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NetworkMToonMaterial::NetworkMToonMaterial(const NetworkMToonMaterial& material) :
|
||||
NetworkMaterial(material),
|
||||
_shade(material._shade),
|
||||
_shadingShift(material._shadingShift),
|
||||
_shadingToony(material._shadingToony),
|
||||
_matcap(material._matcap),
|
||||
_parametricRim(material._parametricRim),
|
||||
_parametricRimFresnelPower(material._parametricRimFresnelPower),
|
||||
_parametricRimLift(material._parametricRimLift),
|
||||
_rimLightingMix(material._rimLightingMix),
|
||||
_uvAnimationScrollXSpeed(material._uvAnimationScrollXSpeed),
|
||||
_uvAnimationScrollYSpeed(material._uvAnimationScrollYSpeed),
|
||||
_uvAnimationRotationSpeed(material._uvAnimationRotationSpeed),
|
||||
_outlineWidthMode(material._outlineWidthMode),
|
||||
_outlineWidth(material._outlineWidth),
|
||||
_outline(material._outline)
|
||||
{}
|
||||
|
||||
std::string NetworkMToonMaterial::getOutlineWidthModeName(OutlineWidthMode mode) {
|
||||
const std::string names[3] = { "none", "worldCoordinates", "screenCoordinates" };
|
||||
return names[mode];
|
||||
}
|
||||
|
||||
bool NetworkMToonMaterial::getOutlineWidthModeFromName(const std::string& modeName, OutlineWidthMode& mode) {
|
||||
for (int i = OUTLINE_NONE; i < NUM_OUTLINE_MODES; i++) {
|
||||
mode = (OutlineWidthMode)i;
|
||||
if (modeName == getOutlineWidthModeName(mode)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setShadeMap(const QUrl& url) {
|
||||
auto map = fetchTextureMap(url, image::TextureUsage::ALBEDO_TEXTURE, (MapChannel) MToonMapChannel::SHADE_MAP);
|
||||
if (map) {
|
||||
setTextureMap((MapChannel) MToonMapChannel::SHADE_MAP, map);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setShadingShiftMap(const QUrl& url) {
|
||||
auto map = fetchTextureMap(url, image::TextureUsage::ROUGHNESS_TEXTURE, (MapChannel) MToonMapChannel::SHADING_SHIFT_MAP);
|
||||
if (map) {
|
||||
setTextureMap((MapChannel) MToonMapChannel::SHADING_SHIFT_MAP, map);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setMatcapMap(const QUrl& url) {
|
||||
auto map = fetchTextureMap(url, image::TextureUsage::EMISSIVE_TEXTURE, (MapChannel)MToonMapChannel::MATCAP_MAP);
|
||||
if (map) {
|
||||
setTextureMap((MapChannel) MToonMapChannel::MATCAP_MAP, map);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setRimMap(const QUrl& url) {
|
||||
auto map = fetchTextureMap(url, image::TextureUsage::ALBEDO_TEXTURE, (MapChannel)MToonMapChannel::RIM_MAP);
|
||||
if (map) {
|
||||
setTextureMap((MapChannel) MToonMapChannel::RIM_MAP, map);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setUVAnimationMaskMap(const QUrl& url) {
|
||||
auto map = fetchTextureMap(url, image::TextureUsage::ROUGHNESS_TEXTURE, (MapChannel)MToonMapChannel::UV_ANIMATION_MASK_MAP);
|
||||
if (map) {
|
||||
setTextureMap((MapChannel) MToonMapChannel::UV_ANIMATION_MASK_MAP, map);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setShade(const glm::vec3& shade, bool isSRGB) {
|
||||
_key._flags.set(NetworkMToonMaterial::MToonFlagBit::SHADE_VAL_BIT, true);
|
||||
_shade = (isSRGB ? ColorUtils::sRGBToLinearVec3(shade) : shade);
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setShadingShift(float shadingShift) {
|
||||
_key._flags.set(NetworkMToonMaterial::MToonFlagBit::SHADING_SHIFT_VAL_BIT, true);
|
||||
_shadingShift = shadingShift;
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setShadingToony(float shadingToony) {
|
||||
_key._flags.set(NetworkMToonMaterial::MToonFlagBit::SHADING_TOONY_VAL_BIT, true);
|
||||
_shadingToony = shadingToony;
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setMatcap(const glm::vec3& matcap, bool isSRGB) {
|
||||
_key._flags.set(MToonFlagBit::MATCAP_VAL_BIT, true);
|
||||
_matcap = (isSRGB ? ColorUtils::sRGBToLinearVec3(matcap) : matcap);
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setParametricRim(const glm::vec3& parametricRim, bool isSRGB) {
|
||||
_key._flags.set(MToonFlagBit::PARAMETRIC_RIM_VAL_BIT, true);
|
||||
_parametricRim = (isSRGB ? ColorUtils::sRGBToLinearVec3(parametricRim) : parametricRim);
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setParametricRimFresnelPower(float parametricRimFresnelPower) {
|
||||
_key._flags.set(MToonFlagBit::PARAMETRIC_RIM_POWER_VAL_BIT, true);
|
||||
_parametricRimFresnelPower = parametricRimFresnelPower;
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setParametricRimLift(float parametricRimLift) {
|
||||
_key._flags.set(MToonFlagBit::PARAMETRIC_RIM_LIFT_VAL_BIT, true);
|
||||
_parametricRimLift = parametricRimLift;
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setRimLightingMix(float rimLightingMix) {
|
||||
_key._flags.set(MToonFlagBit::RIM_LIGHTING_MIX_VAL_BIT, true);
|
||||
_rimLightingMix = rimLightingMix;
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setUVAnimationScrollXSpeed(float uvAnimationScrollXSpeed) {
|
||||
_key._flags.set(NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_SCROLL_VAL_BIT, true);
|
||||
_uvAnimationScrollXSpeed = uvAnimationScrollXSpeed;
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setUVAnimationScrollYSpeed(float uvAnimationScrollYSpeed) {
|
||||
_key._flags.set(NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_SCROLL_VAL_BIT, true);
|
||||
_uvAnimationScrollYSpeed = uvAnimationScrollYSpeed;
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setUVAnimationRotationSpeed(float uvAnimationRotationSpeed) {
|
||||
_key._flags.set(NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_SCROLL_VAL_BIT, true);
|
||||
_uvAnimationRotationSpeed = uvAnimationRotationSpeed;
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setOutlineWidthMode(OutlineWidthMode mode) {
|
||||
_outlineWidthMode = mode;
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setOutlineWidth(float width) {
|
||||
_outlineWidth = width;
|
||||
}
|
||||
|
||||
void NetworkMToonMaterial::setOutline(const glm::vec3& outline, bool isSRGB) {
|
||||
_outline = (isSRGB ? ColorUtils::sRGBToLinearVec3(outline) : outline);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//
|
||||
// Created by Sam Gondelman on 2/9/2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -63,13 +64,14 @@ protected:
|
|||
|
||||
const bool& isOriginal() const { return _isOriginal; }
|
||||
|
||||
private:
|
||||
// Helpers for the ctors
|
||||
QUrl getTextureUrl(const QUrl& baseUrl, const HFMTexture& hfmTexture);
|
||||
graphics::TextureMapPointer fetchTextureMap(const QUrl& baseUrl, const HFMTexture& hfmTexture,
|
||||
image::TextureUsage::Type type, MapChannel channel);
|
||||
graphics::TextureMapPointer fetchTextureMap(const QUrl& url, image::TextureUsage::Type type, MapChannel channel);
|
||||
|
||||
private:
|
||||
// Helpers for the ctors
|
||||
QUrl getTextureUrl(const QUrl& baseUrl, const HFMTexture& hfmTexture);
|
||||
|
||||
Transform _albedoTransform;
|
||||
Transform _lightmapTransform;
|
||||
vec2 _lightmapParams;
|
||||
|
@ -77,6 +79,119 @@ private:
|
|||
bool _isOriginal { true };
|
||||
};
|
||||
|
||||
class NetworkMToonMaterial : public NetworkMaterial {
|
||||
public:
|
||||
NetworkMToonMaterial() : NetworkMaterial() {}
|
||||
NetworkMToonMaterial(const NetworkMToonMaterial& material);
|
||||
|
||||
enum MToonMapChannel {
|
||||
// Keep aligned with graphics/ShaderConstants.h and graphics-scripting/ScriptableModel.cpp
|
||||
SHADE_MAP = MapChannel::ROUGHNESS_MAP,
|
||||
SHADING_SHIFT_MAP = MapChannel::METALLIC_MAP,
|
||||
MATCAP_MAP = MapChannel::OCCLUSION_MAP,
|
||||
RIM_MAP = MapChannel::SCATTERING_MAP,
|
||||
UV_ANIMATION_MASK_MAP = MapChannel::LIGHT_MAP,
|
||||
};
|
||||
|
||||
enum MToonFlagBit {
|
||||
SHADE_MAP_BIT = graphics::MaterialKey::FlagBit::ROUGHNESS_MAP_BIT,
|
||||
SHADING_SHIFT_MAP_BIT = graphics::MaterialKey::FlagBit::METALLIC_MAP_BIT,
|
||||
MATCAP_MAP_BIT = graphics::MaterialKey::FlagBit::OCCLUSION_MAP_BIT,
|
||||
RIM_MAP_BIT = graphics::MaterialKey::FlagBit::SCATTERING_MAP_BIT,
|
||||
UV_ANIMATION_MASK_MAP_BIT = graphics::MaterialKey::FlagBit::LIGHT_MAP_BIT,
|
||||
|
||||
SHADE_VAL_BIT = graphics::MaterialKey::FlagBit::UNLIT_VAL_BIT,
|
||||
SHADING_SHIFT_VAL_BIT = graphics::MaterialKey::FlagBit::METALLIC_VAL_BIT,
|
||||
SHADING_TOONY_VAL_BIT = graphics::MaterialKey::FlagBit::GLOSSY_VAL_BIT,
|
||||
UV_ANIMATION_SCROLL_VAL_BIT = graphics::MaterialKey::FlagBit::SCATTERING_VAL_BIT,
|
||||
MATCAP_VAL_BIT = graphics::MaterialKey::FlagBit::EXTRA_1_BIT,
|
||||
PARAMETRIC_RIM_VAL_BIT = graphics::MaterialKey::FlagBit::EXTRA_2_BIT,
|
||||
PARAMETRIC_RIM_POWER_VAL_BIT = graphics::MaterialKey::FlagBit::EXTRA_3_BIT,
|
||||
PARAMETRIC_RIM_LIFT_VAL_BIT = graphics::MaterialKey::FlagBit::EXTRA_4_BIT,
|
||||
RIM_LIGHTING_MIX_VAL_BIT = graphics::MaterialKey::FlagBit::EXTRA_5_BIT,
|
||||
|
||||
OUTLINE_WIDTH_MODE_VAL_BIT = graphics::Material::ExtraFlagBit::EXTRA_1_BIT,
|
||||
OUTLINE_WIDTH_VAL_BIT = graphics::Material::ExtraFlagBit::EXTRA_2_BIT,
|
||||
OUTLINE_VAL_BIT = graphics::Material::ExtraFlagBit::EXTRA_3_BIT,
|
||||
};
|
||||
|
||||
enum OutlineWidthMode {
|
||||
OUTLINE_NONE = 0,
|
||||
OUTLINE_WORLD,
|
||||
OUTLINE_SCREEN,
|
||||
|
||||
NUM_OUTLINE_MODES
|
||||
};
|
||||
static std::string getOutlineWidthModeName(OutlineWidthMode mode);
|
||||
// find the enum value from a string, return true if match found
|
||||
static bool getOutlineWidthModeFromName(const std::string& modeName, OutlineWidthMode& mode);
|
||||
|
||||
bool isMToon() const override { return true; }
|
||||
|
||||
void setShadeMap(const QUrl& url);
|
||||
void setShadingShiftMap(const QUrl& url);
|
||||
void setMatcapMap(const QUrl& url);
|
||||
void setRimMap(const QUrl& url);
|
||||
void setUVAnimationMaskMap(const QUrl& url);
|
||||
|
||||
void setShade(const glm::vec3& shade, bool isSRGB = true);
|
||||
glm::vec3 getShade(bool SRGB = true) const override { return (SRGB ? ColorUtils::tosRGBVec3(_shade) : _shade); }
|
||||
|
||||
void setShadingShift(float shadeShift);
|
||||
float getShadingShift() const override { return _shadingShift; }
|
||||
|
||||
void setShadingToony(float shadingToony);
|
||||
float getShadingToony() const override { return _shadingToony; }
|
||||
|
||||
void setMatcap(const glm::vec3& matcap, bool isSRGB = true);
|
||||
glm::vec3 getMatcap(bool SRGB = true) const override { return (SRGB ? ColorUtils::tosRGBVec3(_matcap) : _matcap); }
|
||||
|
||||
void setParametricRim(const glm::vec3& parametricRim, bool isSRGB = true);
|
||||
glm::vec3 getParametricRim(bool SRGB = true) const override { return (SRGB ? ColorUtils::tosRGBVec3(_parametricRim) : _parametricRim); }
|
||||
|
||||
void setParametricRimFresnelPower(float parametricRimFresnelPower);
|
||||
float getParametricRimFresnelPower() const override { return _parametricRimFresnelPower; }
|
||||
|
||||
void setParametricRimLift(float parametricRimLift);
|
||||
float getParametricRimLift() const override { return _parametricRimLift; }
|
||||
|
||||
void setRimLightingMix(float rimLightingMix);
|
||||
float getRimLightingMix() const override { return _rimLightingMix; }
|
||||
|
||||
void setUVAnimationScrollXSpeed(float uvAnimationScrollXSpeed);
|
||||
float getUVAnimationScrollXSpeed() const override { return _uvAnimationScrollXSpeed; }
|
||||
void setUVAnimationScrollYSpeed(float uvAnimationScrollYSpeed);
|
||||
float getUVAnimationScrollYSpeed() const override { return _uvAnimationScrollYSpeed; }
|
||||
void setUVAnimationRotationSpeed(float uvAnimationRotationSpeed);
|
||||
float getUVAnimationRotationSpeed() const override { return _uvAnimationRotationSpeed; }
|
||||
|
||||
void setOutlineWidthMode(OutlineWidthMode mode);
|
||||
uint8_t getOutlineWidthMode() override { return _outlineWidthMode; }
|
||||
void setOutlineWidth(float width);
|
||||
float getOutlineWidth() override { return _outlineWidth; }
|
||||
void setOutline(const glm::vec3& outline, bool isSRGB = true);
|
||||
glm::vec3 getOutline(bool SRGB = true) const override { return (SRGB ? ColorUtils::tosRGBVec3(_outline) : _outline); }
|
||||
|
||||
private:
|
||||
glm::vec3 _shade { DEFAULT_SHADE };
|
||||
float _shadingShift { DEFAULT_SHADING_SHIFT };
|
||||
float _shadingToony { DEFAULT_SHADING_TOONY };
|
||||
|
||||
glm::vec3 _matcap { DEFAULT_MATCAP };
|
||||
glm::vec3 _parametricRim { DEFAULT_PARAMETRIC_RIM };
|
||||
float _parametricRimFresnelPower { DEFAULT_PARAMETRIC_RIM_FRESNEL_POWER };
|
||||
float _parametricRimLift { DEFAULT_PARAMETRIC_RIM_LIFT };
|
||||
float _rimLightingMix { DEFAULT_RIM_LIGHTING_MIX };
|
||||
|
||||
float _uvAnimationScrollXSpeed { DEFAULT_UV_ANIMATION_SCROLL_SPEED };
|
||||
float _uvAnimationScrollYSpeed { DEFAULT_UV_ANIMATION_SCROLL_SPEED };
|
||||
float _uvAnimationRotationSpeed { DEFAULT_UV_ANIMATION_SCROLL_SPEED };
|
||||
|
||||
OutlineWidthMode _outlineWidthMode { OutlineWidthMode::OUTLINE_NONE };
|
||||
float _outlineWidth { 0.0f };
|
||||
glm::vec3 _outline { DEFAULT_OUTLINE };
|
||||
};
|
||||
|
||||
class NetworkMaterialResource : public Resource {
|
||||
public:
|
||||
NetworkMaterialResource() : Resource() {}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//
|
||||
// Created by HifiExperiments on 3/14/2021
|
||||
// Copyright 2021 Vircadia contributors.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -162,7 +163,7 @@ bool ReferenceMaterial::isReady() const {
|
|||
|
||||
QString ReferenceMaterial::getProceduralString() const {
|
||||
return resultWithLock<QString>([&] {
|
||||
auto material = getMaterial();
|
||||
auto material = getProceduralMaterial();
|
||||
return material ? material->getProceduralString() : QString();
|
||||
});
|
||||
}
|
||||
|
@ -212,6 +213,112 @@ void ReferenceMaterial::initializeProcedural() {
|
|||
});
|
||||
}
|
||||
|
||||
// MToonMaterial
|
||||
bool ReferenceMaterial::isMToon() const {
|
||||
return resultWithLock<bool>([&] {
|
||||
auto material = getMaterial();
|
||||
return material ? material->isMToon() : false;
|
||||
});
|
||||
}
|
||||
|
||||
glm::vec3 ReferenceMaterial::getShade(bool SRGB) const {
|
||||
return resultWithLock<glm::vec3>([&] {
|
||||
auto material = getMToonMaterial();
|
||||
return material ? material->getShade(SRGB) : glm::vec3();
|
||||
});
|
||||
}
|
||||
|
||||
float ReferenceMaterial::getShadingShift() const {
|
||||
return resultWithLock<float>([&] {
|
||||
auto material = getMToonMaterial();
|
||||
return material ? material->getShadingShift() : 0.0f;
|
||||
});
|
||||
}
|
||||
|
||||
float ReferenceMaterial::getShadingToony() const {
|
||||
return resultWithLock<float>([&] {
|
||||
auto material = getMToonMaterial();
|
||||
return material ? material->getShadingToony() : 0.0f;
|
||||
});
|
||||
}
|
||||
|
||||
glm::vec3 ReferenceMaterial::getMatcap(bool SRGB) const {
|
||||
return resultWithLock<glm::vec3>([&] {
|
||||
auto material = getMToonMaterial();
|
||||
return material ? material->getMatcap(SRGB) : glm::vec3();
|
||||
});
|
||||
}
|
||||
|
||||
glm::vec3 ReferenceMaterial::getParametricRim(bool SRGB) const {
|
||||
return resultWithLock<glm::vec3>([&] {
|
||||
auto material = getMToonMaterial();
|
||||
return material ? material->getParametricRim(SRGB) : glm::vec3();
|
||||
});
|
||||
}
|
||||
|
||||
float ReferenceMaterial::getParametricRimFresnelPower() const {
|
||||
return resultWithLock<float>([&] {
|
||||
auto material = getMToonMaterial();
|
||||
return material ? material->getParametricRimFresnelPower() : 0.0f;
|
||||
});
|
||||
}
|
||||
|
||||
float ReferenceMaterial::getParametricRimLift() const {
|
||||
return resultWithLock<float>([&] {
|
||||
auto material = getMToonMaterial();
|
||||
return material ? material->getParametricRimLift() : 0.0f;
|
||||
});
|
||||
}
|
||||
|
||||
float ReferenceMaterial::getRimLightingMix() const {
|
||||
return resultWithLock<float>([&] {
|
||||
auto material = getMToonMaterial();
|
||||
return material ? material->getRimLightingMix() : 0.0f;
|
||||
});
|
||||
}
|
||||
|
||||
float ReferenceMaterial::getUVAnimationScrollXSpeed() const {
|
||||
return resultWithLock<float>([&] {
|
||||
auto material = getMToonMaterial();
|
||||
return material ? material->getUVAnimationScrollXSpeed() : 0.0f;
|
||||
});
|
||||
}
|
||||
|
||||
float ReferenceMaterial::getUVAnimationScrollYSpeed() const {
|
||||
return resultWithLock<float>([&] {
|
||||
auto material = getMToonMaterial();
|
||||
return material ? material->getUVAnimationScrollYSpeed() : 0.0f;
|
||||
});
|
||||
}
|
||||
|
||||
float ReferenceMaterial::getUVAnimationRotationSpeed() const {
|
||||
return resultWithLock<float>([&] {
|
||||
auto material = getMToonMaterial();
|
||||
return material ? material->getUVAnimationRotationSpeed() : 0.0f;
|
||||
});
|
||||
}
|
||||
|
||||
uint8_t ReferenceMaterial::getOutlineWidthMode() {
|
||||
return resultWithLock<uint8_t>([&] {
|
||||
auto material = getMToonMaterial();
|
||||
return material ? material->getOutlineWidthMode() : 0;
|
||||
});
|
||||
}
|
||||
|
||||
float ReferenceMaterial::getOutlineWidth() {
|
||||
return resultWithLock<float>([&] {
|
||||
auto material = getMToonMaterial();
|
||||
return material ? material->getOutlineWidth() : 0.0f;
|
||||
});
|
||||
}
|
||||
|
||||
glm::vec3 ReferenceMaterial::getOutline(bool SRGB) const {
|
||||
return resultWithLock<glm::vec3>([&] {
|
||||
auto material = getMToonMaterial();
|
||||
return material ? material->getOutline() : glm::vec3(0.0f);
|
||||
});
|
||||
}
|
||||
|
||||
void ReferenceMaterial::setMaterialForUUIDOperator(std::function<graphics::MaterialPointer(QUuid)> materialForUUIDOperator) {
|
||||
_unboundMaterialForUUIDOperator = materialForUUIDOperator;
|
||||
}
|
||||
|
@ -244,6 +351,16 @@ graphics::ProceduralMaterialPointer ReferenceMaterial::getProceduralMaterial() c
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<NetworkMToonMaterial> ReferenceMaterial::getMToonMaterial() const {
|
||||
if (_materialForUUIDOperator) {
|
||||
std::shared_ptr<NetworkMToonMaterial> result = nullptr;
|
||||
if (auto material = _materialForUUIDOperator()) {
|
||||
return std::static_pointer_cast<NetworkMToonMaterial>(material);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename T, typename F>
|
||||
inline T ReferenceMaterial::resultWithLock(F&& f) const {
|
||||
if (_locked) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//
|
||||
// Created by HifiExperiments on 3/14/2021
|
||||
// Copyright 2021 Vircadia contributors.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -52,6 +53,23 @@ public:
|
|||
const uint64_t& created, const ProceduralProgramKey key = ProceduralProgramKey()) override;
|
||||
void initializeProcedural() override;
|
||||
|
||||
// MToonMaterial
|
||||
bool isMToon() const override;
|
||||
glm::vec3 getShade(bool SRGB = true) const override;
|
||||
float getShadingShift() const override;
|
||||
float getShadingToony() const override;
|
||||
glm::vec3 getMatcap(bool SRGB = true) const override;
|
||||
glm::vec3 getParametricRim(bool SRGB = true) const override;
|
||||
float getParametricRimFresnelPower() const override;
|
||||
float getParametricRimLift() const override;
|
||||
float getRimLightingMix() const override;
|
||||
float getUVAnimationScrollXSpeed() const override;
|
||||
float getUVAnimationScrollYSpeed() const override;
|
||||
float getUVAnimationRotationSpeed() const override;
|
||||
uint8_t getOutlineWidthMode() override;
|
||||
float getOutlineWidth() override;
|
||||
glm::vec3 getOutline(bool SRGB = true) const override;
|
||||
|
||||
bool isReference() const override { return true; }
|
||||
std::function<graphics::MaterialPointer()> getReferenceOperator() const { return _materialForUUIDOperator; }
|
||||
|
||||
|
@ -65,6 +83,7 @@ private:
|
|||
graphics::MaterialPointer getMaterial() const;
|
||||
std::shared_ptr<NetworkMaterial> getNetworkMaterial() const;
|
||||
graphics::ProceduralMaterialPointer getProceduralMaterial() const;
|
||||
std::shared_ptr<NetworkMToonMaterial> getMToonMaterial() const;
|
||||
|
||||
template <typename T, typename F>
|
||||
T resultWithLock(F&& f) const;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Sam Gateau on 2/5/15.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -286,5 +287,78 @@ vec3 evalGlobalLightingAlphaBlended(
|
|||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@if HIFI_USE_MTOON@>
|
||||
<@func declareEvalGlobalLightingAlphaBlendedMToon()@>
|
||||
|
||||
<$declareLightingAmbient(1, 1, 1)$>
|
||||
<$declareLightingDirectional()$>
|
||||
|
||||
float linearstep(float a, float b, float t) {
|
||||
return clamp((t - a) / (b - a), 0.0, 1.0);
|
||||
}
|
||||
|
||||
vec3 evalGlobalLightingAlphaBlendedMToon(
|
||||
mat4 invViewMat, float obscurance, vec3 positionES, vec3 normalWS, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive,
|
||||
float roughness, float opacity, vec3 shade, float shadingShift, float shadingToony, vec3 matcap,
|
||||
vec3 parametricRim, float parametricRimFresnelPower, float parametricRimLift, vec3 rim, float rimMix, BITFIELD matKey)
|
||||
{
|
||||
<$prepareGlobalLight(positionES, normalWS)$>
|
||||
|
||||
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
|
||||
|
||||
color += emissive * isEmissiveEnabled();
|
||||
|
||||
// Ambient
|
||||
vec3 ambientDiffuse;
|
||||
vec3 ambientSpecular;
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance);
|
||||
color += ambientDiffuse;
|
||||
color += evalSpecularWithOpacity(ambientSpecular, opacity);
|
||||
|
||||
// Directional MToon Shading
|
||||
updateSurfaceDataWithLight(surfaceWS, lightDirection);
|
||||
|
||||
float shading = surfaceWS.ndotl;
|
||||
shading += shadingShift; // shadingShift includes both the scalar and texture values
|
||||
shading = linearstep(-1.0 + shadingToony, 1.0 - shadingToony, shading);
|
||||
|
||||
color += lightIrradiance * mix(albedo, shade, shading) * isDirectionalEnabled();
|
||||
|
||||
vec3 worldViewX = normalize(vec3(surfaceWS.eyeDir.z, 0.0, -surfaceWS.eyeDir.x));
|
||||
vec3 worldViewY = cross(surfaceWS.eyeDir, worldViewX);
|
||||
vec2 matcapUV = vec2(dot(worldViewX, surfaceWS.normal), dot(worldViewY, surfaceWS.normal)) * 0.495 + 0.5;
|
||||
const float epsilon = 0.00001;
|
||||
|
||||
vec3 rimDiffuse;
|
||||
<$evalMaterialMatcap(matcapUV, matcap, matKey, rimDiffuse)$>;
|
||||
float rimColor = clamp(1.0 - dot(surfaceWS.normal, surfaceWS.eyeDir) + parametricRimLift, 0.0, 1.0);
|
||||
rimColor = pow(rimColor, max(parametricRimFresnelPower, epsilon));
|
||||
rimDiffuse += rimColor * parametricRim;
|
||||
rimDiffuse *= rim;
|
||||
rimDiffuse = rimDiffuse * mix(vec3(1.0), vec3(0.0), rimMix);
|
||||
color += rimDiffuse;
|
||||
|
||||
// Haze
|
||||
if (isHazeEnabled() > 0.0) {
|
||||
if ((hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
|
||||
color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS);
|
||||
}
|
||||
|
||||
if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
|
||||
vec4 hazeColor = computeHazeColor(
|
||||
positionES, // fragment position in eye coordinates
|
||||
fragPositionWS, // fragment position in world coordinates
|
||||
invViewMat[3].xyz, // eye position in world coordinates
|
||||
lightDirection // keylight direction vector in world coordinates
|
||||
);
|
||||
|
||||
color = mix(color.rgb, hazeColor.rgb, hazeColor.a);
|
||||
}
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
<@endfunc@>
|
||||
<@endif@>
|
||||
|
||||
<@endif@>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Olivier Prat on 08/08/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -40,6 +41,7 @@ namespace gr {
|
|||
#define OUTLINE_STENCIL_MASK 1
|
||||
|
||||
extern void initZPassPipelines(ShapePlumber& plumber, gpu::StatePointer state, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter);
|
||||
extern void sortAndRenderZPassShapes(const ShapePlumberPointer& shapePlumber, const render::RenderContextPointer& renderContext, const render::ShapeBounds& inShapes, render::ItemBounds &itemBounds);
|
||||
|
||||
HighlightResources::HighlightResources() {
|
||||
}
|
||||
|
@ -108,10 +110,14 @@ PrepareDrawHighlight::PrepareDrawHighlight() {
|
|||
}
|
||||
|
||||
void PrepareDrawHighlight::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) {
|
||||
auto destinationFrameBuffer = inputs;
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
auto destinationFrameBuffer = inputs;
|
||||
_resources->update(destinationFrameBuffer);
|
||||
outputs = _resources;
|
||||
outputs.edit0() = _resources;
|
||||
|
||||
outputs.edit1() = args->_renderMode;
|
||||
args->_renderMode = RenderArgs::SHADOW_RENDER_MODE;
|
||||
}
|
||||
|
||||
gpu::PipelinePointer DrawHighlightMask::_stencilMaskPipeline;
|
||||
|
@ -188,61 +194,7 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c
|
|||
batch.setProjectionJitter(jitter.x, jitter.y);
|
||||
batch.setViewTransform(viewMat);
|
||||
|
||||
const std::vector<ShapeKey::Builder> keys = {
|
||||
ShapeKey::Builder(), ShapeKey::Builder().withFade(),
|
||||
ShapeKey::Builder().withDeformed(), ShapeKey::Builder().withDeformed().withFade(),
|
||||
ShapeKey::Builder().withDeformed().withDualQuatSkinned(), ShapeKey::Builder().withDeformed().withDualQuatSkinned().withFade(),
|
||||
ShapeKey::Builder().withOwnPipeline(), ShapeKey::Builder().withOwnPipeline().withFade(),
|
||||
ShapeKey::Builder().withDeformed().withOwnPipeline(), ShapeKey::Builder().withDeformed().withOwnPipeline().withFade(),
|
||||
ShapeKey::Builder().withDeformed().withDualQuatSkinned().withOwnPipeline(), ShapeKey::Builder().withDeformed().withDualQuatSkinned().withOwnPipeline().withFade(),
|
||||
};
|
||||
std::vector<std::vector<ShapeKey>> sortedShapeKeys(keys.size());
|
||||
|
||||
const int OWN_PIPELINE_INDEX = 6;
|
||||
for (const auto& items : inShapes) {
|
||||
itemBounds.insert(itemBounds.end(), items.second.begin(), items.second.end());
|
||||
|
||||
int index = items.first.hasOwnPipeline() ? OWN_PIPELINE_INDEX : 0;
|
||||
if (items.first.isDeformed()) {
|
||||
index += 2;
|
||||
if (items.first.isDualQuatSkinned()) {
|
||||
index += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (items.first.isFaded()) {
|
||||
index += 1;
|
||||
}
|
||||
|
||||
sortedShapeKeys[index].push_back(items.first);
|
||||
}
|
||||
|
||||
// Render non-withOwnPipeline things
|
||||
for (size_t i = 0; i < OWN_PIPELINE_INDEX; i++) {
|
||||
auto& shapeKeys = sortedShapeKeys[i];
|
||||
if (shapeKeys.size() > 0) {
|
||||
const auto& shapePipeline = _shapePlumber->pickPipeline(args, keys[i]);
|
||||
args->_shapePipeline = shapePipeline;
|
||||
for (const auto& key : shapeKeys) {
|
||||
renderShapes(renderContext, _shapePlumber, inShapes.at(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render withOwnPipeline things
|
||||
for (size_t i = OWN_PIPELINE_INDEX; i < keys.size(); i++) {
|
||||
auto& shapeKeys = sortedShapeKeys[i];
|
||||
if (shapeKeys.size() > 0) {
|
||||
args->_shapePipeline = nullptr;
|
||||
for (const auto& key : shapeKeys) {
|
||||
args->_itemShapeKey = key._flags.to_ulong();
|
||||
renderShapes(renderContext, _shapePlumber, inShapes.at(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
args->_shapePipeline = nullptr;
|
||||
args->_batch = nullptr;
|
||||
sortAndRenderZPassShapes(_shapePlumber, renderContext, inShapes, itemBounds);
|
||||
});
|
||||
|
||||
_boundsBuffer->setData(itemBounds.size() * sizeof(render::ItemBound), (const gpu::Byte*) itemBounds.data());
|
||||
|
@ -452,13 +404,28 @@ const gpu::PipelinePointer& DebugHighlight::getDepthPipeline() {
|
|||
return _depthPipeline;
|
||||
}
|
||||
|
||||
void SelectionToHighlight::run(const render::RenderContextPointer& renderContext, Outputs& outputs) {
|
||||
void SelectionToHighlight::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) {
|
||||
auto scene = renderContext->_scene;
|
||||
auto highlightStage = scene->getStage<render::HighlightStage>(render::HighlightStage::getName());
|
||||
|
||||
outputs.clear();
|
||||
auto outlines = inputs.get0();
|
||||
auto framebuffer = inputs.get1();
|
||||
|
||||
outputs.edit0().clear();
|
||||
outputs.edit1().clear();
|
||||
_sharedParameters->_highlightIds.fill(render::HighlightStage::INVALID_INDEX);
|
||||
|
||||
outputs.edit1().reserve(outlines.size());
|
||||
for (auto item : outlines) {
|
||||
render::HighlightStyle style = scene->getOutlineStyle(item.id, renderContext->args->getViewFrustum() , framebuffer->getHeight());
|
||||
auto selectionName = "__OUTLINE_MATERIAL" + style.toString();
|
||||
if (highlightStage->getHighlightIdBySelection(selectionName) == HighlightStage::INVALID_INDEX) {
|
||||
HighlightStage::Index newIndex = highlightStage->addHighlight(selectionName, style);
|
||||
outputs.edit1().push_back(newIndex);
|
||||
}
|
||||
scene->addItemToSelection(selectionName, item.id);
|
||||
}
|
||||
|
||||
int numLayers = 0;
|
||||
auto highlightList = highlightStage->getActiveHighlightIds();
|
||||
|
||||
|
@ -467,8 +434,8 @@ void SelectionToHighlight::run(const render::RenderContextPointer& renderContext
|
|||
|
||||
if (!scene->isSelectionEmpty(highlight._selectionName)) {
|
||||
auto highlightId = highlightStage->getHighlightIdBySelection(highlight._selectionName);
|
||||
_sharedParameters->_highlightIds[outputs.size()] = highlightId;
|
||||
outputs.emplace_back(highlight._selectionName);
|
||||
_sharedParameters->_highlightIds[outputs.edit0().size()] = highlightId;
|
||||
outputs.edit0().emplace_back(highlight._selectionName);
|
||||
numLayers++;
|
||||
|
||||
if (numLayers == HighlightSharedParameters::MAX_PASS_COUNT) {
|
||||
|
@ -500,6 +467,7 @@ void DrawHighlightTask::configure(const Config& config) {
|
|||
|
||||
void DrawHighlightTask::build(JobModel& task, const render::Varying& inputs, render::Varying& outputs) {
|
||||
const auto items = inputs.getN<Inputs>(0).get<RenderFetchCullSortTask::BucketList>();
|
||||
const auto& outlines = items[RenderFetchCullSortTask::OUTLINE];
|
||||
const auto sceneFrameBuffer = inputs.getN<Inputs>(1);
|
||||
const auto primaryFramebuffer = inputs.getN<Inputs>(2);
|
||||
const auto deferredFrameTransform = inputs.getN<Inputs>(3);
|
||||
|
@ -518,16 +486,21 @@ void DrawHighlightTask::build(JobModel& task, const render::Varying& inputs, ren
|
|||
}
|
||||
auto sharedParameters = std::make_shared<HighlightSharedParameters>();
|
||||
|
||||
const auto highlightSelectionNames = task.addJob<SelectionToHighlight>("SelectionToHighlight", sharedParameters);
|
||||
const auto selectionToHighlightInputs = SelectionToHighlight::Inputs(outlines, primaryFramebuffer).asVarying();
|
||||
const auto highlightSelectionOutputs = task.addJob<SelectionToHighlight>("SelectionToHighlight", selectionToHighlightInputs, sharedParameters);
|
||||
|
||||
// Prepare for highlight group rendering.
|
||||
const auto highlightResources = task.addJob<PrepareDrawHighlight>("PrepareHighlight", primaryFramebuffer);
|
||||
const auto prepareOutputs = task.addJob<PrepareDrawHighlight>("PrepareHighlight", primaryFramebuffer);
|
||||
const auto highlightResources = prepareOutputs.getN<PrepareDrawHighlight::Outputs>(0);
|
||||
render::Varying highlight0Rect;
|
||||
|
||||
const auto extractSelectionNameInput = Varying(highlightSelectionOutputs.getN<SelectionToHighlight::Outputs>(0));
|
||||
for (auto i = 0; i < HighlightSharedParameters::MAX_PASS_COUNT; i++) {
|
||||
const auto selectionName = task.addJob<ExtractSelectionName>("ExtractSelectionName", highlightSelectionNames, i);
|
||||
const auto selectionName = task.addJob<ExtractSelectionName>("ExtractSelectionName", extractSelectionNameInput, i);
|
||||
const auto groupItems = addSelectItemJobs(task, selectionName, items);
|
||||
const auto highlightedItemIDs = task.addJob<render::MetaToSubItems>("HighlightMetaToSubItemIDs", groupItems);
|
||||
const auto highlightedSubItemIDs = task.addJob<render::MetaToSubItems>("HighlightMetaToSubItemIDs", groupItems);
|
||||
const auto appendNonMetaOutlinesInput = AppendNonMetaOutlines::Inputs(highlightedSubItemIDs, groupItems).asVarying();
|
||||
const auto highlightedItemIDs = task.addJob<AppendNonMetaOutlines>("AppendNonMetaOutlines", appendNonMetaOutlinesInput);
|
||||
const auto highlightedItems = task.addJob<render::IDsToBounds>("HighlightMetaToSubItems", highlightedItemIDs);
|
||||
|
||||
// Sort
|
||||
|
@ -557,6 +530,10 @@ void DrawHighlightTask::build(JobModel& task, const render::Varying& inputs, ren
|
|||
task.addJob<DrawHighlight>(name, drawHighlightInputs, i, sharedParameters);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
const auto cleanupInput = HighlightCleanup::Inputs(highlightSelectionOutputs.getN<SelectionToHighlight::Outputs>(1), prepareOutputs.getN<PrepareDrawHighlight::Outputs>(1)).asVarying();
|
||||
task.addJob<HighlightCleanup>("HighlightCleanup", cleanupInput);
|
||||
|
||||
// Debug highlight
|
||||
const auto debugInputs = DebugHighlight::Inputs(highlightResources, const_cast<const render::Varying&>(highlight0Rect), jitter, primaryFramebuffer).asVarying();
|
||||
task.addJob<DebugHighlight>("HighlightDebug", debugInputs);
|
||||
|
@ -576,3 +553,31 @@ const render::Varying DrawHighlightTask::addSelectItemJobs(JobModel& task, const
|
|||
return task.addJob<SelectItems>("TransparentSelection", selectItemInput);
|
||||
}
|
||||
|
||||
void AppendNonMetaOutlines::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) {
|
||||
auto& scene = renderContext->_scene;
|
||||
|
||||
outputs = inputs.get0();
|
||||
|
||||
const auto& groupItems = inputs.get1();
|
||||
for (auto idBound : groupItems) {
|
||||
auto& item = scene->getItem(idBound.id);
|
||||
if (item.exist() && !item.getKey().isMeta()) {
|
||||
outputs.push_back(idBound.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HighlightCleanup::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) {
|
||||
auto scene = renderContext->_scene;
|
||||
auto highlightStage = scene->getStage<render::HighlightStage>(render::HighlightStage::getName());
|
||||
|
||||
for (auto index : inputs.get0()) {
|
||||
std::string selectionName = highlightStage->getHighlight(index)._selectionName;
|
||||
highlightStage->removeHighlight(index);
|
||||
scene->removeSelection(selectionName);
|
||||
}
|
||||
|
||||
// Reset the render mode
|
||||
renderContext->args->_renderMode = inputs.get1();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Olivier Prat on 08/08/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -65,7 +66,7 @@ using HighlightSharedParametersPointer = std::shared_ptr<HighlightSharedParamete
|
|||
class PrepareDrawHighlight {
|
||||
public:
|
||||
using Inputs = gpu::FramebufferPointer;
|
||||
using Outputs = HighlightResourcesPointer;
|
||||
using Outputs = render::VaryingSet2<HighlightResourcesPointer, render::Args::RenderMode>;
|
||||
using JobModel = render::Job::ModelIO<PrepareDrawHighlight, Inputs, Outputs>;
|
||||
|
||||
PrepareDrawHighlight();
|
||||
|
@ -81,12 +82,13 @@ private:
|
|||
class SelectionToHighlight {
|
||||
public:
|
||||
|
||||
using Outputs = std::vector<std::string>;
|
||||
using JobModel = render::Job::ModelO<SelectionToHighlight, Outputs>;
|
||||
using Inputs = render::VaryingSet2<render::ItemBounds, gpu::FramebufferPointer>;
|
||||
using Outputs = render::VaryingSet2<std::vector<std::string>, std::vector<render::HighlightStage::Index>>;
|
||||
using JobModel = render::Job::ModelIO<SelectionToHighlight, Inputs, Outputs>;
|
||||
|
||||
SelectionToHighlight(HighlightSharedParametersPointer parameters) : _sharedParameters{ parameters } {}
|
||||
|
||||
void run(const render::RenderContextPointer& renderContext, Outputs& outputs);
|
||||
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -96,7 +98,7 @@ private:
|
|||
class ExtractSelectionName {
|
||||
public:
|
||||
|
||||
using Inputs = SelectionToHighlight::Outputs;
|
||||
using Inputs = std::vector<std::string>;
|
||||
using Outputs = std::string;
|
||||
using JobModel = render::Job::ModelIO<ExtractSelectionName, Inputs, Outputs>;
|
||||
|
||||
|
@ -209,6 +211,25 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class AppendNonMetaOutlines {
|
||||
public:
|
||||
using Inputs = render::VaryingSet2<render::ItemIDs, render::ItemBounds>;
|
||||
using Outputs = render::ItemIDs;
|
||||
using JobModel = render::Job::ModelIO<AppendNonMetaOutlines, Inputs, Outputs>;
|
||||
|
||||
AppendNonMetaOutlines() {}
|
||||
|
||||
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs);
|
||||
};
|
||||
|
||||
class HighlightCleanup {
|
||||
public:
|
||||
using Inputs = render::VaryingSet2<std::vector<render::HighlightStage::Index>, render::Args::RenderMode>;
|
||||
using JobModel = render::Job::ModelI<HighlightCleanup, Inputs>;
|
||||
|
||||
HighlightCleanup() {}
|
||||
|
||||
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
|
||||
};
|
||||
|
||||
#endif // hifi_render_utils_HighlightEffect_h
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Sam Gateau on 10/3/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -220,6 +221,10 @@ void ModelMeshPartPayload::updateKey(const render::ItemKey& key) {
|
|||
builder.withSubMetaCulled();
|
||||
}
|
||||
|
||||
if (_drawMaterials.hasOutline()) {
|
||||
builder.withOutline();
|
||||
}
|
||||
|
||||
_itemKey = builder.build();
|
||||
}
|
||||
|
||||
|
@ -268,11 +273,15 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, PrimitiveMode pr
|
|||
if (hasTangents) {
|
||||
builder.withTangents();
|
||||
}
|
||||
if (hasLightmap) {
|
||||
builder.withLightMap();
|
||||
}
|
||||
if (isUnlit) {
|
||||
builder.withUnlit();
|
||||
if (!_drawMaterials.isMToon()) {
|
||||
if (hasLightmap) {
|
||||
builder.withLightMap();
|
||||
}
|
||||
if (isUnlit) {
|
||||
builder.withUnlit();
|
||||
}
|
||||
} else {
|
||||
builder.withMToon();
|
||||
}
|
||||
if (material) {
|
||||
builder.withCullFaceMode(material->getCullFaceMode());
|
||||
|
@ -377,6 +386,11 @@ bool ModelMeshPartPayload::passesZoneOcclusionTest(const std::unordered_set<QUui
|
|||
return true;
|
||||
}
|
||||
|
||||
render::HighlightStyle ModelMeshPartPayload::getOutlineStyle(const ViewFrustum& viewFrustum, const size_t height) const {
|
||||
return render::HighlightStyle::calculateOutlineStyle(_drawMaterials.getOutlineWidthMode(), _drawMaterials.getOutlineWidth(), _drawMaterials.getOutline(),
|
||||
_parentTransform.getTranslation(), viewFrustum, height);
|
||||
}
|
||||
|
||||
void ModelMeshPartPayload::setBlendshapeBuffer(const std::unordered_map<int, gpu::BufferPointer>& blendshapeBuffers, const QVector<int>& blendedMeshSizes) {
|
||||
if (_meshIndex < blendedMeshSizes.length() && blendedMeshSizes.at(_meshIndex) == _meshNumVertices) {
|
||||
auto blendshapeBuffer = blendshapeBuffers.find(_meshIndex);
|
||||
|
@ -426,4 +440,11 @@ template <> bool payloadPassesZoneOcclusionTest(const ModelMeshPartPayload::Poin
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <> HighlightStyle payloadGetOutlineStyle(const ModelMeshPartPayload::Pointer& payload, const ViewFrustum& viewFrustum, const size_t height) {
|
||||
if (payload) {
|
||||
return payload->getOutlineStyle(viewFrustum, height);
|
||||
}
|
||||
return HighlightStyle();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Sam Gateau on 10/3/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -17,6 +18,7 @@
|
|||
#include <gpu/Batch.h>
|
||||
#include <render/Scene.h>
|
||||
#include <graphics/Geometry.h>
|
||||
#include <render/HighlightStyle.h>
|
||||
|
||||
class ModelMeshPartPayload {
|
||||
public:
|
||||
|
@ -59,6 +61,7 @@ public:
|
|||
void setRenderWithZones(const QVector<QUuid>& renderWithZones) { _renderWithZones = renderWithZones; }
|
||||
void setBillboardMode(BillboardMode billboardMode) { _billboardMode = billboardMode; }
|
||||
bool passesZoneOcclusionTest(const std::unordered_set<QUuid>& containingZones) const;
|
||||
render::HighlightStyle getOutlineStyle(const ViewFrustum& viewFrustum, const size_t height) const;
|
||||
|
||||
void addMaterial(graphics::MaterialLayer material) { _drawMaterials.push(material); }
|
||||
void removeMaterial(graphics::MaterialPointer material) { _drawMaterials.remove(material); }
|
||||
|
@ -107,6 +110,7 @@ namespace render {
|
|||
template <> const ShapeKey shapeGetShapeKey(const ModelMeshPartPayload::Pointer& payload);
|
||||
template <> void payloadRender(const ModelMeshPartPayload::Pointer& payload, RenderArgs* args);
|
||||
template <> bool payloadPassesZoneOcclusionTest(const ModelMeshPartPayload::Pointer& payload, const std::unordered_set<QUuid>& containingZones);
|
||||
template <> HighlightStyle payloadGetOutlineStyle(const ModelMeshPartPayload::Pointer& payload, const ViewFrustum& viewFrustum, const size_t height);
|
||||
}
|
||||
|
||||
#endif // hifi_MeshPartPayload_h
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -37,6 +37,7 @@
|
|||
using namespace render;
|
||||
|
||||
extern void initZPassPipelines(ShapePlumber& plumber, gpu::StatePointer state, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter);
|
||||
extern void sortAndRenderZPassShapes(const ShapePlumberPointer& shapePlumber, const render::RenderContextPointer& renderContext, const render::ShapeBounds& inShapes, render::ItemBounds &itemBounds);
|
||||
|
||||
void RenderShadowTask::configure(const Config& configuration) {
|
||||
//DependencyManager::get<DeferredLightingEffect>()->setShadowMapEnabled(configuration.isEnabled());
|
||||
|
@ -253,58 +254,8 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
|
|||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat, false);
|
||||
|
||||
const std::vector<ShapeKey::Builder> keys = {
|
||||
ShapeKey::Builder(), ShapeKey::Builder().withFade(),
|
||||
ShapeKey::Builder().withDeformed(), ShapeKey::Builder().withDeformed().withFade(),
|
||||
ShapeKey::Builder().withDeformed().withDualQuatSkinned(), ShapeKey::Builder().withDeformed().withDualQuatSkinned().withFade(),
|
||||
ShapeKey::Builder().withOwnPipeline(), ShapeKey::Builder().withOwnPipeline().withFade(),
|
||||
ShapeKey::Builder().withDeformed().withOwnPipeline(), ShapeKey::Builder().withDeformed().withOwnPipeline().withFade(),
|
||||
ShapeKey::Builder().withDeformed().withDualQuatSkinned().withOwnPipeline(), ShapeKey::Builder().withDeformed().withDualQuatSkinned().withOwnPipeline().withFade(),
|
||||
};
|
||||
std::vector<std::vector<ShapeKey>> sortedShapeKeys(keys.size());
|
||||
|
||||
const int OWN_PIPELINE_INDEX = 6;
|
||||
for (const auto& items : inShapes) {
|
||||
int index = items.first.hasOwnPipeline() ? OWN_PIPELINE_INDEX : 0;
|
||||
if (items.first.isDeformed()) {
|
||||
index += 2;
|
||||
if (items.first.isDualQuatSkinned()) {
|
||||
index += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (items.first.isFaded()) {
|
||||
index += 1;
|
||||
}
|
||||
|
||||
sortedShapeKeys[index].push_back(items.first);
|
||||
}
|
||||
|
||||
// Render non-withOwnPipeline things
|
||||
for (size_t i = 0; i < OWN_PIPELINE_INDEX; i++) {
|
||||
auto& shapeKeys = sortedShapeKeys[i];
|
||||
if (shapeKeys.size() > 0) {
|
||||
const auto& shapePipeline = _shapePlumber->pickPipeline(args, keys[i]);
|
||||
args->_shapePipeline = shapePipeline;
|
||||
for (const auto& key : shapeKeys) {
|
||||
renderShapes(renderContext, _shapePlumber, inShapes.at(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render withOwnPipeline things
|
||||
for (size_t i = OWN_PIPELINE_INDEX; i < keys.size(); i++) {
|
||||
auto& shapeKeys = sortedShapeKeys[i];
|
||||
if (shapeKeys.size() > 0) {
|
||||
args->_shapePipeline = nullptr;
|
||||
for (const auto& key : shapeKeys) {
|
||||
args->_itemShapeKey = key._flags.to_ulong();
|
||||
renderShapes(renderContext, _shapePlumber, inShapes.at(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
args->_shapePipeline = nullptr;
|
||||
render::ItemBounds itemBounds;
|
||||
sortAndRenderZPassShapes(_shapePlumber, renderContext, inShapes, itemBounds);
|
||||
}
|
||||
|
||||
args->_batch = nullptr;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
//
|
||||
// Created by Andrzej Kapolka on 5/6/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -15,8 +16,45 @@
|
|||
<@include render-utils/ShaderConstants.h@>
|
||||
<@include CullFace.slh@>
|
||||
|
||||
<@if HIFI_USE_MTOON@>
|
||||
<@if HIFI_USE_SHADOW@>
|
||||
<$declareMToonMaterialTextures(ALBEDO)$>
|
||||
<@else@>
|
||||
<$declareMToonMaterialTextures(ALBEDO, HIFI_USE_NORMALMAP, SHADE, EMISSIVE, SHADING_SHIFT, MATCAP, RIM, UV_ANIMATION_MASK)$>
|
||||
<@endif@>
|
||||
<@else@>
|
||||
<@if HIFI_USE_SHADOW or HIFI_USE_UNLIT@>
|
||||
<$declareMaterialTextures(ALBEDO)$>
|
||||
<@else@>
|
||||
<@if not HIFI_USE_LIGHTMAP@>
|
||||
<@if HIFI_USE_TRANSLUCENT@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, HIFI_USE_NORMALMAP, METALLIC, EMISSIVE, OCCLUSION)$>
|
||||
<@else@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, HIFI_USE_NORMALMAP, METALLIC, EMISSIVE, OCCLUSION, SCATTERING)$>
|
||||
<@endif@>
|
||||
<@else@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, HIFI_USE_NORMALMAP, METALLIC)$>
|
||||
<$declareMaterialLightmap()$>
|
||||
<@endif@>
|
||||
<@endif@>
|
||||
<@endif@>
|
||||
|
||||
<@if not HIFI_USE_SHADOW@>
|
||||
<@if HIFI_USE_FORWARD or HIFI_USE_TRANSLUCENT@>
|
||||
<@if HIFI_USE_MTOON@>
|
||||
|
||||
<@include DefaultMaterials.slh@>
|
||||
<@include GlobalLight.slh@>
|
||||
<$declareEvalGlobalLightingAlphaBlendedMToon()$>
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
<@if HIFI_USE_FORWARD or HIFI_USE_TRANSLUCENT@>
|
||||
layout(location=0) out vec4 _fragColor0;
|
||||
<@else@>
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
<@endif@>
|
||||
<@elif HIFI_USE_FORWARD or HIFI_USE_TRANSLUCENT@>
|
||||
<@include DefaultMaterials.slh@>
|
||||
<@include GlobalLight.slh@>
|
||||
<@if HIFI_USE_LIGHTMAP@>
|
||||
|
@ -31,6 +69,7 @@
|
|||
<@endif@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
layout(location=0) out vec4 _fragColor0;
|
||||
<@else@>
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
@ -43,29 +82,6 @@
|
|||
<@include LightingModel.slh@>
|
||||
<@endif@>
|
||||
|
||||
<@if HIFI_USE_SHADOW or HIFI_USE_UNLIT@>
|
||||
<$declareMaterialTextures(ALBEDO)$>
|
||||
<@else@>
|
||||
<@if not HIFI_USE_LIGHTMAP@>
|
||||
<@if HIFI_USE_NORMALMAP and HIFI_USE_TRANSLUCENT@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL , METALLIC, EMISSIVE, OCCLUSION)$>
|
||||
<@elif HIFI_USE_NORMALMAP@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL , METALLIC, EMISSIVE, OCCLUSION, SCATTERING)$>
|
||||
<@elif HIFI_USE_TRANSLUCENT@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL , METALLIC, EMISSIVE, OCCLUSION)$>
|
||||
<@else@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL , METALLIC, EMISSIVE, OCCLUSION, SCATTERING)$>
|
||||
<@endif@>
|
||||
<@else@>
|
||||
<@if HIFI_USE_NORMALMAP@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC)$>
|
||||
<@else@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC)$>
|
||||
<@endif@>
|
||||
<$declareMaterialLightmap()$>
|
||||
<@endif@>
|
||||
<@endif@>
|
||||
|
||||
<@if HIFI_USE_FADE@>
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
@ -78,7 +94,9 @@ layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
|
|||
<@if not HIFI_USE_SHADOW@>
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color;
|
||||
<@if not HIFI_USE_MTOON@>
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color;
|
||||
<@endif@>
|
||||
<@if HIFI_USE_NORMALMAP@>
|
||||
layout(location=RENDER_UTILS_ATTR_TANGENT_WS) in vec3 _tangentWS;
|
||||
<@endif@>
|
||||
|
@ -101,15 +119,21 @@ void main(void) {
|
|||
Material mat = getMaterial();
|
||||
BITFIELD matKey = getMaterialKey(mat);
|
||||
<@if HIFI_USE_SHADOW or HIFI_USE_UNLIT@>
|
||||
<@if not HIFI_USE_MTOON@>
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$>
|
||||
<@else@>
|
||||
<$fetchMToonMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$>
|
||||
<@endif@>
|
||||
|
||||
<@if HIFI_USE_TRANSLUCENT@>
|
||||
float cutoff = getMaterialOpacityCutoff(mat);
|
||||
float opacity = getMaterialOpacity(mat) * _color.a;
|
||||
<@if HIFI_USE_TRANSLUCENT@>
|
||||
float opacity = getMaterialOpacity(mat);
|
||||
<@if not HIFI_USE_MTOON@>
|
||||
opacity *= _color.a;
|
||||
<@endif@>
|
||||
<$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKey, opacity)$>;
|
||||
<$discardInvisible(opacity)$>;
|
||||
<@else@>
|
||||
float cutoff = getMaterialOpacityCutoff(mat);
|
||||
float opacity = 1.0;
|
||||
<$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity, matKey, opacity)$>;
|
||||
<$discardTransparent(opacity)$>;
|
||||
|
@ -118,7 +142,9 @@ void main(void) {
|
|||
<@if not HIFI_USE_SHADOW@>
|
||||
vec3 albedo = getMaterialAlbedo(mat);
|
||||
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
|
||||
albedo *= _color.rgb;
|
||||
<@if not HIFI_USE_MTOON@>
|
||||
albedo *= _color.rgb;
|
||||
<@endif@>
|
||||
<@if HIFI_USE_FADE@>
|
||||
albedo += fadeEmissive;
|
||||
<@endif@>
|
||||
|
@ -134,6 +160,73 @@ void main(void) {
|
|||
opacity,
|
||||
albedo * isUnlitEnabled());
|
||||
<@endif@>
|
||||
<@elif HIFI_USE_MTOON@>
|
||||
vec3 uvScrollSpeed = getMaterialUVScrollSpeed(mat);
|
||||
float time = getMaterialTime(mat);
|
||||
<@if HIFI_USE_NORMALMAP@>
|
||||
<$fetchMToonMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, normalTex, shadeTex, emissiveTex, shadingShiftTex, rimTex, uvScrollSpeed, time)$>
|
||||
<@else@>
|
||||
<$fetchMToonMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, _SCRIBE_NULL, shadeTex, emissiveTex, shadingShiftTex, rimTex, uvScrollSpeed, time)$>
|
||||
<@endif@>
|
||||
|
||||
float cutoff = getMaterialOpacityCutoff(mat);
|
||||
<@if HIFI_USE_TRANSLUCENT@>
|
||||
float opacity = getMaterialOpacity(mat);
|
||||
<$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKey, opacity)$>;
|
||||
<$discardInvisible(opacity)$>;
|
||||
<@else@>
|
||||
float opacity = 1.0;
|
||||
<$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity, matKey, opacity)$>;
|
||||
<$discardTransparent(opacity)$>;
|
||||
<@endif@>
|
||||
|
||||
vec3 albedo = getMaterialAlbedo(mat);
|
||||
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
|
||||
|
||||
vec3 emissive = getMaterialEmissive(mat);
|
||||
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
|
||||
|
||||
<@if HIFI_USE_NORMALMAP@>
|
||||
vec3 fragNormalWS;
|
||||
<$evalMaterialNormalLOD(_positionES, normalTex, _normalWS, _tangentWS, fragNormalWS)$>
|
||||
<@else@>
|
||||
vec3 fragNormalWS = _normalWS;
|
||||
<@endif@>
|
||||
fragNormalWS = evalFrontOrBackFaceNormal(normalize(fragNormalWS));
|
||||
|
||||
vec3 shade = getMaterialShade(mat);
|
||||
<$evalMaterialShade(shadeTex, shade, matKey, shade)$>;
|
||||
|
||||
float shadingShift = getMaterialShadingShift(mat);
|
||||
<$evalMaterialShadingShift(shadingShiftTex, shadingShift, matKey, shadingShift)$>;
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
float metallic = DEFAULT_METALLIC;
|
||||
vec3 fresnel = getFresnelF0(metallic, albedo);
|
||||
|
||||
vec4 color = vec4(evalGlobalLightingAlphaBlendedMToon(
|
||||
cam._viewInverse, 1.0, _positionES.xyz, fragNormalWS,
|
||||
albedo, fresnel, metallic, emissive, DEFAULT_ROUGHNESS, opacity,
|
||||
shade, shadingShift, getMaterialShadingToony(mat), getMaterialMatcap(mat), getMaterialParametricRim(mat),
|
||||
getMaterialParametricRimFresnelPower(mat), getMaterialParametricRimLift(mat), rimTex, getMaterialRimLightingMix(mat), matKey), opacity);
|
||||
|
||||
<@if HIFI_USE_FORWARD or HIFI_USE_TRANSLUCENT@>
|
||||
_fragColor0 = isUnlitEnabled() * vec4(color.rgb
|
||||
<@if HIFI_USE_FADE@>
|
||||
+ fadeEmissive
|
||||
<@endif@>
|
||||
, color.a);
|
||||
<@else@>
|
||||
packDeferredFragmentUnlit(
|
||||
fragNormalWS,
|
||||
1.0,
|
||||
color.rgb
|
||||
<@if HIFI_USE_FADE@>
|
||||
+ fadeEmissive
|
||||
<@endif@>
|
||||
);
|
||||
<@endif@>
|
||||
|
||||
<@else@>
|
||||
<@if not HIFI_USE_LIGHTMAP@>
|
||||
<@if HIFI_USE_NORMALMAP and HIFI_USE_TRANSLUCENT@>
|
||||
|
@ -154,14 +247,13 @@ void main(void) {
|
|||
<@endif@>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmap)$>
|
||||
<@endif@>
|
||||
|
||||
<@if HIFI_USE_TRANSLUCENT@>
|
||||
|
||||
float cutoff = getMaterialOpacityCutoff(mat);
|
||||
<@if HIFI_USE_TRANSLUCENT@>
|
||||
float opacity = getMaterialOpacity(mat) * _color.a;
|
||||
<$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKey, opacity)$>;
|
||||
<$discardInvisible(opacity)$>;
|
||||
<@else@>
|
||||
float cutoff = getMaterialOpacityCutoff(mat);
|
||||
float opacity = 1.0;
|
||||
<$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity, matKey, opacity)$>;
|
||||
<$discardTransparent(opacity)$>;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
//
|
||||
// Created by Hifi Engine Team
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -47,7 +48,9 @@ layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
|||
<@if not HIFI_USE_SHADOW@>
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
||||
<@if not HIFI_USE_MTOON@>
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
||||
<@endif@>
|
||||
<@if HIFI_USE_NORMALMAP@>
|
||||
layout(location=RENDER_UTILS_ATTR_TANGENT_WS) out vec3 _tangentWS;
|
||||
<@endif@>
|
||||
|
@ -96,7 +99,9 @@ void main(void) {
|
|||
_texCoord01 = vec4(0.0);
|
||||
}
|
||||
<@else@>
|
||||
<@if not HIFI_USE_MTOON@>
|
||||
_color = color_sRGBAToLinear(inColor);
|
||||
<@endif@>
|
||||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _positionWS, _texCoord01.xy)$>
|
||||
|
|
|
@ -1 +1 @@
|
|||
DEFINES (normalmap translucent:f unlit:f/lightmap:f)/shadow fade:f/forward:f deformed:v/deformeddq:v
|
||||
DEFINES (normalmap translucent:f unlit:f/lightmap:f)/shadow mtoon fade:f/forward:f deformed:v/deformeddq:v
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
// Created by Olivier Prat on 11/06/2017.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -12,6 +13,7 @@
|
|||
#define hifi_render_utils_HighlightStyle_h
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -21,23 +23,59 @@ namespace render {
|
|||
class HighlightStyle {
|
||||
public:
|
||||
struct RGBA {
|
||||
glm::vec3 color{ 1.0f, 0.7f, 0.2f };
|
||||
float alpha{ 0.9f };
|
||||
glm::vec3 color { 1.0f, 0.7f, 0.2f };
|
||||
float alpha { 0.9f };
|
||||
|
||||
RGBA(const glm::vec3& c, float a) : color(c), alpha(a) {}
|
||||
|
||||
std::string toString() const { return glm::to_string(color) + " " + std::to_string(alpha); }
|
||||
};
|
||||
|
||||
RGBA _outlineUnoccluded{ { 1.0f, 0.7f, 0.2f }, 0.9f };
|
||||
RGBA _outlineOccluded{ { 1.0f, 0.7f, 0.2f }, 0.9f };
|
||||
RGBA _fillUnoccluded{ { 0.2f, 0.7f, 1.0f }, 0.0f };
|
||||
RGBA _fillOccluded{ { 0.2f, 0.7f, 1.0f }, 0.0f };
|
||||
RGBA _outlineUnoccluded { { 1.0f, 0.7f, 0.2f }, 0.9f };
|
||||
RGBA _outlineOccluded { { 1.0f, 0.7f, 0.2f }, 0.9f };
|
||||
RGBA _fillUnoccluded { { 0.2f, 0.7f, 1.0f }, 0.0f };
|
||||
RGBA _fillOccluded { { 0.2f, 0.7f, 1.0f }, 0.0f };
|
||||
|
||||
float _outlineWidth{ 2.0f };
|
||||
bool _isOutlineSmooth{ false };
|
||||
float _outlineWidth { 2.0f };
|
||||
bool _isOutlineSmooth { false };
|
||||
|
||||
bool isFilled() const {
|
||||
return _fillUnoccluded.alpha > 5e-3f || _fillOccluded.alpha > 5e-3f;
|
||||
}
|
||||
|
||||
std::string toString() const {
|
||||
return _outlineUnoccluded.toString() + _outlineOccluded.toString() + _fillUnoccluded.toString() +
|
||||
_fillOccluded.toString() + std::to_string(_outlineWidth) + std::to_string(_isOutlineSmooth);
|
||||
}
|
||||
|
||||
static HighlightStyle calculateOutlineStyle(uint8_t mode, float outlineWidth, const glm::vec3& outline,
|
||||
const glm::vec3& position, const ViewFrustum& viewFrustum, size_t screenHeight) {
|
||||
HighlightStyle style;
|
||||
style._outlineUnoccluded.color = outline;
|
||||
style._outlineUnoccluded.alpha = 1.0f;
|
||||
style._outlineOccluded.alpha = 0.0f;
|
||||
style._fillUnoccluded.alpha = 0.0f;
|
||||
style._fillOccluded.alpha = 0.0f;
|
||||
style._isOutlineSmooth = false;
|
||||
|
||||
if (mode == 1) { // OUTLINE_WORLD
|
||||
// FIXME: this is a hacky approximation, which gives us somewhat accurate widths with distance based falloff.
|
||||
// Our outline implementation doesn't support the necessary vertex based extrusion to do real world based outlines.
|
||||
glm::vec4 viewPos = glm::inverse(viewFrustum.getView()) * glm::vec4(position, 1.0f);
|
||||
|
||||
const glm::mat4& projection = viewFrustum.getProjection();
|
||||
glm::vec4 p1 = projection * (viewPos + glm::vec4(0.0f, 0.5f * outlineWidth, 0.0f, 0.0f));
|
||||
p1 /= p1.w;
|
||||
glm::vec4 p2 = projection * (viewPos - glm::vec4(0.0f, 0.5f * outlineWidth, 0.0f, 0.0f));
|
||||
p2 /= p2.w;
|
||||
|
||||
style._outlineWidth = 0.5 * screenHeight * fabs(p1.y - p2.y);
|
||||
} else { // OUTLINE_SCREEN
|
||||
style._outlineWidth = outlineWidth * screenHeight;
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Sam Gateau on 1/26/16.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -160,4 +161,11 @@ namespace render {
|
|||
}
|
||||
return payload->passesZoneOcclusionTest(containingZones);
|
||||
}
|
||||
}
|
||||
|
||||
template <> HighlightStyle payloadGetOutlineStyle(const PayloadProxyInterface::Pointer& payload, const ViewFrustum& viewFrustum, const size_t height) {
|
||||
if (!payload) {
|
||||
return HighlightStyle();
|
||||
}
|
||||
return payload->getOutlineStyle(viewFrustum, height);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Sam Gateau on 1/26/16.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -29,6 +30,7 @@
|
|||
#include "ShapePipeline.h"
|
||||
|
||||
#include "BlendshapeConstants.h"
|
||||
#include "HighlightStyle.h"
|
||||
|
||||
namespace render {
|
||||
|
||||
|
@ -104,15 +106,17 @@ public:
|
|||
META_CULL_GROUP, // As a meta item, the culling of my sub items is based solely on my bounding box and my visibility in the view
|
||||
SUB_META_CULLED, // As a sub item of a meta render item set as cull group, need to be set to my culling to the meta render it
|
||||
|
||||
FIRST_TAG_BIT, // 8 Tags available to organize the items and filter them against
|
||||
FIRST_TAG_BIT, // 8 Tags available to organize the items and filter them against
|
||||
LAST_TAG_BIT = FIRST_TAG_BIT + NUM_TAGS,
|
||||
|
||||
FIRST_LAYER_BIT, // 8 Exclusive Layers (encoded in 3 bits) available to organize the items in layers, an item can only belong to ONE layer
|
||||
FIRST_LAYER_BIT, // 8 Exclusive Layers (encoded in 3 bits) available to organize the items in layers, an item can only belong to ONE layer
|
||||
LAST_LAYER_BIT = FIRST_LAYER_BIT + NUM_LAYER_BITS,
|
||||
|
||||
OUTLINE, // Item has an outline
|
||||
|
||||
__SMALLER, // Reserved bit for spatialized item to indicate that it is smaller than expected in the cell in which it belongs (probably because it overlaps over several smaller cells)
|
||||
|
||||
NUM_FLAGS, // Not a valid flag
|
||||
NUM_FLAGS, // Not a valid flag
|
||||
};
|
||||
typedef std::bitset<NUM_FLAGS> Flags;
|
||||
|
||||
|
@ -170,6 +174,9 @@ public:
|
|||
Builder& withLayer(uint8_t layer) { _flags = evalLayerBitsWithKeyBits(layer, _flags.to_ulong()); return (*this); }
|
||||
Builder& withoutLayer() { return withLayer(LAYER_DEFAULT); }
|
||||
|
||||
Builder& withOutline() { _flags.set(OUTLINE); return (*this); }
|
||||
Builder& withoutOutline() { _flags.reset(OUTLINE); return (*this); }
|
||||
|
||||
// Convenient standard keys that we will keep on using all over the place
|
||||
static Builder opaqueShape() { return Builder().withTypeShape(); }
|
||||
static Builder transparentShape() { return Builder().withTypeShape().withTransparent(); }
|
||||
|
@ -213,6 +220,8 @@ public:
|
|||
bool isLayered() const { return getLayer() != LAYER_DEFAULT; }
|
||||
bool isSpatial() const { return !isLayered(); }
|
||||
|
||||
bool isOutline() const { return _flags[OUTLINE]; }
|
||||
|
||||
// Probably not public, flags used by the scene
|
||||
bool isSmall() const { return _flags[__SMALLER]; }
|
||||
void setSmaller(bool smaller) { (smaller ? _flags.set(__SMALLER) : _flags.reset(__SMALLER)); }
|
||||
|
@ -284,6 +293,9 @@ public:
|
|||
Builder& withoutLayered() { _value = ItemKey::evalLayerBitsWithKeyBits(ItemKey::LAYER_DEFAULT, _value.to_ulong()); _mask |= ItemKey::KEY_LAYER_BITS_MASK; return (*this); }
|
||||
Builder& withLayer(uint8_t layer) { _value = ItemKey::evalLayerBitsWithKeyBits(layer, _value.to_ulong()); _mask |= ItemKey::KEY_LAYER_BITS_MASK; return (*this); }
|
||||
|
||||
Builder& withoutOutline() { _value.reset(ItemKey::OUTLINE); _mask.set(ItemKey::OUTLINE); return (*this); }
|
||||
Builder& withOutline() { _value.set(ItemKey::OUTLINE); _mask.set(ItemKey::OUTLINE); return (*this); }
|
||||
|
||||
Builder& withNothing() { _value.reset(); _mask.reset(); return (*this); }
|
||||
|
||||
// Convenient standard keys that we will keep on using all over the place
|
||||
|
@ -440,6 +452,8 @@ public:
|
|||
|
||||
virtual bool passesZoneOcclusionTest(const std::unordered_set<QUuid>& containingZones) const = 0;
|
||||
|
||||
virtual HighlightStyle getOutlineStyle(const ViewFrustum& viewFrustum, const size_t height) const = 0;
|
||||
|
||||
~PayloadInterface() {}
|
||||
|
||||
// Status interface is local to the base class
|
||||
|
@ -493,6 +507,8 @@ public:
|
|||
|
||||
bool passesZoneOcclusionTest(const std::unordered_set<QUuid>& containingZones) const { return _payload->passesZoneOcclusionTest(containingZones); }
|
||||
|
||||
HighlightStyle getOutlineStyle(const ViewFrustum& viewFrustum, const size_t height) const { return _payload->getOutlineStyle(viewFrustum, height); }
|
||||
|
||||
// Access the status
|
||||
const StatusPointer& getStatus() const { return _payload->getStatus(); }
|
||||
|
||||
|
@ -547,6 +563,12 @@ template <class T> uint32_t metaFetchMetaSubItems(const std::shared_ptr<T>& payl
|
|||
// Allows payloads to determine if they should render or not, based on the zones that contain the current camera
|
||||
template <class T> bool payloadPassesZoneOcclusionTest(const std::shared_ptr<T>& payloadData, const std::unordered_set<QUuid>& containingZones) { return true; }
|
||||
|
||||
// Outline Interface
|
||||
// Allows payloads to specify an outline style
|
||||
template <class T> HighlightStyle payloadGetOutlineStyle(const std::shared_ptr<T>& payloadData, const ViewFrustum& viewFrustum, const size_t height) {
|
||||
return HighlightStyle();
|
||||
}
|
||||
|
||||
// THe Payload class is the real Payload to be used
|
||||
// THis allow anything to be turned into a Payload as long as the required interface functions are available
|
||||
// When creating a new kind of payload from a new "stuff" class then you need to create specialized version for "stuff"
|
||||
|
@ -573,6 +595,8 @@ public:
|
|||
|
||||
virtual bool passesZoneOcclusionTest(const std::unordered_set<QUuid>& containingZones) const override { return payloadPassesZoneOcclusionTest<T>(_data, containingZones); }
|
||||
|
||||
virtual HighlightStyle getOutlineStyle(const ViewFrustum& viewFrustum, const size_t height) const override { return payloadGetOutlineStyle<T>(_data, viewFrustum, height); }
|
||||
|
||||
protected:
|
||||
DataPointer _data;
|
||||
|
||||
|
@ -628,6 +652,7 @@ public:
|
|||
virtual void render(RenderArgs* args) = 0;
|
||||
virtual uint32_t metaFetchMetaSubItems(ItemIDs& subItems) const = 0;
|
||||
virtual bool passesZoneOcclusionTest(const std::unordered_set<QUuid>& containingZones) const = 0;
|
||||
virtual HighlightStyle getOutlineStyle(const ViewFrustum& viewFrustum, const size_t height) const = 0;
|
||||
|
||||
// FIXME: this isn't the best place for this since it's only used for ModelEntities, but currently all Entities use PayloadProxyInterface
|
||||
virtual void handleBlendedVertices(int blendshapeNumber, const QVector<BlendshapeOffset>& blendshapeOffsets,
|
||||
|
@ -640,6 +665,7 @@ template <> void payloadRender(const PayloadProxyInterface::Pointer& payload, Re
|
|||
template <> uint32_t metaFetchMetaSubItems(const PayloadProxyInterface::Pointer& payload, ItemIDs& subItems);
|
||||
template <> const ShapeKey shapeGetShapeKey(const PayloadProxyInterface::Pointer& payload);
|
||||
template <> bool payloadPassesZoneOcclusionTest(const PayloadProxyInterface::Pointer& payload, const std::unordered_set<QUuid>& containingZones);
|
||||
template <> HighlightStyle payloadGetOutlineStyle(const PayloadProxyInterface::Pointer& payload, const ViewFrustum& viewFrustum, const size_t height);
|
||||
|
||||
typedef Item::PayloadPointer PayloadPointer;
|
||||
typedef std::vector<PayloadPointer> Payloads;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Zach Pomerantz on 12/22/2016.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -35,18 +36,20 @@ void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varyin
|
|||
const auto nonspatialSelection = task.addJob<FetchNonspatialItems>("FetchLayeredSelection", nonspatialFilter);
|
||||
|
||||
// Multi filter visible items into different buckets
|
||||
const int NUM_SPATIAL_FILTERS = 4;
|
||||
const int NUM_SPATIAL_FILTERS = 5;
|
||||
const int NUM_NON_SPATIAL_FILTERS = 3;
|
||||
const int OPAQUE_SHAPE_BUCKET = 0;
|
||||
const int TRANSPARENT_SHAPE_BUCKET = 1;
|
||||
const int LIGHT_BUCKET = 2;
|
||||
const int META_BUCKET = 3;
|
||||
const int OUTLINE_BUCKET = 4;
|
||||
const int BACKGROUND_BUCKET = 2;
|
||||
MultiFilterItems<NUM_SPATIAL_FILTERS>::ItemFilterArray spatialFilters = { {
|
||||
ItemFilter::Builder::opaqueShape(),
|
||||
ItemFilter::Builder::transparentShape(),
|
||||
ItemFilter::Builder::light(),
|
||||
ItemFilter::Builder::meta()
|
||||
ItemFilter::Builder::meta(),
|
||||
ItemFilter::Builder().withVisible().withOutline()
|
||||
} };
|
||||
MultiFilterItems<NUM_NON_SPATIAL_FILTERS>::ItemFilterArray nonspatialFilters = { {
|
||||
ItemFilter::Builder::opaqueShape(),
|
||||
|
@ -76,7 +79,7 @@ void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varyin
|
|||
|
||||
task.addJob<ClearContainingZones>("ClearContainingZones");
|
||||
|
||||
output = Output(BucketList{ opaques, transparents, lights, metas,
|
||||
output = Output(BucketList{ opaques, transparents, lights, metas, filteredSpatialBuckets[OUTLINE_BUCKET],
|
||||
filteredLayeredOpaque.getN<FilterLayeredItems::Outputs>(0), filteredLayeredTransparent.getN<FilterLayeredItems::Outputs>(0),
|
||||
filteredLayeredOpaque.getN<FilterLayeredItems::Outputs>(1), filteredLayeredTransparent.getN<FilterLayeredItems::Outputs>(1),
|
||||
background }, spatialSelection);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Zach Pomerantz on 12/22/2016.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -23,6 +24,7 @@ public:
|
|||
TRANSPARENT_SHAPE,
|
||||
LIGHT,
|
||||
META,
|
||||
OUTLINE,
|
||||
LAYER_FRONT_OPAQUE_SHAPE,
|
||||
LAYER_FRONT_TRANSPARENT_SHAPE,
|
||||
LAYER_HUD_OPAQUE_SHAPE,
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Sam Gateau on 1/11/15.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -608,6 +609,22 @@ void Scene::resetSelections(const Transaction::SelectionResets& transactions) {
|
|||
}
|
||||
}
|
||||
|
||||
void Scene::addItemToSelection(const std::string& selectionName, ItemID itemID) {
|
||||
std::unique_lock<std::mutex> lock(_selectionsMutex);
|
||||
auto found = _selections.find(selectionName);
|
||||
if (found == _selections.end()) {
|
||||
Selection selection = Selection(selectionName, { itemID });
|
||||
_selections[selectionName] = selection;
|
||||
} else {
|
||||
_selections[selectionName].add(itemID);
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::removeSelection(const std::string& selectionName) {
|
||||
std::unique_lock<std::mutex> lock(_selectionsMutex);
|
||||
_selections.erase(selectionName);
|
||||
}
|
||||
|
||||
// Access a particular Stage (empty if doesn't exist)
|
||||
// Thread safe
|
||||
StagePointer Scene::getStage(const Stage::Name& name) const {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Sam Gateau on 1/11/15.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -166,6 +167,14 @@ public:
|
|||
// Thread safe
|
||||
bool isSelectionEmpty(const Selection::Name& name) const;
|
||||
|
||||
// Add a single item to a selection by name
|
||||
// Thread safe
|
||||
void addItemToSelection(const std::string& selectionName, ItemID itemID);
|
||||
|
||||
// Remove a selection by name
|
||||
// Thread safe
|
||||
void removeSelection(const std::string& selectionName);
|
||||
|
||||
// This next call are NOT threadsafe, you have to call them from the correct thread to avoid any potential issues
|
||||
|
||||
// Access a particular item from its ID
|
||||
|
@ -194,6 +203,8 @@ public:
|
|||
void setItemTransition(ItemID id, Index transitionId);
|
||||
void removeItemTransition(ItemID id);
|
||||
|
||||
HighlightStyle getOutlineStyle(ItemID id, const ViewFrustum& viewFrustum, uint16_t height) { return _items[id].getOutlineStyle(viewFrustum, height); }
|
||||
|
||||
protected:
|
||||
|
||||
// Thread safe elements that can be accessed from anywhere
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Sam Gateau on 4/4/2017.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -37,7 +38,8 @@ namespace render {
|
|||
|
||||
// Test if the ID is in the selection, return the index or -1 if not present
|
||||
static const int NOT_FOUND{ -1 };
|
||||
|
||||
|
||||
void add(ItemID id) { _items.push_back(id); }
|
||||
int find(ItemID id) const;
|
||||
bool contains(ItemID id) const { return find(id) > NOT_FOUND; }
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Zach Pomerantz on 12/31/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
// Copyright 2024 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -38,6 +39,7 @@ public:
|
|||
FADE,
|
||||
CULL_FACE_NONE, // if neither of these are set, we're CULL_FACE_BACK
|
||||
CULL_FACE_FRONT,
|
||||
MTOON,
|
||||
|
||||
OWN_PIPELINE,
|
||||
INVALID,
|
||||
|
@ -84,6 +86,7 @@ public:
|
|||
Builder& withDepthBias() { _flags.set(DEPTH_BIAS); return (*this); }
|
||||
Builder& withWireframe() { _flags.set(WIREFRAME); return (*this); }
|
||||
Builder& withFade() { _flags.set(FADE); return (*this); }
|
||||
Builder& withMToon() { _flags.set(MTOON); return (*this); }
|
||||
|
||||
Builder& withoutCullFace() { return withCullFaceMode(graphics::MaterialKey::CullFaceMode::CULL_NONE); }
|
||||
Builder& withCullFaceMode(graphics::MaterialKey::CullFaceMode cullFaceMode) {
|
||||
|
@ -184,6 +187,9 @@ public:
|
|||
Builder& withFade() { _flags.set(FADE); _mask.set(FADE); return (*this); }
|
||||
Builder& withoutFade() { _flags.reset(FADE); _mask.set(FADE); return (*this); }
|
||||
|
||||
Builder& withMToon() { _flags.set(MTOON); _mask.set(MTOON); return (*this); }
|
||||
Builder& withoutMToon() { _flags.reset(MTOON); _mask.set(MTOON); return (*this); }
|
||||
|
||||
Builder& withCustom(uint8_t custom) { _flags &= (~CUSTOM_MASK); _flags |= (custom << CUSTOM_0); _mask |= (CUSTOM_MASK); return (*this); }
|
||||
Builder& withoutCustom() { _flags &= (~CUSTOM_MASK); _mask |= (CUSTOM_MASK); return (*this); }
|
||||
|
||||
|
@ -211,6 +217,7 @@ public:
|
|||
bool isWireframe() const { return _flags[WIREFRAME]; }
|
||||
bool isCullFace() const { return !_flags[CULL_FACE_NONE] && !_flags[CULL_FACE_FRONT]; }
|
||||
bool isFaded() const { return _flags[FADE]; }
|
||||
bool isMToon() const { return _flags[MTOON]; }
|
||||
|
||||
bool hasOwnPipeline() const { return _flags[OWN_PIPELINE]; }
|
||||
bool isValid() const { return !_flags[INVALID]; }
|
||||
|
@ -250,6 +257,7 @@ inline QDebug operator<<(QDebug debug, const ShapeKey& key) {
|
|||
<< "isWireframe:" << key.isWireframe()
|
||||
<< "isCullFace:" << key.isCullFace()
|
||||
<< "isFaded:" << key.isFaded()
|
||||
<< "isMToon:" << key.isMToon()
|
||||
<< "]";
|
||||
}
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue