From 336181a14794fef8cad57736aae7767d29e1c77f Mon Sep 17 00:00:00 2001
From: HifiExperiments
Date: Mon, 16 Sep 2024 22:37:54 -0700
Subject: [PATCH] support PBR materials on polyvox, and add triplanar
projection to material entities
---
.../src/RenderableEntityItem.cpp | 17 +-
.../src/RenderableMaterialEntityItem.cpp | 8 +-
.../src/RenderablePolyVoxEntityItem.cpp | 107 +++++++-
.../src/RenderablePolyVoxEntityItem.h | 6 +-
.../entities/src/EntityItemProperties.cpp.in | 1 +
.../entities/src/EntityItemPropertiesDocs.cpp | 10 +-
.../entities/src/MaterialEntityItem.cpp.in | 2 +-
libraries/graphics/src/graphics/Material.slh | 4 +-
.../src/graphics/MaterialTextures.slh | 244 ++++++++++++++++++
.../graphics/src/graphics/ShaderConstants.h | 4 +-
.../render-utils/src/MeshPartPayload.cpp | 4 +
.../render-utils/src/RenderPipelines.cpp | 191 +++++++++++++-
libraries/render-utils/src/model.slf | 77 ++++--
libraries/render-utils/src/model.slv | 7 +
.../render-utils/src/render-utils/model.slp | 2 +-
libraries/render/src/render/ShapePipeline.h | 8 +
libraries/shared/src/MaterialMappingMode.cpp | 3 +-
libraries/shared/src/MaterialMappingMode.h | 1 +
scripts/system/create/edit.js | 4 +
.../html/js/entityProperties.js | 2 +-
20 files changed, 654 insertions(+), 48 deletions(-)
diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp
index 7ca3a5c341..a30884c870 100644
--- a/libraries/entities-renderer/src/RenderableEntityItem.cpp
+++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp
@@ -626,7 +626,7 @@ void EntityRenderer::removeMaterial(graphics::MaterialPointer material, const st
graphics::MaterialPointer EntityRenderer::getTopMaterial() {
std::lock_guard lock(_materialsLock);
auto materials = _materials.find("0");
- if (materials != _materials.end()) {
+ if (materials != _materials.end() && materials->second.size() > 0) {
return materials->second.top().material;
}
return nullptr;
@@ -637,7 +637,7 @@ EntityRenderer::Pipeline EntityRenderer::getPipelineType(const graphics::MultiMa
return Pipeline::MIRROR;
}
- if (materials.top().material && materials.top().material->isProcedural() && materials.top().material->isReady()) {
+ if (materials.size() > 0 && materials.top().material && materials.top().material->isProcedural() && materials.top().material->isReady()) {
return Pipeline::PROCEDURAL;
}
@@ -670,7 +670,7 @@ bool EntityRenderer::needsRenderUpdateFromMaterials() const {
return true;
}
- if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) {
+ if (materials->second.size() > 0 && materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast(materials->second.top().material);
if (procedural->isFading()) {
return true;
@@ -696,7 +696,7 @@ void EntityRenderer::updateMaterials(bool baseMaterialChanged) {
}
bool requestUpdate = false;
- if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) {
+ if (materials->second.size() > 0 && materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast(materials->second.top().material);
if (procedural->isFading()) {
procedural->setIsFading(Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) < 1.0f);
@@ -725,7 +725,7 @@ bool EntityRenderer::materialsTransparent() const {
}
}
- if (materials->second.top().material) {
+ if (materials->second.size() > 0 && materials->second.top().material) {
if (materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast(materials->second.top().material);
if (procedural->isFading()) {
@@ -752,7 +752,7 @@ Item::Bound EntityRenderer::getMaterialBound(RenderArgs* args) {
}
}
- if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) {
+ if (materials->second.size() > 0 && materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast(materials->second.top().material);
if (procedural->hasVertexShader() && procedural->hasBoundOperator()) {
return procedural->getBound(args);
@@ -825,6 +825,11 @@ void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& build
} else {
builder.withMToon();
}
+
+ if (materials->second.size() > 0 && materials->second.top().material &&
+ (MaterialMappingMode)materials->second.top().material->getMaterialParams().x == MaterialMappingMode::TRIPLANAR) {
+ builder.withTriplanar();
+ }
} else if (pipelineType == Pipeline::PROCEDURAL) {
builder.withOwnPipeline();
}
diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp
index 21e6cfece9..1d2b771d4e 100644
--- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp
+++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp
@@ -57,7 +57,7 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
_materialMappingPos = mappingPos;
_materialMappingScale = mappingScale;
_materialMappingRot = mappingRot;
- transformChanged |= _materialMappingMode == MaterialMappingMode::UV;
+ transformChanged |= (_materialMappingMode == MaterialMappingMode::UV || _materialMappingMode == MaterialMappingMode::TRIPLANAR);
}
}
{
@@ -264,6 +264,10 @@ ShapeKey MaterialEntityRenderer::getShapeKey() {
builder.withTangents();
}
+ if (drawMaterial && (MaterialMappingMode)drawMaterial->getMaterialParams().x == MaterialMappingMode::TRIPLANAR) {
+ builder.withTriplanar();
+ }
+
if (drawMaterial && drawMaterial->isMToon()) {
builder.withMToon();
} else {
@@ -409,7 +413,7 @@ void MaterialEntityRenderer::deleteMaterial(const QUuid& oldParentID, const QStr
void MaterialEntityRenderer::applyTextureTransform(std::shared_ptr& material) {
Transform textureTransform;
- if (_materialMappingMode == MaterialMappingMode::UV) {
+ if (_materialMappingMode == MaterialMappingMode::UV || _materialMappingMode == MaterialMappingMode::TRIPLANAR) {
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));
diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp
index ef0d8d4449..d1cd4dc473 100644
--- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp
+++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp
@@ -29,12 +29,14 @@
#include
#include
#include
+#include
#include "entities-renderer/ShaderConstants.h"
#include
#include "EntityTreeRenderer.h"
+#include "RenderPipelines.h"
#include
@@ -1707,9 +1709,11 @@ using namespace render;
using namespace render::entities;
static uint8_t CUSTOM_PIPELINE_NUMBER;
+static const gpu::Element COLOR_ELEMENT { gpu::VEC4, gpu::NUINT8, gpu::RGBA };
// forward, shadow, fade, wireframe
static std::map, ShapePipelinePointer> _pipelines;
static gpu::Stream::FormatPointer _vertexFormat;
+static gpu::Stream::FormatPointer _vertexColorFormat;
ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, RenderArgs* args) {
if (_pipelines.empty()) {
@@ -1765,18 +1769,48 @@ PolyVoxEntityRenderer::PolyVoxEntityRenderer(const EntityItemPointer& entity) :
_vertexFormat = std::make_shared();
_vertexFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
_vertexFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 12);
+
+ _vertexColorFormat = std::make_shared();
+ _vertexColorFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
+ _vertexColorFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 12);
+ _vertexColorFormat->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
});
_params = std::make_shared(sizeof(glm::vec4), nullptr);
}
ShapeKey PolyVoxEntityRenderer::getShapeKey() {
- auto builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER);
- if (_primitiveMode == PrimitiveMode::LINES) {
- builder.withWireframe();
+ bool hasMaterials = false;
+ graphics::MultiMaterial materials;
+ {
+ std::lock_guard lock(_materialsLock);
+ auto materialsItr = _materials.find("0");
+ hasMaterials = (materialsItr != _materials.end());
+ if (hasMaterials) {
+ materials = materialsItr->second;
+ }
+ }
+ ShapeKey::Builder builder;
+ if (!hasMaterials) {
+ builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER);
+ if (_primitiveMode == PrimitiveMode::LINES) {
+ builder.withWireframe();
+ }
+ } else {
+ updateShapeKeyBuilderFromMaterials(builder);
+ Pipeline pipelineType = getPipelineType(materials);
+ if (pipelineType == Pipeline::MATERIAL) {
+ builder.withTriplanar();
+ }
+ // FIXME: We don't currently generate tangents for PolyVox, so they don't support normal maps
+ builder.withoutTangents();
}
return builder.build();
}
+bool PolyVoxEntityRenderer::needsRenderUpdate() const {
+ return needsRenderUpdateFromMaterials() || Parent::needsRenderUpdate();
+}
+
bool PolyVoxEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
if (resultWithReadLock([&] {
if (entity->voxelToLocalMatrix() != _lastVoxelToLocalMatrix) {
@@ -1834,6 +1868,17 @@ void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoi
texture = DependencyManager::get()->getTexture(textureURL);
}
}
+
+ updateMaterials();
+}
+
+bool PolyVoxEntityRenderer::isTransparent() const {
+ // TODO: We don't currently support transparent PolyVox (unless they are using the material path)
+ return /*Parent::isTransparent() || */materialsTransparent();
+}
+
+Item::Bound PolyVoxEntityRenderer::getBound(RenderArgs* args) {
+ return Parent::getMaterialBound(args);
}
void PolyVoxEntityRenderer::doRender(RenderArgs* args) {
@@ -1853,20 +1898,60 @@ void PolyVoxEntityRenderer::doRender(RenderArgs* args) {
_prevRenderTransform = transform;
}
- batch.setInputFormat(_vertexFormat);
batch.setInputBuffer(gpu::Stream::POSITION, _mesh->getVertexBuffer()._buffer, 0, sizeof(PolyVox::PositionMaterialNormal));
batch.setIndexBuffer(gpu::UINT32, _mesh->getIndexBuffer()._buffer, 0);
- for (size_t i = 0; i < _xyzTextures.size(); ++i) {
- const auto& texture = _xyzTextures[i];
- if (texture) {
- batch.setResourceTexture((uint32_t)i, texture->getGPUTexture());
- } else {
- batch.setResourceTexture((uint32_t)i, DependencyManager::get()->getWhiteTexture());
+ bool hasMaterials = false;
+ graphics::MultiMaterial materials;
+ {
+ std::lock_guard lock(_materialsLock);
+ auto materialsItr = _materials.find("0");
+ hasMaterials = (materialsItr != _materials.end());
+ if (hasMaterials) {
+ materials = materialsItr->second;
}
}
+ if (!hasMaterials) {
+ for (size_t i = 0; i < _xyzTextures.size(); ++i) {
+ const auto& texture = _xyzTextures[i];
+ if (texture) {
+ batch.setResourceTexture((uint32_t)i, texture->getGPUTexture());
+ } else {
+ batch.setResourceTexture((uint32_t)i, DependencyManager::get()->getWhiteTexture());
+ }
+ }
+ batch.setInputFormat(_vertexFormat);
+ batch.setUniformBuffer(0, _params);
+ } else {
+ glm::vec4 outColor = materials.getColor();
+
+ if (outColor.a == 0.0f) {
+ return;
+ }
+
+ Pipeline pipelineType = getPipelineType(materials);
+ if (pipelineType == Pipeline::PROCEDURAL) {
+ auto procedural = std::static_pointer_cast(materials.top().material);
+ outColor = procedural->getColor(outColor);
+ outColor.a *= procedural->isFading() ? Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) : 1.0f;
+ withReadLock([&] {
+ procedural->prepare(batch, transform.getTranslation(), transform.getScale(), transform.getRotation(), _created,
+ ProceduralProgramKey(outColor.a < 1.0f));
+ });
+ } else if (pipelineType == Pipeline::MATERIAL) {
+ if (RenderPipelines::bindMaterials(materials, batch, args->_renderMode, args->_enableTexturing)) {
+ args->_details._materialSwitches++;
+ }
+ }
+
+ const uint32_t compactColor = GeometryCache::toCompactColor(glm::vec4(outColor));
+ _colorBuffer->setData(sizeof(compactColor), (const gpu::Byte*)&compactColor);
+ gpu::BufferView colorView(_colorBuffer, COLOR_ELEMENT);
+ batch.setInputBuffer(gpu::Stream::COLOR, colorView);
+ batch.setInputFormat(_vertexColorFormat);
+ batch.setUniformBuffer(graphics::slot::buffer::TriplanarScale, _params);
+ }
- batch.setUniformBuffer(0, _params);
batch.drawIndexed(gpu::TRIANGLES, (gpu::uint32)_mesh->getNumIndices(), 0);
}
diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h
index 2c6f29f4b9..72958f73cb 100644
--- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h
+++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h
@@ -204,11 +204,13 @@ public:
protected:
virtual ShapeKey getShapeKey() override;
+ virtual bool isTransparent() const override;
+ virtual Item::Bound getBound(RenderArgs* args) override;
+ virtual bool needsRenderUpdate() const override;
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
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 bool isTransparent() const override { return false; }
private:
#ifdef POLYVOX_ENTITY_USE_FADE_EFFECT
@@ -224,6 +226,8 @@ private:
glm::quat _orientation;
PolyVoxEntityItem::PolyVoxSurfaceStyle _lastSurfaceStyle { PolyVoxEntityItem::SURFACE_MARCHING_CUBES };
std::array _xyzTextureUrls;
+
+ gpu::BufferPointer _colorBuffer { std::make_shared() };
};
} }
diff --git a/libraries/entities/src/EntityItemProperties.cpp.in b/libraries/entities/src/EntityItemProperties.cpp.in
index 3bc67c71f3..fabdb03429 100644
--- a/libraries/entities/src/EntityItemProperties.cpp.in
+++ b/libraries/entities/src/EntityItemProperties.cpp.in
@@ -157,6 +157,7 @@ const QHash stringToMaterialMappingModeLookup = []
QHash toReturn;
addMaterialMappingMode(toReturn, UV);
addMaterialMappingMode(toReturn, PROJECTED);
+ addMaterialMappingMode(toReturn, TRIPLANAR);
return toReturn;
}();
QString EntityItemProperties::getMaterialMappingModeAsString() const { return MaterialMappingModeHelpers::getNameForMaterialMappingMode(_materialMappingMode); }
diff --git a/libraries/entities/src/EntityItemPropertiesDocs.cpp b/libraries/entities/src/EntityItemPropertiesDocs.cpp
index 8195161b77..5f6de26d5d 100644
--- a/libraries/entities/src/EntityItemPropertiesDocs.cpp
+++ b/libraries/entities/src/EntityItemPropertiesDocs.cpp
@@ -308,10 +308,12 @@
* For example, "[0,1,mat::string,mat::string2]"
will replace mesh parts 0 and 1, and any mesh parts with
* material "string"
or "string2"
. Do not put spaces around the commas. Invalid values are parsed
* to 0
.
- * @property {string} materialMappingMode="uv" - How the material is mapped to the entity. Either "uv"
or
- * "projected"
. In "uv"
mode, the material is evaluated within the UV space of the mesh it is
- * applied to. In "projected"
mode, the 3D transform (position, rotation, and dimensions) of the Material
- * entity is used to evaluate the texture coordinates for the material.
+ * @property {string} materialMappingMode="uv" - How the material is mapped to the entity. Either "uv"
,
+ * "projected"
, or "triplanar"
. In "uv"
mode, the material is evaluated within the
+ * UV space of the mesh it is applied to. In "projected"
mode, the 3D transform (position, rotation, and
+ * dimensions) of the Material entity is used to evaluate the texture coordinates for the material. "triplanar"
+ * mode is like "uv"
mode but the UV coordinates are evaluated based on a triplanar mapping instead of the
+ * coordinates from the model.
* @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.
diff --git a/libraries/entities/src/MaterialEntityItem.cpp.in b/libraries/entities/src/MaterialEntityItem.cpp.in
index 045c155084..ea5e25cef3 100644
--- a/libraries/entities/src/MaterialEntityItem.cpp.in
+++ b/libraries/entities/src/MaterialEntityItem.cpp.in
@@ -91,7 +91,7 @@ void MaterialEntityItem::setUnscaledDimensions(const glm::vec3& value) {
_desiredDimensions = value;
if (_hasVertexShader || _materialMappingMode == MaterialMappingMode::PROJECTED) {
EntityItem::setUnscaledDimensions(value);
- } else if (_materialMappingMode == MaterialMappingMode::UV) {
+ } else if (_materialMappingMode == MaterialMappingMode::UV || _materialMappingMode == MaterialMappingMode::TRIPLANAR) {
EntityItem::setUnscaledDimensions(ENTITY_ITEM_DEFAULT_DIMENSIONS);
}
}
diff --git a/libraries/graphics/src/graphics/Material.slh b/libraries/graphics/src/graphics/Material.slh
index 4d4dcde34c..952281c0e5 100644
--- a/libraries/graphics/src/graphics/Material.slh
+++ b/libraries/graphics/src/graphics/Material.slh
@@ -31,7 +31,7 @@ struct TexMapArray {
{
<$outTexcoord0$> = mix(<$texMapArray$>._texcoordTransforms0 * vec4(<$inTexcoord0$>.st, 0.0, 1.0),
<$texMapArray$>._texcoordTransforms0 * <$worldPosition$> + vec4(0.5),
- <$texMapArray$>._materialParams.x).st;
+ float(<$texMapArray$>._materialParams.x == 1.0)).st;
}
<@endfunc@>
@@ -39,7 +39,7 @@ struct TexMapArray {
{
<$outTexcoord1$> = mix(<$texMapArray$>._texcoordTransforms1 * vec4(<$inTexcoord1$>.st, 0.0, 1.0),
<$texMapArray$>._texcoordTransforms1 * <$worldPosition$> + vec4(0.5),
- <$texMapArray$>._materialParams.x).st;
+ float(<$texMapArray$>._materialParams.x == 1.0)).st;
}
<@endfunc@>
diff --git a/libraries/graphics/src/graphics/MaterialTextures.slh b/libraries/graphics/src/graphics/MaterialTextures.slh
index 425b8deed8..fe011d7e70 100644
--- a/libraries/graphics/src/graphics/MaterialTextures.slh
+++ b/libraries/graphics/src/graphics/MaterialTextures.slh
@@ -234,6 +234,128 @@ float fetchScatteringMap(vec2 uv) {
<@endif@>
<@endfunc@>
+<@func fetchMaterialTexturesCoord0Triplanar(matKey, positionMS, triplanarScale, albedo, roughness, normal, metallic, emissive, scattering)@>
+ vec3 inPosition = (<$positionMS$> - vec3(0.5)) / <$triplanarScale$>.xyz;
+ vec3 normalMS = normalize(cross(dFdy(<$positionMS$>.xyz), dFdx(<$positionMS$>.xyz)));
+
+ TexMapArray texMapArray = getTexMapArray();
+ vec2 uvXY = vec2(-inPosition.x, -inPosition.y);
+ <$evalTexMapArrayTexcoord0(texMapArray, uvXY, _positionWS, uvXY)$>
+ vec2 uvXZ = vec2(-inPosition.x, inPosition.z);
+ <$evalTexMapArrayTexcoord0(texMapArray, uvXZ, _positionWS, uvXZ)$>
+ vec2 uvYZ = vec2(inPosition.z, -inPosition.y);
+ <$evalTexMapArrayTexcoord0(texMapArray, uvYZ, _positionWS, uvYZ)$>
+
+<@if albedo@>
+ vec4 <$albedo$>Triplanar = vec4(0.0);
+<@endif@>
+<@if roughness@>
+ float <$roughness$>Triplanar = 0.0;
+<@endif@>
+<@if normal@>
+ vec3 <$normal$>Triplanar = vec3(0.0);
+<@endif@>
+<@if metallic@>
+ float <$metallic$>Triplanar = 0.0;
+<@endif@>
+<@if emissive@>
+ vec3 <$emissive$>Triplanar = vec3(0.0);
+<@endif@>
+<@if scattering@>
+ float <$scattering$>Triplanar = 0.0;
+<@endif@>
+
+ {
+ <$fetchMaterialTexturesCoord0($matKey$, uvXY, $albedo$, $roughness$, $normal$, $metallic$, $emissive$, $scattering$)$>
+ float magnitude = abs(normalMS.z);
+ <@if albedo@>
+ <$albedo$>Triplanar += magnitude * <$albedo$>;
+ <@endif@>
+ <@if roughness@>
+ <$roughness$>Triplanar += magnitude * <$roughness$>;
+ <@endif@>
+ <@if normal@>
+ <$normal$>Triplanar += magnitude * <$normal$>;
+ <@endif@>
+ <@if metallic@>
+ <$metallic$>Triplanar += magnitude * <$metallic$>;
+ <@endif@>
+ <@if emissive@>
+ <$emissive$>Triplanar += magnitude * <$emissive$>;
+ <@endif@>
+ <@if scattering@>
+ <$scattering$>Triplanar += magnitude * <$scattering$>;
+ <@endif@>
+ }
+
+ {
+ <$fetchMaterialTexturesCoord0($matKey$, uvXZ, $albedo$, $roughness$, $normal$, $metallic$, $emissive$, $scattering$)$>
+ float magnitude = abs(normalMS.y);
+ <@if albedo@>
+ <$albedo$>Triplanar += magnitude * <$albedo$>;
+ <@endif@>
+ <@if roughness@>
+ <$roughness$>Triplanar += magnitude * <$roughness$>;
+ <@endif@>
+ <@if normal@>
+ <$normal$>Triplanar += magnitude * <$normal$>;
+ <@endif@>
+ <@if metallic@>
+ <$metallic$>Triplanar += magnitude * <$metallic$>;
+ <@endif@>
+ <@if emissive@>
+ <$emissive$>Triplanar += magnitude * <$emissive$>;
+ <@endif@>
+ <@if scattering@>
+ <$scattering$>Triplanar += magnitude * <$scattering$>;
+ <@endif@>
+ }
+
+ {
+ <$fetchMaterialTexturesCoord0($matKey$, uvYZ, $albedo$, $roughness$, $normal$, $metallic$, $emissive$, $scattering$)$>
+ float magnitude = abs(normalMS.x);
+ <@if albedo@>
+ <$albedo$>Triplanar += magnitude * <$albedo$>;
+ <@endif@>
+ <@if roughness@>
+ <$roughness$>Triplanar += magnitude * <$roughness$>;
+ <@endif@>
+ <@if normal@>
+ <$normal$>Triplanar += magnitude * <$normal$>;
+ <@endif@>
+ <@if metallic@>
+ <$metallic$>Triplanar += magnitude * <$metallic$>;
+ <@endif@>
+ <@if emissive@>
+ <$emissive$>Triplanar += magnitude * <$emissive$>;
+ <@endif@>
+ <@if scattering@>
+ <$scattering$>Triplanar += magnitude * <$scattering$>;
+ <@endif@>
+ }
+
+<@if albedo@>
+ vec4 <$albedo$> = <$albedo$>Triplanar;
+<@endif@>
+<@if roughness@>
+ float <$roughness$> = <$roughness$>Triplanar;
+<@endif@>
+<@if normal@>
+ // FIXME: this isn't strictly correct, as our tangents no longer match the space of our UVs
+ vec3 <$normal$> = normalize(<$normal$>Triplanar);
+<@endif@>
+<@if metallic@>
+ float <$metallic$> = <$metallic$>Triplanar;
+<@endif@>
+<@if emissive@>
+ vec3 <$emissive$> = <$emissive$>Triplanar;
+<@endif@>
+<@if scattering@>
+ float <$scattering$> = <$scattering$>Triplanar;
+<@endif@>
+
+<@endfunc@>
+
<@func fetchMaterialTexturesCoord1(matKey, texcoord1, occlusion, lightmap)@>
<@if occlusion@>
float <$occlusion$> = mix(1.0, fetchOcclusionMap(<$texcoord1$>), float((<$matKey$> & OCCLUSION_MAP_BIT) != 0));
@@ -455,6 +577,128 @@ float fetchUVAnimationMaskMap(vec2 uv) {
<@endif@>
<@endfunc@>
+<@func fetchMToonMaterialTexturesCoord0Triplanar(matKey, positionMS, triplanarScale, albedo, normal, shade, emissive, shadingShift, rim, uvScrollSpeed, time)@>
+ vec3 inPosition = (<$positionMS$> - vec3(0.5)) / <$triplanarScale$>.xyz;
+ vec3 normalMS = normalize(cross(dFdy(<$positionMS$>.xyz), dFdx(<$positionMS$>.xyz)));
+
+ TexMapArray texMapArray = getTexMapArray();
+ vec2 uvXY = vec2(-inPosition.x, -inPosition.y);
+ <$evalTexMapArrayTexcoord0(texMapArray, uvXY, _positionWS, uvXY)$>
+ vec2 uvXZ = vec2(-inPosition.x, inPosition.z);
+ <$evalTexMapArrayTexcoord0(texMapArray, uvXZ, _positionWS, uvXZ)$>
+ vec2 uvYZ = vec2(inPosition.z, -inPosition.y);
+ <$evalTexMapArrayTexcoord0(texMapArray, uvYZ, _positionWS, uvYZ)$>
+
+<@if albedo@>
+ vec4 <$albedo$>Triplanar = vec4(0.0);
+<@endif@>
+<@if normal@>
+ vec3 <$normal$>Triplanar = vec3(0.0);
+<@endif@>
+<@if shade@>
+ vec3 <$shade$>Triplanar = vec3(0.0);
+<@endif@>
+<@if emissive@>
+ vec3 <$emissive$>Triplanar = vec3(0.0);
+<@endif@>
+<@if shadingShift@>
+ float <$shadingShift$>Triplanar = 0.0;
+<@endif@>
+<@if rim@>
+ vec3 <$rim$>Triplanar = vec3(0.0);
+<@endif@>
+
+ {
+ <$fetchMToonMaterialTexturesCoord0($matKey$, uvXY, $albedo$, $normal$, $shade$, $emissive$, $shadingShift$, $rim$, $uvScrollSpeed$, $time$)$>
+ float magnitude = abs(normalMS.z);
+ <@if albedo@>
+ <$albedo$>Triplanar += magnitude * <$albedo$>;
+ <@endif@>
+ <@if normal@>
+ <$normal$>Triplanar += magnitude * <$normal$>;
+ <@endif@>
+ <@if shade@>
+ <$shade$>Triplanar += magnitude * <$shade$>;
+ <@endif@>
+ <@if emissive@>
+ <$emissive$>Triplanar += magnitude * <$emissive$>;
+ <@endif@>
+ <@if shadingShift@>
+ <$shadingShift$>Triplanar += magnitude * <$shadingShift$>;
+ <@endif@>
+ <@if rim@>
+ <$rim$>Triplanar += magnitude * <$rim$>;
+ <@endif@>
+ }
+
+ {
+ <$fetchMToonMaterialTexturesCoord0($matKey$, uvXZ, $albedo$, $normal$, $shade$, $emissive$, $shadingShift$, $rim$, $uvScrollSpeed$, $time$)$>
+ float magnitude = abs(normalMS.y);
+ <@if albedo@>
+ <$albedo$>Triplanar += magnitude * <$albedo$>;
+ <@endif@>
+ <@if normal@>
+ <$normal$>Triplanar += magnitude * <$normal$>;
+ <@endif@>
+ <@if shade@>
+ <$shade$>Triplanar += magnitude * <$shade$>;
+ <@endif@>
+ <@if emissive@>
+ <$emissive$>Triplanar += magnitude * <$emissive$>;
+ <@endif@>
+ <@if shadingShift@>
+ <$shadingShift$>Triplanar += magnitude * <$shadingShift$>;
+ <@endif@>
+ <@if rim@>
+ <$rim$>Triplanar += magnitude * <$rim$>;
+ <@endif@>
+ }
+
+ {
+ <$fetchMToonMaterialTexturesCoord0($matKey$, uvYZ, $albedo$, $normal$, $shade$, $emissive$, $shadingShift$, $rim$, $uvScrollSpeed$, $time$)$>
+ float magnitude = abs(normalMS.x);
+ <@if albedo@>
+ <$albedo$>Triplanar += magnitude * <$albedo$>;
+ <@endif@>
+ <@if normal@>
+ <$normal$>Triplanar += magnitude * <$normal$>;
+ <@endif@>
+ <@if shade@>
+ <$shade$>Triplanar += magnitude * <$shade$>;
+ <@endif@>
+ <@if emissive@>
+ <$emissive$>Triplanar += magnitude * <$emissive$>;
+ <@endif@>
+ <@if shadingShift@>
+ <$shadingShift$>Triplanar += magnitude * <$shadingShift$>;
+ <@endif@>
+ <@if rim@>
+ <$rim$>Triplanar += magnitude * <$rim$>;
+ <@endif@>
+ }
+
+<@if albedo@>
+ vec4 <$albedo$> = <$albedo$>Triplanar;
+<@endif@>
+<@if normal@>
+ // FIXME: this isn't strictly correct, as our tangents no longer match the space of our UVs
+ vec3 <$normal$> = normalize(<$normal$>Triplanar);
+<@endif@>
+<@if shade@>
+ vec3 <$shade$> = <$shade$>Triplanar;
+<@endif@>
+<@if emissive@>
+ vec3 <$emissive$> = <$emissive$>Triplanar;
+<@endif@>
+<@if shadingShift@>
+ float <$shadingShift$> = <$shadingShift$>Triplanar;
+<@endif@>
+<@if rim@>
+ vec3 <$rim$> = <$rim$>Triplanar;
+<@endif@>
+
+<@endfunc@>
+
<@func evalMaterialShade(fetchedShade, materialShade, matKey, shade)@>
{
<$shade$> = mix(vec3(1.0), <$materialShade$>, float((<$matKey$> & SHADE_VAL_BIT) != 0));
diff --git a/libraries/graphics/src/graphics/ShaderConstants.h b/libraries/graphics/src/graphics/ShaderConstants.h
index 75eb4d00cc..ed76ee287a 100644
--- a/libraries/graphics/src/graphics/ShaderConstants.h
+++ b/libraries/graphics/src/graphics/ShaderConstants.h
@@ -20,6 +20,7 @@
#define GRAPHICS_BUFFER_KEY_LIGHT 4
#define GRAPHICS_BUFFER_LIGHT 5
#define GRAPHICS_BUFFER_AMBIENT_LIGHT 6
+#define GRAPHICS_BUFFER_TRIPLANAR_SCALE 7
#define GRAPHICS_TEXTURE_MATERIAL_ALBEDO 0
#define GRAPHICS_TEXTURE_MATERIAL_NORMAL 1
@@ -55,7 +56,8 @@ enum Buffer {
KeyLight = GRAPHICS_BUFFER_KEY_LIGHT,
AmbientLight = GRAPHICS_BUFFER_AMBIENT_LIGHT,
SkyboxParams = GRAPHICS_BUFFER_SKYBOX_PARAMS,
- HazeParams = GRAPHICS_BUFFER_HAZE_PARAMS
+ HazeParams = GRAPHICS_BUFFER_HAZE_PARAMS,
+ TriplanarScale = GRAPHICS_BUFFER_TRIPLANAR_SCALE
};
} // namespace buffer
diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp
index 1f8cb17841..76db3ca5d7 100644
--- a/libraries/render-utils/src/MeshPartPayload.cpp
+++ b/libraries/render-utils/src/MeshPartPayload.cpp
@@ -292,6 +292,10 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, PrimitiveMode pr
}
if (material) {
builder.withCullFaceMode(material->getCullFaceMode());
+
+ if ((MaterialMappingMode)material->getMaterialParams().x == MaterialMappingMode::TRIPLANAR) {
+ builder.withTriplanar();
+ }
}
}
diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp
index f491d127c9..b7249b0b9b 100644
--- a/libraries/render-utils/src/RenderPipelines.cpp
+++ b/libraries/render-utils/src/RenderPipelines.cpp
@@ -56,7 +56,7 @@ void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderArgs* a
void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderArgs* args);
static bool forceLightBatchSetter{ false };
-// TOOD: build this list algorithmically so we don't have to maintain it
+// TODO: build this list algorithmically so we don't have to maintain it
std::vector> ALL_PIPELINES = {
// Simple
{ Key::Builder(), simple, model_shadow },
@@ -89,6 +89,26 @@ std::vector> ALL_PIPELINES = {
{ Key::Builder().withMaterial().withTangents().withMToon(), model_normalmap_mtoon, model_shadow_mtoon },
{ Key::Builder().withMaterial().withTranslucent().withMToon(), model_translucent_mtoon, model_shadow_mtoon },
{ Key::Builder().withMaterial().withTangents().withTranslucent().withMToon(), model_normalmap_translucent_mtoon, model_shadow_mtoon },
+ // Unskinned Triplanar
+ { Key::Builder().withMaterial().withTriplanar(), model_triplanar, model_shadow_triplanar },
+ { Key::Builder().withMaterial().withTangents().withTriplanar(), model_normalmap_triplanar, model_shadow_triplanar },
+ { Key::Builder().withMaterial().withTranslucent().withTriplanar(), model_translucent_triplanar, model_shadow_triplanar },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar(), model_normalmap_translucent_triplanar, model_shadow_triplanar },
+ // Unskinned Unlit Triplanar
+ { Key::Builder().withMaterial().withUnlit().withTriplanar(), model_unlit_triplanar, model_shadow_triplanar },
+ { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar(), model_normalmap_unlit_triplanar, model_shadow_triplanar },
+ { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar(), model_translucent_unlit_triplanar, model_shadow_triplanar },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar(), model_normalmap_translucent_unlit_triplanar, model_shadow_triplanar },
+ // Unskinned Lightmapped Triplanar
+ { Key::Builder().withMaterial().withLightMap().withTriplanar(), model_lightmap_triplanar, model_shadow_triplanar },
+ { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar(), model_normalmap_lightmap_triplanar, model_shadow_triplanar },
+ { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar(), model_translucent_lightmap_triplanar, model_shadow_triplanar },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar(), model_normalmap_translucent_lightmap_triplanar, model_shadow_triplanar },
+ // Unskinned MToon Triplanar
+ { Key::Builder().withMaterial().withMToon().withTriplanar(), model_mtoon_triplanar, model_shadow_mtoon_triplanar },
+ { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar(), model_normalmap_mtoon_triplanar, model_shadow_mtoon_triplanar },
+ { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar(), model_translucent_mtoon_triplanar, model_shadow_mtoon_triplanar },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar(), model_normalmap_translucent_mtoon_triplanar, model_shadow_mtoon_triplanar },
// Unskinned Fade
{ Key::Builder().withMaterial().withFade(), model_fade, model_shadow_fade },
{ Key::Builder().withMaterial().withTangents().withFade(), model_normalmap_fade, model_shadow_fade },
@@ -109,6 +129,26 @@ std::vector> ALL_PIPELINES = {
{ Key::Builder().withMaterial().withTangents().withMToon().withFade(), model_normalmap_mtoon_fade, model_shadow_mtoon_fade },
{ Key::Builder().withMaterial().withTranslucent().withMToon().withFade(), model_translucent_mtoon_fade, model_shadow_mtoon_fade },
{ Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withFade(), model_normalmap_translucent_mtoon_fade, model_shadow_mtoon_fade },
+ // Unskinned Fade Triplanar
+ { Key::Builder().withMaterial().withTriplanar().withFade(), model_triplanar_fade, model_shadow_triplanar_fade },
+ { Key::Builder().withMaterial().withTangents().withTriplanar().withFade(), model_normalmap_triplanar_fade, model_shadow_triplanar_fade },
+ { Key::Builder().withMaterial().withTranslucent().withTriplanar().withFade(), model_translucent_triplanar_fade, model_shadow_triplanar_fade },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar().withFade(), model_normalmap_translucent_triplanar_fade, model_shadow_triplanar_fade },
+ // Unskinned Unlit Fade Triplanar
+ { Key::Builder().withMaterial().withUnlit().withTriplanar().withFade(), model_unlit_triplanar_fade, model_shadow_triplanar_fade },
+ { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar().withFade(), model_normalmap_unlit_triplanar_fade, model_shadow_triplanar_fade },
+ { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar().withFade(), model_translucent_unlit_triplanar_fade, model_shadow_triplanar_fade },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar().withFade(), model_normalmap_translucent_unlit_triplanar_fade, model_shadow_triplanar_fade },
+ // Unskinned Lightmapped Fade Triplanar
+ { Key::Builder().withMaterial().withLightMap().withTriplanar().withFade(), model_lightmap_triplanar_fade, model_shadow_triplanar_fade },
+ { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar().withFade(), model_normalmap_lightmap_triplanar_fade, model_shadow_triplanar_fade },
+ { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar().withFade(), model_translucent_lightmap_triplanar_fade, model_shadow_triplanar_fade },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar().withFade(), model_normalmap_translucent_lightmap_triplanar_fade, model_shadow_triplanar_fade },
+ // Unskinned MToon Fade Triplanar
+ { Key::Builder().withMaterial().withMToon().withTriplanar().withFade(), model_mtoon_triplanar_fade, model_shadow_mtoon_triplanar_fade },
+ { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar().withFade(), model_normalmap_mtoon_triplanar_fade, model_shadow_mtoon_triplanar_fade },
+ { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar().withFade(), model_translucent_mtoon_triplanar_fade, model_shadow_mtoon_triplanar_fade },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar().withFade(), model_normalmap_translucent_mtoon_triplanar_fade, model_shadow_mtoon_triplanar_fade },
// Matrix palette skinned
{ Key::Builder().withMaterial().withDeformed(), model_deformed, model_shadow_deformed },
@@ -130,6 +170,26 @@ std::vector> ALL_PIPELINES = {
{ Key::Builder().withMaterial().withTangents().withMToon().withDeformed(), model_normalmap_mtoon_deformed, model_shadow_mtoon_deformed },
{ Key::Builder().withMaterial().withTranslucent().withMToon().withDeformed(), model_translucent_mtoon_deformed, model_shadow_mtoon_deformed },
{ Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withDeformed(), model_normalmap_translucent_mtoon_deformed, model_shadow_mtoon_deformed },
+ // Matrix palette skinned Triplanar
+ { Key::Builder().withMaterial().withTriplanar().withDeformed(), model_triplanar_deformed, model_shadow_triplanar_deformed },
+ { Key::Builder().withMaterial().withTangents().withTriplanar().withDeformed(), model_normalmap_triplanar_deformed, model_shadow_triplanar_deformed },
+ { Key::Builder().withMaterial().withTranslucent().withTriplanar().withDeformed(), model_translucent_triplanar_deformed, model_shadow_triplanar_deformed },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar().withDeformed(), model_normalmap_translucent_triplanar_deformed, model_shadow_triplanar_deformed },
+ // Matrix palette skinned Unlit Triplanar
+ { Key::Builder().withMaterial().withUnlit().withTriplanar().withDeformed(), model_unlit_triplanar_deformed, model_shadow_triplanar_deformed },
+ { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar().withDeformed(), model_normalmap_unlit_triplanar_deformed, model_shadow_triplanar_deformed },
+ { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar().withDeformed(), model_translucent_unlit_triplanar_deformed, model_shadow_triplanar_deformed },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar().withDeformed(), model_normalmap_translucent_unlit_triplanar_deformed, model_shadow_triplanar_deformed },
+ // Matrix palette skinned Lightmapped Triplanar
+ { Key::Builder().withMaterial().withLightMap().withTriplanar().withDeformed(), model_lightmap_triplanar_deformed, model_shadow_triplanar_deformed },
+ { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar().withDeformed(), model_normalmap_lightmap_triplanar_deformed, model_shadow_triplanar_deformed },
+ { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar().withDeformed(), model_translucent_lightmap_triplanar_deformed, model_shadow_triplanar_deformed },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar().withDeformed(), model_normalmap_translucent_lightmap_triplanar_deformed, model_shadow_triplanar_deformed },
+ // Matrix palette skinned MToon Triplanar
+ { Key::Builder().withMaterial().withMToon().withTriplanar().withDeformed(), model_mtoon_triplanar_deformed, model_shadow_mtoon_triplanar_deformed },
+ { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar().withDeformed(), model_normalmap_mtoon_triplanar_deformed, model_shadow_mtoon_triplanar_deformed },
+ { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar().withDeformed(), model_translucent_mtoon_triplanar_deformed, model_shadow_mtoon_triplanar_deformed },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar().withDeformed(), model_normalmap_translucent_mtoon_triplanar_deformed, model_shadow_mtoon_triplanar_deformed },
// Matrix palette skinned Fade
{ Key::Builder().withMaterial().withFade().withDeformed(), model_fade_deformed, model_shadow_fade_deformed },
{ Key::Builder().withMaterial().withTangents().withFade().withDeformed(), model_normalmap_fade_deformed, model_shadow_fade_deformed },
@@ -150,6 +210,26 @@ std::vector> ALL_PIPELINES = {
{ Key::Builder().withMaterial().withTangents().withMToon().withFade().withDeformed(), model_normalmap_mtoon_fade_deformed, model_shadow_mtoon_fade_deformed },
{ Key::Builder().withMaterial().withTranslucent().withMToon().withFade().withDeformed(), model_translucent_mtoon_fade_deformed, model_shadow_mtoon_fade_deformed },
{ Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withFade().withDeformed(), model_normalmap_translucent_mtoon_fade_deformed, model_shadow_mtoon_fade_deformed },
+ // Matrix palette skinned Fade Triplanar
+ { Key::Builder().withMaterial().withTriplanar().withFade().withDeformed(), model_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed },
+ { Key::Builder().withMaterial().withTangents().withTriplanar().withFade().withDeformed(), model_normalmap_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed },
+ { Key::Builder().withMaterial().withTranslucent().withTriplanar().withFade().withDeformed(), model_translucent_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar().withFade().withDeformed(), model_normalmap_translucent_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed },
+ // Matrix palette skinned Unlit Fade Triplanar
+ { Key::Builder().withMaterial().withUnlit().withTriplanar().withFade().withDeformed(), model_unlit_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed },
+ { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar().withFade().withDeformed(), model_normalmap_unlit_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed },
+ { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar().withFade().withDeformed(), model_translucent_unlit_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar().withFade().withDeformed(), model_normalmap_translucent_unlit_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed },
+ // Matrix palette skinned Lightmapped Fade Triplanar
+ { Key::Builder().withMaterial().withLightMap().withTriplanar().withFade().withDeformed(), model_lightmap_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed },
+ { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar().withFade().withDeformed(), model_normalmap_lightmap_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed },
+ { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar().withFade().withDeformed(), model_translucent_lightmap_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar().withFade().withDeformed(), model_normalmap_translucent_lightmap_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed },
+ // Matrix palette skinned MToon Fade Triplanar
+ { Key::Builder().withMaterial().withMToon().withTriplanar().withFade().withDeformed(), model_mtoon_triplanar_fade_deformed, model_shadow_mtoon_triplanar_fade_deformed },
+ { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar().withFade().withDeformed(), model_normalmap_mtoon_triplanar_fade_deformed, model_shadow_mtoon_triplanar_fade_deformed },
+ { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar().withFade().withDeformed(), model_translucent_mtoon_triplanar_fade_deformed, model_shadow_mtoon_triplanar_fade_deformed },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar().withFade().withDeformed(), model_normalmap_translucent_mtoon_triplanar_fade_deformed, model_shadow_mtoon_triplanar_fade_deformed },
// Dual quaternion skinned
{ Key::Builder().withMaterial().withDeformed().withDualQuatSkinned(), model_deformeddq, model_shadow_deformeddq },
@@ -171,6 +251,26 @@ std::vector> ALL_PIPELINES = {
{ Key::Builder().withMaterial().withTangents().withMToon().withDeformed().withDualQuatSkinned(), model_normalmap_mtoon_deformeddq, model_shadow_mtoon_deformeddq },
{ Key::Builder().withMaterial().withTranslucent().withMToon().withDeformed().withDualQuatSkinned(), model_translucent_mtoon_deformeddq, model_shadow_mtoon_deformeddq },
{ Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_mtoon_deformeddq, model_shadow_mtoon_deformeddq },
+ // Dual quaternion skinned Triplanar
+ { Key::Builder().withMaterial().withTriplanar().withDeformed().withDualQuatSkinned(), model_triplanar_deformeddq, model_shadow_triplanar_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_triplanar_deformeddq, model_shadow_triplanar_deformeddq },
+ { Key::Builder().withMaterial().withTranslucent().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_triplanar_deformeddq, model_shadow_triplanar_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_triplanar_deformeddq, model_shadow_triplanar_deformeddq },
+ // Dual quaternion skinned Unlit Triplanar
+ { Key::Builder().withMaterial().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_unlit_triplanar_deformeddq, model_shadow_triplanar_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_unlit_triplanar_deformeddq, model_shadow_triplanar_deformeddq },
+ { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_unlit_triplanar_deformeddq, model_shadow_triplanar_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_unlit_triplanar_deformeddq, model_shadow_triplanar_deformeddq },
+ // Dual quaternion skinned Lightmapped Triplanar
+ { Key::Builder().withMaterial().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_lightmap_triplanar_deformeddq, model_shadow_triplanar_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_lightmap_triplanar_deformeddq, model_shadow_triplanar_deformeddq },
+ { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_lightmap_triplanar_deformeddq, model_shadow_triplanar_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_lightmap_triplanar_deformeddq, model_shadow_triplanar_deformeddq },
+ // Dual quaternion skinned MToon Triplanar
+ { Key::Builder().withMaterial().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_mtoon_triplanar_deformeddq, model_shadow_mtoon_triplanar_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_mtoon_triplanar_deformeddq, model_shadow_mtoon_triplanar_deformeddq },
+ { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_mtoon_triplanar_deformeddq, model_shadow_mtoon_triplanar_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_mtoon_triplanar_deformeddq, model_shadow_mtoon_triplanar_deformeddq },
// Dual quaternion skinned Fade
{ Key::Builder().withMaterial().withFade().withDeformed().withDualQuatSkinned(), model_fade_deformeddq, model_shadow_fade_deformeddq },
{ Key::Builder().withMaterial().withTangents().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_fade_deformeddq, model_shadow_fade_deformeddq },
@@ -191,6 +291,26 @@ std::vector> ALL_PIPELINES = {
{ Key::Builder().withMaterial().withTangents().withMToon().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_mtoon_fade_deformeddq, model_shadow_mtoon_fade_deformeddq },
{ Key::Builder().withMaterial().withTranslucent().withMToon().withFade().withDeformed().withDualQuatSkinned(), model_translucent_mtoon_fade_deformeddq, model_shadow_mtoon_fade_deformeddq },
{ Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_mtoon_fade_deformeddq, model_shadow_mtoon_fade_deformeddq },
+ // Dual quaternion skinned Fade Triplanar
+ { Key::Builder().withMaterial().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq },
+ { Key::Builder().withMaterial().withTranslucent().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_translucent_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq },
+ // Dual quaternion skinned Unlit Fade Triplanar
+ { Key::Builder().withMaterial().withUnlit().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_unlit_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_unlit_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq },
+ { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_translucent_unlit_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_unlit_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq },
+ // Dual quaternion skinned Lightmapped Fade Triplanar
+ { Key::Builder().withMaterial().withLightMap().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_lightmap_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_lightmap_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq },
+ { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_translucent_lightmap_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_lightmap_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq },
+ // Dual quaternion skinned MToon Fade Triplanar
+ { Key::Builder().withMaterial().withMToon().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_mtoon_triplanar_fade_deformeddq, model_shadow_mtoon_triplanar_fade_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_mtoon_triplanar_fade_deformeddq, model_shadow_mtoon_triplanar_fade_deformeddq },
+ { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_translucent_mtoon_triplanar_fade_deformeddq, model_shadow_mtoon_triplanar_fade_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_mtoon_triplanar_fade_deformeddq, model_shadow_mtoon_triplanar_fade_deformeddq },
};
void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter) {
@@ -245,6 +365,26 @@ void initForwardPipelines(ShapePlumber& plumber) {
{ Key::Builder().withMaterial().withTangents().withMToon(), model_normalmap_mtoon_forward },
{ Key::Builder().withMaterial().withTranslucent().withMToon(), model_translucent_mtoon_forward },
{ Key::Builder().withMaterial().withTangents().withTranslucent().withMToon(), model_normalmap_translucent_mtoon_forward },
+ // Unskinned Triplanar
+ { Key::Builder().withMaterial().withTriplanar(), model_triplanar_forward },
+ { Key::Builder().withMaterial().withTangents().withTriplanar(), model_normalmap_triplanar_forward },
+ { Key::Builder().withMaterial().withTranslucent().withTriplanar(), model_translucent_triplanar_forward },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar(), model_normalmap_translucent_triplanar_forward },
+ // Unskinned Unlit Triplanar
+ { Key::Builder().withMaterial().withUnlit().withTriplanar(), model_unlit_triplanar_forward },
+ { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar(), model_normalmap_unlit_triplanar_forward },
+ { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar(), model_translucent_unlit_triplanar_forward },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar(), model_normalmap_translucent_unlit_triplanar_forward },
+ // Unskinned Lightmapped Triplanar
+ { Key::Builder().withMaterial().withLightMap().withTriplanar(), model_lightmap_triplanar_forward },
+ { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar(), model_normalmap_lightmap_triplanar_forward },
+ { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar(), model_translucent_lightmap_triplanar_forward },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar(), model_normalmap_translucent_lightmap_triplanar_forward },
+ // Unskinned MToon Triplanar
+ { Key::Builder().withMaterial().withMToon().withTriplanar(), model_mtoon_triplanar_forward },
+ { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar(), model_normalmap_mtoon_triplanar_forward },
+ { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar(), model_translucent_mtoon_triplanar_forward },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar(), model_normalmap_translucent_mtoon_triplanar_forward },
// Matrix palette skinned
{ Key::Builder().withMaterial().withDeformed(), model_forward_deformed },
@@ -266,6 +406,26 @@ void initForwardPipelines(ShapePlumber& plumber) {
{ Key::Builder().withMaterial().withTangents().withMToon().withDeformed(), model_normalmap_mtoon_forward_deformed },
{ Key::Builder().withMaterial().withTranslucent().withMToon().withDeformed(), model_translucent_mtoon_forward_deformed },
{ Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withDeformed(), model_normalmap_translucent_mtoon_forward_deformed },
+ // Matrix palette skinned Triplanar
+ { Key::Builder().withMaterial().withTriplanar().withDeformed(), model_triplanar_forward_deformed },
+ { Key::Builder().withMaterial().withTangents().withTriplanar().withDeformed(), model_normalmap_triplanar_forward_deformed },
+ { Key::Builder().withMaterial().withTranslucent().withTriplanar().withDeformed(), model_translucent_triplanar_forward_deformed },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar().withDeformed(), model_normalmap_translucent_triplanar_forward_deformed },
+ // Matrix palette skinned Unlit Triplanar
+ { Key::Builder().withMaterial().withUnlit().withTriplanar().withDeformed(), model_unlit_triplanar_forward_deformed },
+ { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar().withDeformed(), model_normalmap_unlit_triplanar_forward_deformed },
+ { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar().withDeformed(), model_translucent_unlit_triplanar_forward_deformed },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar().withDeformed(), model_normalmap_translucent_unlit_triplanar_forward_deformed },
+ // Matrix palette skinned Lightmapped Triplanar
+ { Key::Builder().withMaterial().withLightMap().withTriplanar().withDeformed(), model_lightmap_triplanar_forward_deformed },
+ { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar().withDeformed(), model_normalmap_lightmap_triplanar_forward_deformed },
+ { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar().withDeformed(), model_translucent_lightmap_triplanar_forward_deformed },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar().withDeformed(), model_normalmap_translucent_lightmap_triplanar_forward_deformed },
+ // Matrix palette skinned MToon Triplanar
+ { Key::Builder().withMaterial().withMToon().withTriplanar().withDeformed(), model_mtoon_triplanar_forward_deformed },
+ { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar().withDeformed(), model_normalmap_mtoon_triplanar_forward_deformed },
+ { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar().withDeformed(), model_translucent_mtoon_triplanar_forward_deformed },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar().withDeformed(), model_normalmap_translucent_mtoon_triplanar_forward_deformed },
// Dual quaternion skinned
{ Key::Builder().withMaterial().withDeformed().withDualQuatSkinned(), model_forward_deformeddq },
@@ -287,6 +447,26 @@ void initForwardPipelines(ShapePlumber& plumber) {
{ Key::Builder().withMaterial().withTangents().withMToon().withDeformed().withDualQuatSkinned(), model_normalmap_mtoon_forward_deformeddq },
{ Key::Builder().withMaterial().withTranslucent().withMToon().withDeformed().withDualQuatSkinned(), model_translucent_mtoon_forward_deformeddq },
{ Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_mtoon_forward_deformeddq },
+ // Dual quaternion skinned Triplanar
+ { Key::Builder().withMaterial().withTriplanar().withDeformed().withDualQuatSkinned(), model_triplanar_forward_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_triplanar_forward_deformeddq },
+ { Key::Builder().withMaterial().withTranslucent().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_triplanar_forward_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_triplanar_forward_deformeddq },
+ // Dual quaternion skinned Unlit Triplanar
+ { Key::Builder().withMaterial().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_unlit_triplanar_forward_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_unlit_triplanar_forward_deformeddq },
+ { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_unlit_triplanar_forward_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_unlit_triplanar_forward_deformeddq },
+ // Dual quaternion skinned Lightmapped Triplanar
+ { Key::Builder().withMaterial().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_lightmap_triplanar_forward_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_lightmap_triplanar_forward_deformeddq },
+ { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_lightmap_triplanar_forward_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_lightmap_triplanar_forward_deformeddq },
+ // Dual quaternion skinned MToon Triplanar
+ { Key::Builder().withMaterial().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_mtoon_triplanar_forward_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_mtoon_triplanar_forward_deformeddq },
+ { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_mtoon_triplanar_forward_deformeddq },
+ { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_mtoon_triplanar_forward_deformeddq },
};
for (auto& pipeline : pipelines) {
@@ -1295,6 +1475,7 @@ bool RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu:
static gpu::BufferView defaultMaterialSchema;
static gpu::TextureTablePointer defaultMToonMaterialTextures = std::make_shared();
static gpu::BufferView defaultMToonMaterialSchema;
+ static gpu::BufferView defaultTriplanarScale;
static std::once_flag once;
std::call_once(once, [textureCache] {
@@ -1320,8 +1501,16 @@ bool RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu:
defaultMToonMaterialTextures->setTexture(gr::Texture::MaterialMatcap, textureCache->getBlackTexture());
defaultMToonMaterialTextures->setTexture(gr::Texture::MaterialRim, textureCache->getWhiteTexture());
defaultMToonMaterialTextures->setTexture(gr::Texture::MaterialUVAnimationMask, textureCache->getWhiteTexture());
+
+ vec4 triplanarScale = vec4(1.0f);
+ defaultTriplanarScale = gpu::BufferView(std::make_shared(sizeof(triplanarScale), (const gpu::Byte*) &triplanarScale, sizeof(triplanarScale)));
});
+ if (multiMaterial.size() > 0 &&
+ (MaterialMappingMode)multiMaterial.top().material->getMaterialParams().x == MaterialMappingMode::TRIPLANAR) {
+ batch.setUniformBuffer(gr::Buffer::TriplanarScale, defaultTriplanarScale);
+ }
+
// For shadows, we only need opacity mask information
auto key = multiMaterial.getMaterialKey();
if (renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE || (key.isOpacityMaskMap() || key.isTranslucentMap())) {
diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf
index a2f15df8a4..2fec410130 100644
--- a/libraries/render-utils/src/model.slf
+++ b/libraries/render-utils/src/model.slf
@@ -45,6 +45,16 @@
<@endif@>
<@endif@>
+<@if HIFI_USE_TRIPLANAR@>
+ struct TriplanarParams {
+ vec4 scale;
+ };
+
+ LAYOUT(binding=GRAPHICS_BUFFER_TRIPLANAR_SCALE) uniform triplanarParamsBuffer {
+ TriplanarParams triplanarParams;
+ };
+<@endif@>
+
<@if not HIFI_USE_SHADOW@>
<@if HIFI_USE_MTOON@>
<@include DefaultMaterials.slh@>
@@ -111,6 +121,9 @@ layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
layout(location=RENDER_UTILS_ATTR_TANGENT_WS) in vec3 _tangentWS;
<@endif@>
<@endif@>
+<@if HIFI_USE_TRIPLANAR@>
+ layout(location=RENDER_UTILS_ATTR_POSITION_MS) in vec3 _positionMS;
+<@endif@>
void main(void) {
<@if HIFI_USE_FADE@>
@@ -129,10 +142,19 @@ 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)$>
+ <@if not HIFI_USE_TRIPLANAR@>
+ <@if not HIFI_USE_MTOON@>
+ <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$>
+ <@else@>
+ <$fetchMToonMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$>
+ <@endif@>
<@else@>
- <$fetchMToonMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$>
+ const vec3 triplanarScale = triplanarParams.scale.xyz;
+ <@if not HIFI_USE_MTOON@>
+ <$fetchMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex)$>
+ <@else@>
+ <$fetchMToonMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex)$>
+ <@endif@>
<@endif@>
float cutoff = getMaterialOpacityCutoff(mat);
@@ -264,24 +286,47 @@ void main(void) {
<@endif@>
<@else@>
- <@if not HIFI_USE_LIGHTMAP@>
- <@if HIFI_USE_NORMALMAP and HIFI_USE_TRANSLUCENT@>
- <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, _SCRIBE_NULL)$>
- <@elif HIFI_USE_NORMALMAP@>
- <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, scatteringTex)$>
- <@elif HIFI_USE_TRANSLUCENT@>
- <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, _SCRIBE_NULL)$>
+ <@if not HIFI_USE_TRIPLANAR@>
+ <@if not HIFI_USE_LIGHTMAP@>
+ <@if HIFI_USE_NORMALMAP and HIFI_USE_TRANSLUCENT@>
+ <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, _SCRIBE_NULL)$>
+ <@elif HIFI_USE_NORMALMAP@>
+ <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, scatteringTex)$>
+ <@elif HIFI_USE_TRANSLUCENT@>
+ <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, _SCRIBE_NULL)$>
+ <@else@>
+ <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, scatteringTex)$>
+ <@endif@>
+ <$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$>
<@else@>
- <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, scatteringTex)$>
+ <@if HIFI_USE_NORMALMAP@>
+ <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex)$>
+ <@else@>
+ <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex)$>
+ <@endif@>
+ <$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmap)$>
<@endif@>
- <$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$>
<@else@>
- <@if HIFI_USE_NORMALMAP@>
- <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex)$>
+ const vec3 triplanarScale = triplanarParams.scale.xyz;
+ <@if not HIFI_USE_LIGHTMAP@>
+ <@if HIFI_USE_NORMALMAP and HIFI_USE_TRANSLUCENT@>
+ <$fetchMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, _SCRIBE_NULL)$>
+ <@elif HIFI_USE_NORMALMAP@>
+ <$fetchMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, scatteringTex)$>
+ <@elif HIFI_USE_TRANSLUCENT@>
+ <$fetchMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, _SCRIBE_NULL)$>
+ <@else@>
+ <$fetchMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, scatteringTex)$>
+ <@endif@>
+ <$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$>
<@else@>
- <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex)$>
+ <@if HIFI_USE_NORMALMAP@>
+ <$fetchMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex)$>
+ <@else@>
+ <$fetchMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex)$>
+ <@endif@>
+ <$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmap)$>
<@endif@>
- <$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmap)$>
<@endif@>
float cutoff = getMaterialOpacityCutoff(mat);
diff --git a/libraries/render-utils/src/model.slv b/libraries/render-utils/src/model.slv
index dc4bcde7fe..ba7abd4534 100644
--- a/libraries/render-utils/src/model.slv
+++ b/libraries/render-utils/src/model.slv
@@ -56,12 +56,19 @@ layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
layout(location=RENDER_UTILS_ATTR_TANGENT_WS) out vec3 _tangentWS;
<@endif@>
<@endif@>
+<@if HIFI_USE_TRIPLANAR@>
+ layout(location=RENDER_UTILS_ATTR_POSITION_MS) out vec3 _positionMS;
+<@endif@>
void main(void) {
vec4 positionMS = inPosition;
vec3 normalMS = inNormal.xyz;
vec3 tangentMS = inTangent.xyz;
+<@if HIFI_USE_TRIPLANAR@>
+ _positionMS = inPosition.xyz;
+<@endif@>
+
<@if HIFI_USE_DEFORMED or HIFI_USE_DEFORMEDDQ@>
evalMeshDeformer(inPosition, positionMS,
<@if not HIFI_USE_SHADOW@>
diff --git a/libraries/render-utils/src/render-utils/model.slp b/libraries/render-utils/src/render-utils/model.slp
index f2b1a0d588..641ae0e446 100644
--- a/libraries/render-utils/src/render-utils/model.slp
+++ b/libraries/render-utils/src/render-utils/model.slp
@@ -1 +1 @@
-DEFINES (normalmap translucent:f unlit:f/lightmap:f)/(shadow mirror:f) mtoon fade:f/forward:f deformed:v/deformeddq:v
+DEFINES (normalmap translucent:f unlit:f/lightmap:f)/(shadow mirror:f) mtoon triplanar fade:f/forward:f deformed:v/deformeddq:v
diff --git a/libraries/render/src/render/ShapePipeline.h b/libraries/render/src/render/ShapePipeline.h
index 87a1d3c834..df1187f99a 100644
--- a/libraries/render/src/render/ShapePipeline.h
+++ b/libraries/render/src/render/ShapePipeline.h
@@ -40,6 +40,7 @@ public:
CULL_FACE_NONE, // if neither of these are set, we're CULL_FACE_BACK
CULL_FACE_FRONT,
MTOON,
+ TRIPLANAR,
OWN_PIPELINE,
INVALID,
@@ -81,6 +82,7 @@ public:
Builder& withTranslucent() { _flags.set(TRANSLUCENT); return (*this); }
Builder& withLightMap() { _flags.set(LIGHTMAP); return (*this); }
Builder& withTangents() { _flags.set(TANGENTS); return (*this); }
+ Builder& withoutTangents() { _flags.reset(TANGENTS); return (*this); }
Builder& withUnlit() { _flags.set(UNLIT); return (*this); }
Builder& withDeformed() { _flags.set(DEFORMED); return (*this); }
Builder& withDualQuatSkinned() { _flags.set(DUAL_QUAT_SKINNED); return (*this); }
@@ -88,6 +90,7 @@ public:
Builder& withWireframe() { _flags.set(WIREFRAME); return (*this); }
Builder& withFade() { _flags.set(FADE); return (*this); }
Builder& withMToon() { _flags.set(MTOON); return (*this); }
+ Builder& withTriplanar() { _flags.set(TRIPLANAR); return (*this); }
Builder& withoutCullFace() { return withCullFaceMode(graphics::MaterialKey::CullFaceMode::CULL_NONE); }
Builder& withCullFaceMode(graphics::MaterialKey::CullFaceMode cullFaceMode) {
@@ -191,6 +194,9 @@ public:
Builder& withMToon() { _flags.set(MTOON); _mask.set(MTOON); return (*this); }
Builder& withoutMToon() { _flags.reset(MTOON); _mask.set(MTOON); return (*this); }
+ Builder& withTriplanar() { _flags.set(TRIPLANAR); _mask.set(TRIPLANAR); return (*this); }
+ Builder& withoutTriplanar() { _flags.reset(TRIPLANAR); _mask.set(TRIPLANAR); 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); }
@@ -221,6 +227,7 @@ public:
bool isCullFaceFront() const { return !_flags[CULL_FACE_NONE] && _flags[CULL_FACE_FRONT]; }
bool isFaded() const { return _flags[FADE]; }
bool isMToon() const { return _flags[MTOON]; }
+ bool isTriplanar() const { return _flags[TRIPLANAR]; }
bool hasOwnPipeline() const { return _flags[OWN_PIPELINE]; }
bool isValid() const { return !_flags[INVALID]; }
@@ -261,6 +268,7 @@ inline QDebug operator<<(QDebug debug, const ShapeKey& key) {
<< "isCullFace:" << key.isCullFace()
<< "isFaded:" << key.isFaded()
<< "isMToon:" << key.isMToon()
+ << "isTriplanar:" << key.isTriplanar()
<< "]";
}
} else {
diff --git a/libraries/shared/src/MaterialMappingMode.cpp b/libraries/shared/src/MaterialMappingMode.cpp
index 09a7cfd6d9..da2f8429db 100644
--- a/libraries/shared/src/MaterialMappingMode.cpp
+++ b/libraries/shared/src/MaterialMappingMode.cpp
@@ -10,7 +10,8 @@
const char* materialMappingModeNames[] = {
"uv",
- "projected"
+ "projected",
+ "triplanar"
};
static const size_t MATERIAL_MODE_NAMES = (sizeof(materialMappingModeNames) / sizeof(materialMappingModeNames[0]));
diff --git a/libraries/shared/src/MaterialMappingMode.h b/libraries/shared/src/MaterialMappingMode.h
index d48739562a..391e90d224 100644
--- a/libraries/shared/src/MaterialMappingMode.h
+++ b/libraries/shared/src/MaterialMappingMode.h
@@ -14,6 +14,7 @@
enum MaterialMappingMode : uint8_t {
UV = 0,
PROJECTED,
+ TRIPLANAR,
// put new mapping-modes before this line.
UNSET_MATERIAL_MAPPING_MODE
};
diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js
index 24df1c9e0f..b7bbacaad5 100644
--- a/scripts/system/create/edit.js
+++ b/scripts/system/create/edit.js
@@ -745,6 +745,7 @@
var MATERIAL_MODE_UV = 0;
var MATERIAL_MODE_PROJECTED = 1;
+ var MATERIAL_MODE_TRIPLANAR = 2;
function handleNewModelDialogResult(result) {
if (result) {
@@ -886,6 +887,9 @@
// case MATERIAL_MODE_PROJECTED:
// materialMappingMode = "projected";
// break;
+ // case MATERIAL_MODE_TRIPLANAR:
+ // materialMappingMode = "triplanar";
+ // break;
// default:
// shapeType = "uv";
//}
diff --git a/scripts/system/create/entityProperties/html/js/entityProperties.js b/scripts/system/create/entityProperties/html/js/entityProperties.js
index 408a3771cc..f50088b089 100644
--- a/scripts/system/create/entityProperties/html/js/entityProperties.js
+++ b/scripts/system/create/entityProperties/html/js/entityProperties.js
@@ -1106,7 +1106,7 @@ const GROUPS = [
label: "Material Mapping Mode",
type: "dropdown",
options: {
- uv: "UV space", projected: "3D projected"
+ uv: "UV space", projected: "3D projected", triplanar: "Triplanar mapping"
},
propertyID: "materialMappingMode",
},