Merge pull request #14372 from SamGondelman/decals

Case 19798: 3D projected Material Entities and materialRepeat option
This commit is contained in:
Adam Smith 2018-12-06 11:13:46 -08:00 committed by GitHub
commit 08d6e35d4d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 165 additions and 46 deletions

View file

@ -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);

View file

@ -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 <code>0</code>.
* @property {string} materialMappingMode="uv" - How the material is mapped to the entity. Either <code>"uv"</code> or
* <code>"projected"</code>. <em>Currently, only <code>"uv"</code> is supported.
* <code>"projected"</code>. 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
* <code>{ x: 0, y: 0 }</code> &ndash; <code>{ x: 1, y: 1 }</code>.
* @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
* <code>JSON.parse()</code> to parse the string into a JavaScript object which you can manipulate the properties of, and
* use <code>JSON.stringify()</code> 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 <caption>Color a sphere using a Material entity.</caption>
* 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<QString> EntityItemProperties::listChangedProperties() {
if (materialDataChanged()) {
out += "materialData";
}
if (materialRepeatChanged()) {
out += "materialRepeat";
}
if (isVisibleInSecondaryCameraChanged()) {
out += "isVisibleInSecondaryCamera";
}

View file

@ -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);

View file

@ -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;

View file

@ -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,

View file

@ -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<NetworkMaterial> 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());

View file

@ -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 };

View file

@ -130,9 +130,11 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur
if (channel == MaterialKey::LIGHTMAP_MAP) {
// update the texcoord1 with lightmap
_schemaBuffer.edit<Schema>()._texcoordTransforms[1] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
_schemaBuffer.edit<Schema>()._lightmapParams = (textureMap ? glm::vec4(textureMap->getLightmapOffsetScale(), 0.0, 0.0) : glm::vec4(0.0, 1.0, 0.0, 0.0));
_schemaBuffer.edit<Schema>()._lightmapParams = (textureMap ? glm::vec2(textureMap->getLightmapOffsetScale()) : glm::vec2(0.0, 1.0));
}
_schemaBuffer.edit<Schema>()._materialParams = (textureMap ? glm::vec2(textureMap->getMappingMode(), textureMap->getRepeat()) : glm::vec2(MaterialMappingMode::UV, 1.0));
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
}
@ -211,13 +213,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<Schema>()._texcoordTransforms[i] = transform.getMatrix();
}
}
_schemaBuffer.edit<Schema>()._materialParams = glm::vec2(mode, repeat);
}

View file

@ -22,6 +22,8 @@
#include <gpu/Resource.h>
#include <gpu/TextureTable.h>
#include "MaterialMappingMode.h"
class Transform;
namespace graphics {
@ -330,7 +332,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)
// y: 1 for texture repeat, 0 for discard outside of 0 - 1
glm::vec2 _materialParams { 0.0, 1.0 };
Schema() {}
};
@ -353,7 +359,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; }

View file

@ -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@>

View file

@ -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$> = mix(vec4(1.0), fetchAlbedoMap(<$texcoord0$>), float((<$matKey$> & (ALBEDO_MAP_BIT | OPACITY_MASK_MAP_BIT | OPACITY_TRANSLUCENT_MAP_BIT)) != 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@>

View file

@ -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 };
};

View file

@ -33,7 +33,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
case PacketType::EntityEdit:
case PacketType::EntityData:
case PacketType::EntityPhysics:
return static_cast<PacketVersion>(EntityVersion::FixedLightSerialization);
return static_cast<PacketVersion>(EntityVersion::MaterialRepeat);
case PacketType::EntityQuery:
return static_cast<PacketVersion>(EntityQueryPacketVersion::ConicalFrustums);
case PacketType::AvatarIdentity:

View file

@ -244,7 +244,8 @@ enum class EntityVersion : PacketVersion {
BloomEffect,
GrabProperties,
ScriptGlmVectors,
FixedLightSerialization
FixedLightSerialization,
MaterialRepeat
};
enum class EntityScriptCallMethodVersion : PacketVersion {

View file

@ -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)$>
}

View file

@ -41,13 +41,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)$>
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View file

@ -579,6 +579,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",
@ -608,6 +616,11 @@ const GROUPS = [
unit: "deg",
propertyID: "materialMappingRot",
},
{
label: "Material Repeat",
type: "bool",
propertyID: "materialRepeat",
},
]
},
{