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",
+ },
]
},
{