diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index c607f678b6..6451e873c9 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -126,7 +126,7 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) { batch.setModelTransform(renderTransform); if (args->_renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE) { - drawMaterial->setTextureTransforms(textureTransform); + drawMaterial->setTextureTransforms(textureTransform, MaterialMappingMode::UV, true); // bind the material RenderPipelines::bindMaterial(drawMaterial, batch, args->_enableTexturing); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index c243f772e2..2b7135413d 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -385,6 +385,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_MATERIAL_MAPPING_SCALE, materialMappingScale); CHECK_PROPERTY_CHANGE(PROP_MATERIAL_MAPPING_ROT, materialMappingRot); CHECK_PROPERTY_CHANGE(PROP_MATERIAL_DATA, materialData); + CHECK_PROPERTY_CHANGE(PROP_MATERIAL_REPEAT, materialRepeat); CHECK_PROPERTY_CHANGE(PROP_VISIBLE_IN_SECONDARY_CAMERA, isVisibleInSecondaryCamera); CHECK_PROPERTY_CHANGE(PROP_PARTICLE_SPIN, particleSpin); CHECK_PROPERTY_CHANGE(PROP_SPIN_SPREAD, spinSpread); @@ -754,7 +755,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * Otherwise the property value is parsed as an unsigned integer, specifying the mesh index to modify. Invalid values are * parsed to 0. * @property {string} materialMappingMode="uv" - How the material is mapped to the entity. Either "uv" or - * "projected". Currently, only "uv" is supported. + * "projected". In "uv" mode, the material will be evaluated within the UV space of the mesh it is applied to. In + * "projected" mode, the 3D transform of the Material Entity will be used to evaluate the texture coordinates for the material. * @property {Vec2} materialMappingPos=0,0 - Offset position in UV-space of the top left of the material, range * { x: 0, y: 0 }{ x: 1, y: 1 }. * @property {Vec2} materialMappingScale=1,1 - How much to scale the material within the parent's UV-space. @@ -762,6 +764,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {string} materialData="" - Used to store {@link MaterialResource} data as a JSON string. You can use * JSON.parse() to parse the string into a JavaScript object which you can manipulate the properties of, and * use JSON.stringify() to convert the object into a string to put in the property. + * @property {boolean} materialRepeat=true - If true, the material will repeat. If false, fragments outside of texCoord 0 - 1 will be discarded. + * Works in both "uv" and "projected" modes. * @example Color a sphere using a Material entity. * var entityID = Entities.addEntity({ * type: "Sphere", @@ -1485,6 +1489,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_MAPPING_SCALE, materialMappingScale); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_MAPPING_ROT, materialMappingRot); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_DATA, materialData); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_REPEAT, materialRepeat); } /**jsdoc @@ -1666,6 +1671,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(materialMappingScale, vec2, setMaterialMappingScale); COPY_PROPERTY_FROM_QSCRIPTVALUE(materialMappingRot, float, setMaterialMappingRot); COPY_PROPERTY_FROM_QSCRIPTVALUE(materialData, QString, setMaterialData); + COPY_PROPERTY_FROM_QSCRIPTVALUE(materialRepeat, bool, setMaterialRepeat); COPY_PROPERTY_FROM_QSCRIPTVALUE(isVisibleInSecondaryCamera, bool, setIsVisibleInSecondaryCamera); COPY_PROPERTY_FROM_QSCRIPTVALUE(particleSpin, float, setParticleSpin); COPY_PROPERTY_FROM_QSCRIPTVALUE(spinSpread, float, setSpinSpread); @@ -2061,6 +2067,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_MATERIAL_MAPPING_SCALE, MaterialMappingScale, materialMappingScale, vec2); ADD_PROPERTY_TO_MAP(PROP_MATERIAL_MAPPING_ROT, MaterialMappingRot, materialMappingRot, float); ADD_PROPERTY_TO_MAP(PROP_MATERIAL_DATA, MaterialData, materialData, QString); + ADD_PROPERTY_TO_MAP(PROP_MATERIAL_REPEAT, MaterialRepeat, materialRepeat, bool); ADD_PROPERTY_TO_MAP(PROP_VISIBLE_IN_SECONDARY_CAMERA, IsVisibleInSecondaryCamera, isVisibleInSecondaryCamera, bool); @@ -2511,6 +2518,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy APPEND_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_SCALE, properties.getMaterialMappingScale()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_ROT, properties.getMaterialMappingRot()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_DATA, properties.getMaterialData()); + APPEND_ENTITY_PROPERTY(PROP_MATERIAL_REPEAT, properties.getMaterialRepeat()); } APPEND_ENTITY_PROPERTY(PROP_NAME, properties.getName()); @@ -2898,6 +2906,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_MAPPING_SCALE, vec2, setMaterialMappingScale); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_MAPPING_ROT, float, setMaterialMappingRot); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_DATA, QString, setMaterialData); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_REPEAT, bool, setMaterialRepeat); } READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NAME, QString, setName); @@ -3137,6 +3146,7 @@ void EntityItemProperties::markAllChanged() { _materialMappingScaleChanged = true; _materialMappingRotChanged = true; _materialDataChanged = true; + _materialRepeatChanged = true; // Certifiable Properties _itemNameChanged = true; @@ -3587,6 +3597,9 @@ QList EntityItemProperties::listChangedProperties() { if (materialDataChanged()) { out += "materialData"; } + if (materialRepeatChanged()) { + out += "materialRepeat"; + } if (isVisibleInSecondaryCameraChanged()) { out += "isVisibleInSecondaryCamera"; } diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index c91ccda5aa..87fefb5c1b 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -241,6 +241,7 @@ public: DEFINE_PROPERTY_REF(PROP_MATERIAL_MAPPING_SCALE, MaterialMappingScale, materialMappingScale, glm::vec2, glm::vec2(1.0f)); DEFINE_PROPERTY_REF(PROP_MATERIAL_MAPPING_ROT, MaterialMappingRot, materialMappingRot, float, 0); DEFINE_PROPERTY_REF(PROP_MATERIAL_DATA, MaterialData, materialData, QString, ""); + DEFINE_PROPERTY_REF(PROP_MATERIAL_REPEAT, MaterialRepeat, materialRepeat, bool, true); DEFINE_PROPERTY(PROP_VISIBLE_IN_SECONDARY_CAMERA, IsVisibleInSecondaryCamera, isVisibleInSecondaryCamera, bool, ENTITY_ITEM_DEFAULT_VISIBLE_IN_SECONDARY_CAMERA); diff --git a/libraries/entities/src/EntityPropertyFlags.cpp b/libraries/entities/src/EntityPropertyFlags.cpp index c077b153b8..4f3c35ce0a 100644 --- a/libraries/entities/src/EntityPropertyFlags.cpp +++ b/libraries/entities/src/EntityPropertyFlags.cpp @@ -175,6 +175,7 @@ QDebug& operator<<(QDebug& dbg, const EntityPropertyFlags& f) { result = f.getHasProperty(PROP_MATERIAL_MAPPING_SCALE) ? result + "materialMappingScale " : result; result = f.getHasProperty(PROP_MATERIAL_MAPPING_ROT) ? result + "materialMappingRot " : result; result = f.getHasProperty(PROP_MATERIAL_DATA) ? result + "materialData " : result; + result = f.getHasProperty(PROP_MATERIAL_REPEAT) ? result + "materialRepeat " : result; result = f.getHasProperty(PROP_VISIBLE_IN_SECONDARY_CAMERA) ? result + "visibleInSecondaryCamera " : result; result = f.getHasProperty(PROP_PARTICLE_SPIN) ? result + "particleSpin " : result; result = f.getHasProperty(PROP_SPIN_START) ? result + "spinStart " : result; diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index d2f687fbd3..e6649f74aa 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -275,6 +275,8 @@ enum EntityPropertyList { PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, + PROP_MATERIAL_REPEAT, + //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, diff --git a/libraries/entities/src/MaterialEntityItem.cpp b/libraries/entities/src/MaterialEntityItem.cpp index 825dd83348..cec602a5e1 100644 --- a/libraries/entities/src/MaterialEntityItem.cpp +++ b/libraries/entities/src/MaterialEntityItem.cpp @@ -41,6 +41,7 @@ EntityItemProperties MaterialEntityItem::getProperties(const EntityPropertyFlags COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialMappingScale, getMaterialMappingScale); COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialMappingRot, getMaterialMappingRot); COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialData, getMaterialData); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialRepeat, getMaterialRepeat); return properties; } @@ -55,6 +56,7 @@ bool MaterialEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(materialMappingScale, setMaterialMappingScale); SET_ENTITY_PROPERTY_FROM_PROPERTIES(materialMappingRot, setMaterialMappingRot); SET_ENTITY_PROPERTY_FROM_PROPERTIES(materialData, setMaterialData); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(materialRepeat, setMaterialRepeat); if (somethingChanged) { bool wantDebug = false; @@ -85,6 +87,7 @@ int MaterialEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* da READ_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_SCALE, glm::vec2, setMaterialMappingScale); READ_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_ROT, float, setMaterialMappingRot); READ_ENTITY_PROPERTY(PROP_MATERIAL_DATA, QString, setMaterialData); + READ_ENTITY_PROPERTY(PROP_MATERIAL_REPEAT, bool, setMaterialRepeat); return bytesRead; } @@ -99,6 +102,7 @@ EntityPropertyFlags MaterialEntityItem::getEntityProperties(EncodeBitstreamParam requestedProperties += PROP_MATERIAL_MAPPING_SCALE; requestedProperties += PROP_MATERIAL_MAPPING_ROT; requestedProperties += PROP_MATERIAL_DATA; + requestedProperties += PROP_MATERIAL_REPEAT; return requestedProperties; } @@ -119,6 +123,7 @@ void MaterialEntityItem::appendSubclassData(OctreePacketData* packetData, Encode APPEND_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_SCALE, getMaterialMappingScale()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_ROT, getMaterialMappingRot()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_DATA, getMaterialData()); + APPEND_ENTITY_PROPERTY(PROP_MATERIAL_REPEAT, getMaterialRepeat()); } void MaterialEntityItem::debugDump() const { @@ -128,6 +133,7 @@ void MaterialEntityItem::debugDump() const { qCDebug(entities) << " material url:" << _materialURL; qCDebug(entities) << " current material name:" << _currentMaterialName.c_str(); qCDebug(entities) << " material mapping mode:" << _materialMappingMode; + qCDebug(entities) << " material repeat:" << _materialRepeat; qCDebug(entities) << " priority:" << _priority; qCDebug(entities) << " parent material name:" << _parentMaterialName; qCDebug(entities) << " material mapping pos:" << _materialMappingPos; @@ -140,7 +146,12 @@ void MaterialEntityItem::debugDump() const { } void MaterialEntityItem::setUnscaledDimensions(const glm::vec3& value) { - EntityItem::setUnscaledDimensions(ENTITY_ITEM_DEFAULT_DIMENSIONS); + _desiredDimensions = value; + if (_materialMappingMode == MaterialMappingMode::UV) { + EntityItem::setUnscaledDimensions(ENTITY_ITEM_DEFAULT_DIMENSIONS); + } else if (_materialMappingMode == MaterialMappingMode::PROJECTED) { + EntityItem::setUnscaledDimensions(value); + } } std::shared_ptr MaterialEntityItem::getMaterial() const { @@ -208,6 +219,23 @@ void MaterialEntityItem::setMaterialData(const QString& materialData) { } } +void MaterialEntityItem::setMaterialMappingMode(MaterialMappingMode mode) { + if (_materialMappingMode != mode) { + removeMaterial(); + _materialMappingMode = mode; + setUnscaledDimensions(_desiredDimensions); + applyMaterial(); + } +} + +void MaterialEntityItem::setMaterialRepeat(bool repeat) { + if (_materialRepeat != repeat) { + removeMaterial(); + _materialRepeat = repeat; + applyMaterial(); + } +} + void MaterialEntityItem::setMaterialMappingPos(const glm::vec2& materialMappingPos) { if (_materialMappingPos != materialMappingPos) { removeMaterial(); @@ -256,6 +284,22 @@ void MaterialEntityItem::setParentID(const QUuid& parentID) { } } +void MaterialEntityItem::locationChanged(bool tellPhysics) { + EntityItem::locationChanged(); + if (_materialMappingMode == MaterialMappingMode::PROJECTED) { + removeMaterial(); + applyMaterial(); + } +} + +void MaterialEntityItem::dimensionsChanged() { + EntityItem::dimensionsChanged(); + if (_materialMappingMode == MaterialMappingMode::PROJECTED) { + removeMaterial(); + applyMaterial(); + } +} + void MaterialEntityItem::removeMaterial() { graphics::MaterialPointer material = getMaterial(); if (!material) { @@ -289,11 +333,19 @@ void MaterialEntityItem::applyMaterial() { if (!material || parentID.isNull()) { return; } + Transform textureTransform; - textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f)); - textureTransform.setRotation(glm::vec3(0.0f, 0.0f, glm::radians(_materialMappingRot))); - textureTransform.setScale(glm::vec3(_materialMappingScale, 1.0f)); - material->setTextureTransforms(textureTransform); + if (_materialMappingMode == MaterialMappingMode::UV) { + textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f)); + textureTransform.setRotation(glm::vec3(0.0f, 0.0f, glm::radians(_materialMappingRot))); + textureTransform.setScale(glm::vec3(_materialMappingScale, 1.0f)); + } else if (_materialMappingMode == MaterialMappingMode::PROJECTED) { + textureTransform = getTransform(); + textureTransform.postScale(getUnscaledDimensions()); + // Pass the inverse transform here so we don't need to compute it in the shaders + textureTransform.evalFromRawMatrix(textureTransform.getInverseMatrix()); + } + material->setTextureTransforms(textureTransform, _materialMappingMode, _materialRepeat); graphics::MaterialLayer materialLayer = graphics::MaterialLayer(material, getPriority()); diff --git a/libraries/entities/src/MaterialEntityItem.h b/libraries/entities/src/MaterialEntityItem.h index 8aaa833db9..ba142d7719 100644 --- a/libraries/entities/src/MaterialEntityItem.h +++ b/libraries/entities/src/MaterialEntityItem.h @@ -58,7 +58,10 @@ public: void setCurrentMaterialName(const std::string& currentMaterialName); MaterialMappingMode getMaterialMappingMode() const { return _materialMappingMode; } - void setMaterialMappingMode(MaterialMappingMode mode) { _materialMappingMode = mode; } + void setMaterialMappingMode(MaterialMappingMode mode); + + bool getMaterialRepeat() const { return _materialRepeat; } + void setMaterialRepeat(bool repeat); quint16 getPriority() const { return _priority; } void setPriority(quint16 priority); @@ -80,6 +83,9 @@ public: void setParentID(const QUuid& parentID) override; + void locationChanged(bool tellPhysics) override; + void dimensionsChanged() override; + void applyMaterial(); void removeMaterial(); @@ -104,8 +110,10 @@ private: // emissiveMap, albedoMap (set opacityMap = albedoMap for transparency), metallicMap or specularMap, roughnessMap or glossMap, // normalMap or bumpMap, occlusionMap, lightmapMap (broken, FIXME), scatteringMap (only works if normal mapped) QString _materialURL; - // Type of material. "uv" or "projected". NOT YET IMPLEMENTED, only UV is used + // Type of material. "uv" or "projected". MaterialMappingMode _materialMappingMode { UV }; + bool _materialRepeat { true }; + glm::vec3 _desiredDimensions; // Priority for this material when applying it to its parent. Only the highest priority material will be used. Materials with the same priority are (essentially) randomly sorted. // Base materials that come with models always have priority 0. quint16 _priority { 0 }; diff --git a/libraries/graphics/src/graphics/Material.cpp b/libraries/graphics/src/graphics/Material.cpp index ab890cecca..5cf3ef9871 100755 --- a/libraries/graphics/src/graphics/Material.cpp +++ b/libraries/graphics/src/graphics/Material.cpp @@ -135,9 +135,11 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur if (channel == MaterialKey::LIGHTMAP_MAP) { // update the texcoord1 with lightmap _schemaBuffer.edit()._texcoordTransforms[1] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4()); - _schemaBuffer.edit()._lightmapParams = (textureMap ? glm::vec4(textureMap->getLightmapOffsetScale(), 0.0, 0.0) : glm::vec4(0.0, 1.0, 0.0, 0.0)); + _schemaBuffer.edit()._lightmapParams = (textureMap ? glm::vec2(textureMap->getLightmapOffsetScale()) : glm::vec2(0.0, 1.0)); } + _schemaBuffer.edit()._materialParms = (textureMap ? glm::vec2(textureMap->getMappingMode(), textureMap->getRepeat()) : glm::vec2(MaterialMappingMode::UV, 1.0)); + _schemaBuffer.edit()._key = (uint32)_key._flags.to_ulong(); } @@ -216,13 +218,16 @@ bool Material::calculateMaterialInfo() const { return _hasCalculatedTextureInfo; } -void Material::setTextureTransforms(const Transform& transform) { +void Material::setTextureTransforms(const Transform& transform, MaterialMappingMode mode, bool repeat) { for (auto &textureMapItem : _textureMaps) { if (textureMapItem.second) { textureMapItem.second->setTextureTransform(transform); + textureMapItem.second->setMappingMode(mode); + textureMapItem.second->setRepeat(repeat); } } for (int i = 0; i < NUM_TEXCOORD_TRANSFORMS; i++) { _schemaBuffer.edit()._texcoordTransforms[i] = transform.getMatrix(); } + _schemaBuffer.edit()._materialParms = glm::vec2(mode, repeat); } \ No newline at end of file diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index 0db78ab349..196c0d595c 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -22,6 +22,8 @@ #include #include +#include "MaterialMappingMode.h" + class Transform; namespace graphics { @@ -332,7 +334,11 @@ public: // Texture Coord Transform Array glm::mat4 _texcoordTransforms[NUM_TEXCOORD_TRANSFORMS]; - glm::vec4 _lightmapParams{ 0.0, 1.0, 0.0, 0.0 }; + glm::vec2 _lightmapParams { 0.0, 1.0 }; + + // x: material mode (0 for UV, 1 for PROJECTED) + // x: 1 for texture repeat, 0 for discard outside of 0 - 1 + glm::vec2 _materialParms { 0.0, 1.0 }; Schema() {} }; @@ -355,7 +361,7 @@ public: size_t getTextureSize() const { calculateMaterialInfo(); return _textureSize; } bool hasTextureInfo() const { return _hasCalculatedTextureInfo; } - void setTextureTransforms(const Transform& transform); + void setTextureTransforms(const Transform& transform, MaterialMappingMode mode, bool repeat); const std::string& getName() const { return _name; } diff --git a/libraries/graphics/src/graphics/Material.slh b/libraries/graphics/src/graphics/Material.slh index d2055b9a59..48b8415df5 100644 --- a/libraries/graphics/src/graphics/Material.slh +++ b/libraries/graphics/src/graphics/Material.slh @@ -19,20 +19,25 @@ const int MAX_TEXCOORDS = 2; struct TexMapArray { mat4 _texcoordTransforms0; mat4 _texcoordTransforms1; - vec4 _lightmapParams; + vec2 _lightmapParams; + vec2 _materialParams; }; <@func declareMaterialTexMapArrayBuffer()@> -<@func evalTexMapArrayTexcoord0(texMapArray, inTexcoord0, outTexcoord0)@> +<@func evalTexMapArrayTexcoord0(texMapArray, inTexcoord0, worldPosition, outTexcoord0)@> { - <$outTexcoord0$> = (<$texMapArray$>._texcoordTransforms0 * vec4(<$inTexcoord0$>.st, 0.0, 1.0)).st; + <$outTexcoord0$> = mix(<$texMapArray$>._texcoordTransforms0 * vec4(<$inTexcoord0$>.st, 0.0, 1.0), + <$texMapArray$>._texcoordTransforms0 * <$worldPosition$> + vec4(0.5), + <$texMapArray$>._materialParams.x).st; } <@endfunc@> -<@func evalTexMapArrayTexcoord1(texMapArray, inTexcoord1, outTexcoord1)@> +<@func evalTexMapArrayTexcoord1(texMapArray, inTexcoord1, worldPosition, outTexcoord1)@> { - <$outTexcoord1$> = (<$texMapArray$>._texcoordTransforms1 * vec4(<$inTexcoord1$>.st, 0.0, 1.0)).st; + <$outTexcoord1$> = mix(<$texMapArray$>._texcoordTransforms1 * vec4(<$inTexcoord1$>.st, 0.0, 1.0), + <$texMapArray$>._texcoordTransforms1 * <$worldPosition$> + vec4(0.5), + <$texMapArray$>._materialParams.x).st; } <@endfunc@> diff --git a/libraries/graphics/src/graphics/MaterialTextures.slh b/libraries/graphics/src/graphics/MaterialTextures.slh index db329c3852..82d89faf41 100644 --- a/libraries/graphics/src/graphics/MaterialTextures.slh +++ b/libraries/graphics/src/graphics/MaterialTextures.slh @@ -151,6 +151,9 @@ float fetchScatteringMap(vec2 uv) { <@func fetchMaterialTexturesCoord0(matKey, texcoord0, albedo, roughness, normal, metallic, emissive, scattering)@> + if (getTexMapArray()._materialParams.y != 1.0 && clamp(<$texcoord0$>, vec2(0.0), vec2(1.0)) != <$texcoord0$>) { + discard; + } <@if albedo@> vec4 <$albedo$> = (((<$matKey$> & (ALBEDO_MAP_BIT | OPACITY_MASK_MAP_BIT | OPACITY_TRANSLUCENT_MAP_BIT)) != 0) ? fetchAlbedoMap(<$texcoord0$>) : vec4(1.0)); <@endif@> @@ -188,7 +191,7 @@ float fetchScatteringMap(vec2 uv) { LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap; vec3 fetchLightmapMap(vec2 uv) { - vec2 lightmapParams = getTexMapArray()._lightmapParams.xy; + vec2 lightmapParams = getTexMapArray()._lightmapParams; return (vec3(lightmapParams.x) + lightmapParams.y * texture(emissiveMap, uv).rgb); } <@endfunc@> diff --git a/libraries/graphics/src/graphics/TextureMap.h b/libraries/graphics/src/graphics/TextureMap.h index 1678d9df98..eea9d2b31b 100755 --- a/libraries/graphics/src/graphics/TextureMap.h +++ b/libraries/graphics/src/graphics/TextureMap.h @@ -14,6 +14,7 @@ #include "gpu/Texture.h" #include "Transform.h" +#include "MaterialMappingMode.h" namespace graphics { @@ -30,6 +31,12 @@ public: void setTextureTransform(const Transform& texcoordTransform); const Transform& getTextureTransform() const { return _texcoordTransform; } + void setMappingMode(MaterialMappingMode mode) { _mappingMode = mode; } + MaterialMappingMode getMappingMode() const { return _mappingMode; } + + void setRepeat(bool repeat) { _repeat = repeat; } + bool getRepeat() const { return _repeat; } + void setUseAlphaChannel(bool useAlpha) { _useAlphaChannel = useAlpha; } bool useAlphaChannel() const { return _useAlphaChannel; } @@ -41,6 +48,8 @@ protected: Transform _texcoordTransform; glm::vec2 _lightmapOffsetScale{ 0.0f, 1.0f }; + MaterialMappingMode _mappingMode { MaterialMappingMode::UV }; + bool _repeat { true }; bool _useAlphaChannel{ false }; }; diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 9eed463d2d..fe61a6ad3f 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -33,7 +33,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityEdit: case PacketType::EntityData: case PacketType::EntityPhysics: - return static_cast(EntityVersion::FixedLightSerialization); + return static_cast(EntityVersion::MaterialRepeat); case PacketType::EntityQuery: return static_cast(EntityQueryPacketVersion::ConicalFrustums); case PacketType::AvatarIdentity: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 37a4b32940..d81d6e4931 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -245,7 +245,8 @@ enum class EntityVersion : PacketVersion { BloomEffect, GrabProperties, ScriptGlmVectors, - FixedLightSerialization + FixedLightSerialization, + MaterialRepeat }; enum class EntityScriptCallMethodVersion : PacketVersion { diff --git a/libraries/render-utils/src/deformed_model.slv b/libraries/render-utils/src/deformed_model.slv index 039ad0a7d9..8c6d3d049d 100644 --- a/libraries/render-utils/src/deformed_model.slv +++ b/libraries/render-utils/src/deformed_model.slv @@ -44,13 +44,13 @@ void main(void) { _color.rgb = color_sRGBToLinear(inColor.rgb); _color.a = inColor.a; - TexMapArray texMapArray = getTexMapArray(); - <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$> - <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$> - // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); <$transformModelToWorldAndEyeAndClipPos(cam, obj, deformedPosition, _positionWS, _positionES, gl_Position)$> <$transformModelToWorldDir(cam, obj, deformedNormal, _normalWS.xyz)$> + + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _positionWS, _texCoord01.xy)$> + <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _positionWS, _texCoord01.zw)$> } diff --git a/libraries/render-utils/src/deformed_model_dq.slv b/libraries/render-utils/src/deformed_model_dq.slv index c6540c90b1..8f5f064022 100644 --- a/libraries/render-utils/src/deformed_model_dq.slv +++ b/libraries/render-utils/src/deformed_model_dq.slv @@ -42,13 +42,13 @@ void main(void) { _color.rgb = color_sRGBToLinear(inColor.rgb); _color.a = inColor.a; - TexMapArray texMapArray = getTexMapArray(); - <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$> - <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$> - // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); <$transformModelToWorldAndEyeAndClipPos(cam, obj, deformedPosition, _positionWS, _positionES, gl_Position)$> <$transformModelToWorldDir(cam, obj, deformedNormal, _normalWS.xyz)$> + + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _positionWS, _texCoord01.xy)$> + <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _positionWS, _texCoord01.zw)$> } diff --git a/libraries/render-utils/src/deformed_model_normal_map.slv b/libraries/render-utils/src/deformed_model_normal_map.slv index 8627b5b856..85e164b639 100644 --- a/libraries/render-utils/src/deformed_model_normal_map.slv +++ b/libraries/render-utils/src/deformed_model_normal_map.slv @@ -43,14 +43,14 @@ void main(void) { _color.rgb = color_sRGBToLinear(inColor.rgb); _color.a = inColor.a; - TexMapArray texMapArray = getTexMapArray(); - <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$> - <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$> - // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); <$transformModelToWorldAndEyeAndClipPos(cam, obj, deformedPosition, _positionWS, _positionES, gl_Position)$> <$transformModelToWorldDir(cam, obj, deformedNormal, _normalWS.xyz)$> <$transformModelToWorldDir(cam, obj, deformedTangent, _tangentWS.xyz)$> + + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _positionWS, _texCoord01.xy)$> + <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _positionWS, _texCoord01.zw)$> } diff --git a/libraries/render-utils/src/deformed_model_normal_map_dq.slv b/libraries/render-utils/src/deformed_model_normal_map_dq.slv index b45d94938a..807d343643 100644 --- a/libraries/render-utils/src/deformed_model_normal_map_dq.slv +++ b/libraries/render-utils/src/deformed_model_normal_map_dq.slv @@ -44,14 +44,14 @@ void main(void) { _color.rgb = color_sRGBToLinear(inColor.rgb); _color.a = inColor.a; - TexMapArray texMapArray = getTexMapArray(); - <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$> - <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$> - // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); <$transformModelToWorldAndEyeAndClipPos(cam, obj, deformedPosition, _positionWS, _positionES, gl_Position)$> <$transformModelToWorldDir(cam, obj, deformedNormal, _normalWS.xyz)$> <$transformModelToWorldDir(cam, obj, deformedTangent, _tangentWS.xyz)$> + + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _positionWS, _texCoord01.xy)$> + <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _positionWS, _texCoord01.zw)$> } diff --git a/libraries/render-utils/src/model.slv b/libraries/render-utils/src/model.slv index f3d315c7a4..88cbd1e18c 100644 --- a/libraries/render-utils/src/model.slv +++ b/libraries/render-utils/src/model.slv @@ -31,13 +31,13 @@ void main(void) { _color.rgb = color_sRGBToLinear(inColor.rgb); _color.a = inColor.a; - TexMapArray texMapArray = getTexMapArray(); - <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$> - <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$> - // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); <$transformModelToWorldAndEyeAndClipPos(cam, obj, inPosition, _positionWS, _positionES, gl_Position)$> <$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$> + + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _positionWS, _texCoord01.xy)$> + <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _positionWS, _texCoord01.zw)$> } diff --git a/libraries/render-utils/src/model_normal_map.slv b/libraries/render-utils/src/model_normal_map.slv index 94d8a43b6e..0fd9a8b582 100644 --- a/libraries/render-utils/src/model_normal_map.slv +++ b/libraries/render-utils/src/model_normal_map.slv @@ -32,14 +32,14 @@ void main(void) { _color.rgb = color_sRGBToLinear(inColor.rgb); _color.a = inColor.a; - TexMapArray texMapArray = getTexMapArray(); - <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$> - <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$> - // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); <$transformModelToWorldAndEyeAndClipPos(cam, obj, inPosition, _positionWS, _positionES, gl_Position)$> <$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$> <$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangentWS)$> + + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _positionWS, _texCoord01.xy)$> + <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _positionWS, _texCoord01.zw)$> } diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index c7c75a243b..1d9ec74ef6 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -565,6 +565,14 @@ const GROUPS = [ min: 0, propertyID: "priority", }, + { + label: "Material Mapping Mode", + type: "dropdown", + options: { + uv: "UV space", projected: "3D projected" + }, + propertyID: "materialMappingMode", + }, { label: "Material Position", type: "vec2", @@ -594,6 +602,11 @@ const GROUPS = [ unit: "deg", propertyID: "materialMappingRot", }, + { + label: "Material Repeat", + type: "bool", + propertyID: "materialRepeat", + }, ] }, {